diff options
-rw-r--r-- | .depend | 7 | ||||
-rw-r--r-- | auth-options.c | 650 | ||||
-rw-r--r-- | auth-options.h | 46 | ||||
-rw-r--r-- | auth-pam.c | 4 | ||||
-rw-r--r-- | auth-pam.h | 4 | ||||
-rw-r--r-- | auth-passwd.c | 30 | ||||
-rw-r--r-- | auth.c | 180 | ||||
-rw-r--r-- | auth.h | 28 | ||||
-rw-r--r-- | auth2-none.c | 4 | ||||
-rw-r--r-- | auth2-passwd.c | 4 | ||||
-rw-r--r-- | auth2-pubkey.c | 532 | ||||
-rw-r--r-- | auth2.c | 4 | ||||
-rw-r--r-- | misc.c | 3 | ||||
-rw-r--r-- | monitor.c | 70 | ||||
-rw-r--r-- | monitor_wrap.c | 44 | ||||
-rw-r--r-- | monitor_wrap.h | 11 | ||||
-rw-r--r-- | serverloop.c | 33 | ||||
-rw-r--r-- | session.c | 85 | ||||
-rw-r--r-- | sshd.c | 12 |
19 files changed, 767 insertions, 984 deletions
@@ -7,8 +7,7 @@ audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-c | |||
7 | audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h | 7 | audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h |
8 | auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h | 8 | auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h |
9 | auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h ssh.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h uidswap.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h | 9 | auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h ssh.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h uidswap.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h |
10 | auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h openbsd-compat/sys-queue.h key.h sshkey.h xmalloc.h match.h ssherr.h log.h canohost.h packet.h dispatch.h opacket.h misc.h channels.h servconf.h auth-options.h hostfile.h auth.h auth-pam.h | 10 | auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h log.h misc.h sshkey.h match.h ssh2.h auth-options.h |
11 | auth-options.o: audit.h loginrec.h | ||
12 | auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h | 11 | auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h |
13 | auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h | 12 | auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h |
14 | auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h uidswap.h pathnames.h log.h misc.h key.h sshkey.h servconf.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h | 13 | auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h uidswap.h pathnames.h log.h misc.h key.h sshkey.h servconf.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h |
@@ -16,7 +15,7 @@ auth-shadow.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-c | |||
16 | auth-sia.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h | 15 | auth-sia.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h |
17 | auth-skey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h | 16 | auth-skey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h |
18 | auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h match.h groupaccess.h log.h misc.h servconf.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h canohost.h uidswap.h packet.h openbsd-compat/sys-queue.h | 17 | auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h match.h groupaccess.h log.h misc.h servconf.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h canohost.h uidswap.h packet.h openbsd-compat/sys-queue.h |
19 | auth.o: dispatch.h opacket.h authfile.h monitor_wrap.h ssherr.h compat.h | 18 | auth.o: dispatch.h opacket.h authfile.h monitor_wrap.h ssherr.h compat.h channels.h |
20 | auth2-chall.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h ssh2.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h | 19 | auth2-chall.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h ssh2.h key.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h |
21 | auth2-gss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h | 20 | auth2-gss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h |
22 | auth2-hostbased.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h canohost.h | 21 | auth2-hostbased.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h log.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h canohost.h |
@@ -161,7 +160,7 @@ sshconnect.o: ssh2.h version.h authfile.h ssherr.h authfd.h | |||
161 | sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h key.h sshkey.h kex.h mac.h | 160 | sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h key.h sshkey.h kex.h mac.h |
162 | sshconnect2.o: myproposal.h sshconnect.h authfile.h dh.h authfd.h log.h misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h ssherr.h utf8.h | 161 | sshconnect2.o: myproposal.h sshconnect.h authfile.h dh.h authfd.h log.h misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h ssherr.h utf8.h |
163 | sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h opacket.h log.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h | 162 | sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h opacket.h log.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h |
164 | sshd.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h key.h sshkey.h kex.h mac.h myproposal.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h ssh-sandbox.h version.h ssherr.h | 163 | sshd.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h key.h sshkey.h kex.h mac.h myproposal.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h ssh-sandbox.h auth-options.h version.h ssherr.h |
165 | ssherr.o: ssherr.h | 164 | ssherr.o: ssherr.h |
166 | sshkey-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h | 165 | sshkey-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h |
167 | sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h crypto_api.h ssh2.h ssherr.h misc.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h sshkey-xmss.h match.h xmss_fast.h | 166 | sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h buffer.h sshbuf.h crypto_api.h ssh2.h ssherr.h misc.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h sshkey-xmss.h match.h xmss_fast.h |
diff --git a/auth-options.c b/auth-options.c index 8b93b51e5..484e44b74 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -1,14 +1,4 @@ | |||
1 | /* $OpenBSD: auth-options.c,v 1.75 2018/03/03 03:06:02 djm Exp $ */ | 1 | /* $OpenBSD: auth-options.c,v 1.76 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | ||
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | ||
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
5 | * All rights reserved | ||
6 | * As far as I am concerned, the code I have written for this software | ||
7 | * can be used freely for any purpose. Any derived versions of this | ||
8 | * software must be clearly marked as such, and if the derived work is | ||
9 | * incompatible with the protocol description in the RFC file, it must be | ||
10 | * called by a name other than "ssh" or "Secure Shell". | ||
11 | */ | ||
12 | /* | 2 | /* |
13 | * Copyright (c) 2018 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2018 Damien Miller <djm@mindrot.org> |
14 | * | 4 | * |
@@ -39,649 +29,15 @@ | |||
39 | 29 | ||
40 | #include "openbsd-compat/sys-queue.h" | 30 | #include "openbsd-compat/sys-queue.h" |
41 | 31 | ||
42 | #include "key.h" /* XXX for typedef */ | ||
43 | #include "buffer.h" /* XXX for typedef */ | ||
44 | #include "xmalloc.h" | 32 | #include "xmalloc.h" |
45 | #include "match.h" | ||
46 | #include "ssherr.h" | 33 | #include "ssherr.h" |
47 | #include "ssh2.h" | ||
48 | #include "log.h" | 34 | #include "log.h" |
49 | #include "canohost.h" | ||
50 | #include "packet.h" | ||
51 | #include "sshbuf.h" | 35 | #include "sshbuf.h" |
52 | #include "misc.h" | 36 | #include "misc.h" |
53 | #include "channels.h" | ||
54 | #include "servconf.h" | ||
55 | #include "sshkey.h" | 37 | #include "sshkey.h" |
38 | #include "match.h" | ||
39 | #include "ssh2.h" | ||
56 | #include "auth-options.h" | 40 | #include "auth-options.h" |
57 | #include "hostfile.h" | ||
58 | #include "auth.h" | ||
59 | |||
60 | /* Flags set authorized_keys flags */ | ||
61 | int no_port_forwarding_flag = 0; | ||
62 | int no_agent_forwarding_flag = 0; | ||
63 | int no_x11_forwarding_flag = 0; | ||
64 | int no_pty_flag = 0; | ||
65 | int no_user_rc = 0; | ||
66 | int key_is_cert_authority = 0; | ||
67 | |||
68 | /* "command=" option. */ | ||
69 | char *forced_command = NULL; | ||
70 | |||
71 | /* "environment=" options. */ | ||
72 | struct envstring *custom_environment = NULL; | ||
73 | |||
74 | /* "tunnel=" option. */ | ||
75 | int forced_tun_device = -1; | ||
76 | |||
77 | /* "principals=" option. */ | ||
78 | char *authorized_principals = NULL; | ||
79 | |||
80 | extern ServerOptions options; | ||
81 | |||
82 | /* XXX refactor to be stateless */ | ||
83 | |||
84 | void | ||
85 | auth_clear_options(void) | ||
86 | { | ||
87 | struct ssh *ssh = active_state; /* XXX */ | ||
88 | |||
89 | no_agent_forwarding_flag = 0; | ||
90 | no_port_forwarding_flag = 0; | ||
91 | no_pty_flag = 0; | ||
92 | no_x11_forwarding_flag = 0; | ||
93 | no_user_rc = 0; | ||
94 | key_is_cert_authority = 0; | ||
95 | while (custom_environment) { | ||
96 | struct envstring *ce = custom_environment; | ||
97 | custom_environment = ce->next; | ||
98 | free(ce->s); | ||
99 | free(ce); | ||
100 | } | ||
101 | free(forced_command); | ||
102 | forced_command = NULL; | ||
103 | free(authorized_principals); | ||
104 | authorized_principals = NULL; | ||
105 | forced_tun_device = -1; | ||
106 | channel_clear_permitted_opens(ssh); | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Match flag 'opt' in *optsp, and if allow_negate is set then also match | ||
111 | * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0 | ||
112 | * if negated option matches. | ||
113 | * If the option or negated option matches, then *optsp is updated to | ||
114 | * point to the first character after the option and, if 'msg' is not NULL | ||
115 | * then a message based on it added via auth_debug_add(). | ||
116 | */ | ||
117 | static int | ||
118 | match_flag(const char *opt, int allow_negate, char **optsp, const char *msg) | ||
119 | { | ||
120 | size_t opt_len = strlen(opt); | ||
121 | char *opts = *optsp; | ||
122 | int negate = 0; | ||
123 | |||
124 | if (allow_negate && strncasecmp(opts, "no-", 3) == 0) { | ||
125 | opts += 3; | ||
126 | negate = 1; | ||
127 | } | ||
128 | if (strncasecmp(opts, opt, opt_len) == 0) { | ||
129 | *optsp = opts + opt_len; | ||
130 | if (msg != NULL) { | ||
131 | auth_debug_add("%s %s.", msg, | ||
132 | negate ? "disabled" : "enabled"); | ||
133 | } | ||
134 | return negate ? 0 : 1; | ||
135 | } | ||
136 | return -1; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * return 1 if access is granted, 0 if not. | ||
141 | * side effect: sets key option flags | ||
142 | * XXX remove side effects; fill structure instead. | ||
143 | */ | ||
144 | int | ||
145 | auth_parse_options(struct passwd *pw, char *opts, const char *file, | ||
146 | u_long linenum) | ||
147 | { | ||
148 | struct ssh *ssh = active_state; /* XXX */ | ||
149 | const char *cp; | ||
150 | int i, r; | ||
151 | |||
152 | /* reset options */ | ||
153 | auth_clear_options(); | ||
154 | |||
155 | if (!opts) | ||
156 | return 1; | ||
157 | |||
158 | while (*opts && *opts != ' ' && *opts != '\t') { | ||
159 | if ((r = match_flag("cert-authority", 0, &opts, NULL)) != -1) { | ||
160 | key_is_cert_authority = r; | ||
161 | goto next_option; | ||
162 | } | ||
163 | if ((r = match_flag("restrict", 0, &opts, NULL)) != -1) { | ||
164 | auth_debug_add("Key is restricted."); | ||
165 | no_port_forwarding_flag = 1; | ||
166 | no_agent_forwarding_flag = 1; | ||
167 | no_x11_forwarding_flag = 1; | ||
168 | no_pty_flag = 1; | ||
169 | no_user_rc = 1; | ||
170 | goto next_option; | ||
171 | } | ||
172 | if ((r = match_flag("port-forwarding", 1, &opts, | ||
173 | "Port forwarding")) != -1) { | ||
174 | no_port_forwarding_flag = r != 1; | ||
175 | goto next_option; | ||
176 | } | ||
177 | if ((r = match_flag("agent-forwarding", 1, &opts, | ||
178 | "Agent forwarding")) != -1) { | ||
179 | no_agent_forwarding_flag = r != 1; | ||
180 | goto next_option; | ||
181 | } | ||
182 | if ((r = match_flag("x11-forwarding", 1, &opts, | ||
183 | "X11 forwarding")) != -1) { | ||
184 | no_x11_forwarding_flag = r != 1; | ||
185 | goto next_option; | ||
186 | } | ||
187 | if ((r = match_flag("pty", 1, &opts, | ||
188 | "PTY allocation")) != -1) { | ||
189 | no_pty_flag = r != 1; | ||
190 | goto next_option; | ||
191 | } | ||
192 | if ((r = match_flag("user-rc", 1, &opts, | ||
193 | "User rc execution")) != -1) { | ||
194 | no_user_rc = r != 1; | ||
195 | goto next_option; | ||
196 | } | ||
197 | cp = "command=\""; | ||
198 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | ||
199 | opts += strlen(cp); | ||
200 | free(forced_command); | ||
201 | forced_command = xmalloc(strlen(opts) + 1); | ||
202 | i = 0; | ||
203 | while (*opts) { | ||
204 | if (*opts == '"') | ||
205 | break; | ||
206 | if (*opts == '\\' && opts[1] == '"') { | ||
207 | opts += 2; | ||
208 | forced_command[i++] = '"'; | ||
209 | continue; | ||
210 | } | ||
211 | forced_command[i++] = *opts++; | ||
212 | } | ||
213 | if (!*opts) { | ||
214 | debug("%.100s, line %lu: missing end quote", | ||
215 | file, linenum); | ||
216 | auth_debug_add("%.100s, line %lu: missing end quote", | ||
217 | file, linenum); | ||
218 | free(forced_command); | ||
219 | forced_command = NULL; | ||
220 | goto bad_option; | ||
221 | } | ||
222 | forced_command[i] = '\0'; | ||
223 | auth_debug_add("Forced command."); | ||
224 | opts++; | ||
225 | goto next_option; | ||
226 | } | ||
227 | cp = "principals=\""; | ||
228 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | ||
229 | opts += strlen(cp); | ||
230 | free(authorized_principals); | ||
231 | authorized_principals = xmalloc(strlen(opts) + 1); | ||
232 | i = 0; | ||
233 | while (*opts) { | ||
234 | if (*opts == '"') | ||
235 | break; | ||
236 | if (*opts == '\\' && opts[1] == '"') { | ||
237 | opts += 2; | ||
238 | authorized_principals[i++] = '"'; | ||
239 | continue; | ||
240 | } | ||
241 | authorized_principals[i++] = *opts++; | ||
242 | } | ||
243 | if (!*opts) { | ||
244 | debug("%.100s, line %lu: missing end quote", | ||
245 | file, linenum); | ||
246 | auth_debug_add("%.100s, line %lu: missing end quote", | ||
247 | file, linenum); | ||
248 | free(authorized_principals); | ||
249 | authorized_principals = NULL; | ||
250 | goto bad_option; | ||
251 | } | ||
252 | authorized_principals[i] = '\0'; | ||
253 | auth_debug_add("principals: %.900s", | ||
254 | authorized_principals); | ||
255 | opts++; | ||
256 | goto next_option; | ||
257 | } | ||
258 | cp = "environment=\""; | ||
259 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | ||
260 | char *s; | ||
261 | struct envstring *new_envstring; | ||
262 | |||
263 | opts += strlen(cp); | ||
264 | s = xmalloc(strlen(opts) + 1); | ||
265 | i = 0; | ||
266 | while (*opts) { | ||
267 | if (*opts == '"') | ||
268 | break; | ||
269 | if (*opts == '\\' && opts[1] == '"') { | ||
270 | opts += 2; | ||
271 | s[i++] = '"'; | ||
272 | continue; | ||
273 | } | ||
274 | s[i++] = *opts++; | ||
275 | } | ||
276 | if (!*opts) { | ||
277 | debug("%.100s, line %lu: missing end quote", | ||
278 | file, linenum); | ||
279 | auth_debug_add("%.100s, line %lu: missing end quote", | ||
280 | file, linenum); | ||
281 | free(s); | ||
282 | goto bad_option; | ||
283 | } | ||
284 | s[i] = '\0'; | ||
285 | opts++; | ||
286 | if (options.permit_user_env) { | ||
287 | auth_debug_add("Adding to environment: " | ||
288 | "%.900s", s); | ||
289 | debug("Adding to environment: %.900s", s); | ||
290 | new_envstring = xcalloc(1, | ||
291 | sizeof(*new_envstring)); | ||
292 | new_envstring->s = s; | ||
293 | new_envstring->next = custom_environment; | ||
294 | custom_environment = new_envstring; | ||
295 | s = NULL; | ||
296 | } | ||
297 | free(s); | ||
298 | goto next_option; | ||
299 | } | ||
300 | cp = "from=\""; | ||
301 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | ||
302 | const char *remote_ip = ssh_remote_ipaddr(ssh); | ||
303 | const char *remote_host = auth_get_canonical_hostname( | ||
304 | ssh, options.use_dns); | ||
305 | char *patterns = xmalloc(strlen(opts) + 1); | ||
306 | |||
307 | opts += strlen(cp); | ||
308 | i = 0; | ||
309 | while (*opts) { | ||
310 | if (*opts == '"') | ||
311 | break; | ||
312 | if (*opts == '\\' && opts[1] == '"') { | ||
313 | opts += 2; | ||
314 | patterns[i++] = '"'; | ||
315 | continue; | ||
316 | } | ||
317 | patterns[i++] = *opts++; | ||
318 | } | ||
319 | if (!*opts) { | ||
320 | debug("%.100s, line %lu: missing end quote", | ||
321 | file, linenum); | ||
322 | auth_debug_add("%.100s, line %lu: missing end quote", | ||
323 | file, linenum); | ||
324 | free(patterns); | ||
325 | goto bad_option; | ||
326 | } | ||
327 | patterns[i] = '\0'; | ||
328 | opts++; | ||
329 | switch (match_host_and_ip(remote_host, remote_ip, | ||
330 | patterns)) { | ||
331 | case 1: | ||
332 | free(patterns); | ||
333 | /* Host name matches. */ | ||
334 | goto next_option; | ||
335 | case -1: | ||
336 | debug("%.100s, line %lu: invalid criteria", | ||
337 | file, linenum); | ||
338 | auth_debug_add("%.100s, line %lu: " | ||
339 | "invalid criteria", file, linenum); | ||
340 | /* FALLTHROUGH */ | ||
341 | case 0: | ||
342 | free(patterns); | ||
343 | logit("Authentication tried for %.100s with " | ||
344 | "correct key but not from a permitted " | ||
345 | "host (host=%.200s, ip=%.200s).", | ||
346 | pw->pw_name, remote_host, remote_ip); | ||
347 | auth_debug_add("Your host '%.200s' is not " | ||
348 | "permitted to use this key for login.", | ||
349 | remote_host); | ||
350 | break; | ||
351 | } | ||
352 | /* deny access */ | ||
353 | return 0; | ||
354 | } | ||
355 | cp = "permitopen=\""; | ||
356 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | ||
357 | char *host, *p; | ||
358 | int port; | ||
359 | char *patterns = xmalloc(strlen(opts) + 1); | ||
360 | |||
361 | opts += strlen(cp); | ||
362 | i = 0; | ||
363 | while (*opts) { | ||
364 | if (*opts == '"') | ||
365 | break; | ||
366 | if (*opts == '\\' && opts[1] == '"') { | ||
367 | opts += 2; | ||
368 | patterns[i++] = '"'; | ||
369 | continue; | ||
370 | } | ||
371 | patterns[i++] = *opts++; | ||
372 | } | ||
373 | if (!*opts) { | ||
374 | debug("%.100s, line %lu: missing end quote", | ||
375 | file, linenum); | ||
376 | auth_debug_add("%.100s, line %lu: missing " | ||
377 | "end quote", file, linenum); | ||
378 | free(patterns); | ||
379 | goto bad_option; | ||
380 | } | ||
381 | patterns[i] = '\0'; | ||
382 | opts++; | ||
383 | p = patterns; | ||
384 | /* XXX - add streamlocal support */ | ||
385 | host = hpdelim(&p); | ||
386 | if (host == NULL || strlen(host) >= NI_MAXHOST) { | ||
387 | debug("%.100s, line %lu: Bad permitopen " | ||
388 | "specification <%.100s>", file, linenum, | ||
389 | patterns); | ||
390 | auth_debug_add("%.100s, line %lu: " | ||
391 | "Bad permitopen specification", file, | ||
392 | linenum); | ||
393 | free(patterns); | ||
394 | goto bad_option; | ||
395 | } | ||
396 | host = cleanhostname(host); | ||
397 | if (p == NULL || (port = permitopen_port(p)) < 0) { | ||
398 | debug("%.100s, line %lu: Bad permitopen port " | ||
399 | "<%.100s>", file, linenum, p ? p : ""); | ||
400 | auth_debug_add("%.100s, line %lu: " | ||
401 | "Bad permitopen port", file, linenum); | ||
402 | free(patterns); | ||
403 | goto bad_option; | ||
404 | } | ||
405 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) | ||
406 | channel_add_permitted_opens(ssh, host, port); | ||
407 | free(patterns); | ||
408 | goto next_option; | ||
409 | } | ||
410 | cp = "tunnel=\""; | ||
411 | if (strncasecmp(opts, cp, strlen(cp)) == 0) { | ||
412 | char *tun = NULL; | ||
413 | opts += strlen(cp); | ||
414 | tun = xmalloc(strlen(opts) + 1); | ||
415 | i = 0; | ||
416 | while (*opts) { | ||
417 | if (*opts == '"') | ||
418 | break; | ||
419 | tun[i++] = *opts++; | ||
420 | } | ||
421 | if (!*opts) { | ||
422 | debug("%.100s, line %lu: missing end quote", | ||
423 | file, linenum); | ||
424 | auth_debug_add("%.100s, line %lu: missing end quote", | ||
425 | file, linenum); | ||
426 | free(tun); | ||
427 | forced_tun_device = -1; | ||
428 | goto bad_option; | ||
429 | } | ||
430 | tun[i] = '\0'; | ||
431 | forced_tun_device = a2tun(tun, NULL); | ||
432 | free(tun); | ||
433 | if (forced_tun_device == SSH_TUNID_ERR) { | ||
434 | debug("%.100s, line %lu: invalid tun device", | ||
435 | file, linenum); | ||
436 | auth_debug_add("%.100s, line %lu: invalid tun device", | ||
437 | file, linenum); | ||
438 | forced_tun_device = -1; | ||
439 | goto bad_option; | ||
440 | } | ||
441 | auth_debug_add("Forced tun device: %d", forced_tun_device); | ||
442 | opts++; | ||
443 | goto next_option; | ||
444 | } | ||
445 | next_option: | ||
446 | /* | ||
447 | * Skip the comma, and move to the next option | ||
448 | * (or break out if there are no more). | ||
449 | */ | ||
450 | if (!*opts) | ||
451 | fatal("Bugs in auth-options.c option processing."); | ||
452 | if (*opts == ' ' || *opts == '\t') | ||
453 | break; /* End of options. */ | ||
454 | if (*opts != ',') | ||
455 | goto bad_option; | ||
456 | opts++; | ||
457 | /* Process the next option. */ | ||
458 | } | ||
459 | |||
460 | /* grant access */ | ||
461 | return 1; | ||
462 | |||
463 | bad_option: | ||
464 | logit("Bad options in %.100s file, line %lu: %.50s", | ||
465 | file, linenum, opts); | ||
466 | auth_debug_add("Bad options in %.100s file, line %lu: %.50s", | ||
467 | file, linenum, opts); | ||
468 | |||
469 | /* deny access */ | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | #define OPTIONS_CRITICAL 1 | ||
474 | #define OPTIONS_EXTENSIONS 2 | ||
475 | static int | ||
476 | parse_option_list(struct sshbuf *oblob, struct passwd *pw, | ||
477 | u_int which, int crit, | ||
478 | int *cert_no_port_forwarding_flag, | ||
479 | int *cert_no_agent_forwarding_flag, | ||
480 | int *cert_no_x11_forwarding_flag, | ||
481 | int *cert_no_pty_flag, | ||
482 | int *cert_no_user_rc, | ||
483 | char **cert_forced_command, | ||
484 | int *cert_source_address_done) | ||
485 | { | ||
486 | struct ssh *ssh = active_state; /* XXX */ | ||
487 | char *command, *allowed; | ||
488 | const char *remote_ip; | ||
489 | char *name = NULL; | ||
490 | struct sshbuf *c = NULL, *data = NULL; | ||
491 | int r, ret = -1, result, found; | ||
492 | |||
493 | if ((c = sshbuf_fromb(oblob)) == NULL) { | ||
494 | error("%s: sshbuf_fromb failed", __func__); | ||
495 | goto out; | ||
496 | } | ||
497 | |||
498 | while (sshbuf_len(c) > 0) { | ||
499 | sshbuf_free(data); | ||
500 | data = NULL; | ||
501 | if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 || | ||
502 | (r = sshbuf_froms(c, &data)) != 0) { | ||
503 | error("Unable to parse certificate options: %s", | ||
504 | ssh_err(r)); | ||
505 | goto out; | ||
506 | } | ||
507 | debug3("found certificate option \"%.100s\" len %zu", | ||
508 | name, sshbuf_len(data)); | ||
509 | found = 0; | ||
510 | if ((which & OPTIONS_EXTENSIONS) != 0) { | ||
511 | if (strcmp(name, "permit-X11-forwarding") == 0) { | ||
512 | *cert_no_x11_forwarding_flag = 0; | ||
513 | found = 1; | ||
514 | } else if (strcmp(name, | ||
515 | "permit-agent-forwarding") == 0) { | ||
516 | *cert_no_agent_forwarding_flag = 0; | ||
517 | found = 1; | ||
518 | } else if (strcmp(name, | ||
519 | "permit-port-forwarding") == 0) { | ||
520 | *cert_no_port_forwarding_flag = 0; | ||
521 | found = 1; | ||
522 | } else if (strcmp(name, "permit-pty") == 0) { | ||
523 | *cert_no_pty_flag = 0; | ||
524 | found = 1; | ||
525 | } else if (strcmp(name, "permit-user-rc") == 0) { | ||
526 | *cert_no_user_rc = 0; | ||
527 | found = 1; | ||
528 | } | ||
529 | } | ||
530 | if (!found && (which & OPTIONS_CRITICAL) != 0) { | ||
531 | if (strcmp(name, "force-command") == 0) { | ||
532 | if ((r = sshbuf_get_cstring(data, &command, | ||
533 | NULL)) != 0) { | ||
534 | error("Unable to parse \"%s\" " | ||
535 | "section: %s", name, ssh_err(r)); | ||
536 | goto out; | ||
537 | } | ||
538 | if (*cert_forced_command != NULL) { | ||
539 | error("Certificate has multiple " | ||
540 | "force-command options"); | ||
541 | free(command); | ||
542 | goto out; | ||
543 | } | ||
544 | *cert_forced_command = command; | ||
545 | found = 1; | ||
546 | } | ||
547 | if (strcmp(name, "source-address") == 0) { | ||
548 | if ((r = sshbuf_get_cstring(data, &allowed, | ||
549 | NULL)) != 0) { | ||
550 | error("Unable to parse \"%s\" " | ||
551 | "section: %s", name, ssh_err(r)); | ||
552 | goto out; | ||
553 | } | ||
554 | if ((*cert_source_address_done)++) { | ||
555 | error("Certificate has multiple " | ||
556 | "source-address options"); | ||
557 | free(allowed); | ||
558 | goto out; | ||
559 | } | ||
560 | remote_ip = ssh_remote_ipaddr(ssh); | ||
561 | result = addr_match_cidr_list(remote_ip, | ||
562 | allowed); | ||
563 | free(allowed); | ||
564 | switch (result) { | ||
565 | case 1: | ||
566 | /* accepted */ | ||
567 | break; | ||
568 | case 0: | ||
569 | /* no match */ | ||
570 | logit("Authentication tried for %.100s " | ||
571 | "with valid certificate but not " | ||
572 | "from a permitted host " | ||
573 | "(ip=%.200s).", pw->pw_name, | ||
574 | remote_ip); | ||
575 | auth_debug_add("Your address '%.200s' " | ||
576 | "is not permitted to use this " | ||
577 | "certificate for login.", | ||
578 | remote_ip); | ||
579 | goto out; | ||
580 | case -1: | ||
581 | default: | ||
582 | error("Certificate source-address " | ||
583 | "contents invalid"); | ||
584 | goto out; | ||
585 | } | ||
586 | found = 1; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | if (!found) { | ||
591 | if (crit) { | ||
592 | error("Certificate critical option \"%s\" " | ||
593 | "is not supported", name); | ||
594 | goto out; | ||
595 | } else { | ||
596 | logit("Certificate extension \"%s\" " | ||
597 | "is not supported", name); | ||
598 | } | ||
599 | } else if (sshbuf_len(data) != 0) { | ||
600 | error("Certificate option \"%s\" corrupt " | ||
601 | "(extra data)", name); | ||
602 | goto out; | ||
603 | } | ||
604 | free(name); | ||
605 | name = NULL; | ||
606 | } | ||
607 | /* successfully parsed all options */ | ||
608 | ret = 0; | ||
609 | |||
610 | out: | ||
611 | if (ret != 0 && | ||
612 | cert_forced_command != NULL && | ||
613 | *cert_forced_command != NULL) { | ||
614 | free(*cert_forced_command); | ||
615 | *cert_forced_command = NULL; | ||
616 | } | ||
617 | free(name); | ||
618 | sshbuf_free(data); | ||
619 | sshbuf_free(c); | ||
620 | return ret; | ||
621 | } | ||
622 | |||
623 | /* | ||
624 | * Set options from critical certificate options. These supersede user key | ||
625 | * options so this must be called after auth_parse_options(). | ||
626 | */ | ||
627 | int | ||
628 | auth_cert_options(struct sshkey *k, struct passwd *pw, const char **reason) | ||
629 | { | ||
630 | int cert_no_port_forwarding_flag = 1; | ||
631 | int cert_no_agent_forwarding_flag = 1; | ||
632 | int cert_no_x11_forwarding_flag = 1; | ||
633 | int cert_no_pty_flag = 1; | ||
634 | int cert_no_user_rc = 1; | ||
635 | char *cert_forced_command = NULL; | ||
636 | int cert_source_address_done = 0; | ||
637 | |||
638 | *reason = "invalid certificate options"; | ||
639 | |||
640 | /* Separate options and extensions for v01 certs */ | ||
641 | if (parse_option_list(k->cert->critical, pw, | ||
642 | OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, | ||
643 | &cert_forced_command, | ||
644 | &cert_source_address_done) == -1) | ||
645 | return -1; | ||
646 | if (parse_option_list(k->cert->extensions, pw, | ||
647 | OPTIONS_EXTENSIONS, 0, | ||
648 | &cert_no_port_forwarding_flag, | ||
649 | &cert_no_agent_forwarding_flag, | ||
650 | &cert_no_x11_forwarding_flag, | ||
651 | &cert_no_pty_flag, | ||
652 | &cert_no_user_rc, | ||
653 | NULL, NULL) == -1) | ||
654 | return -1; | ||
655 | |||
656 | no_port_forwarding_flag |= cert_no_port_forwarding_flag; | ||
657 | no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; | ||
658 | no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; | ||
659 | no_pty_flag |= cert_no_pty_flag; | ||
660 | no_user_rc |= cert_no_user_rc; | ||
661 | /* | ||
662 | * Only permit both CA and key option forced-command if they match. | ||
663 | * Otherwise refuse the certificate. | ||
664 | */ | ||
665 | if (cert_forced_command != NULL && forced_command != NULL) { | ||
666 | if (strcmp(forced_command, cert_forced_command) == 0) { | ||
667 | free(forced_command); | ||
668 | forced_command = cert_forced_command; | ||
669 | } else { | ||
670 | *reason = "certificate and key options forced command " | ||
671 | "do not match"; | ||
672 | free(cert_forced_command); | ||
673 | return -1; | ||
674 | } | ||
675 | } else if (cert_forced_command != NULL) | ||
676 | forced_command = cert_forced_command; | ||
677 | /* success */ | ||
678 | *reason = NULL; | ||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | /* | ||
683 | * authorized_keys options processing. | ||
684 | */ | ||
685 | 41 | ||
686 | /* | 42 | /* |
687 | * Match flag 'opt' in *optsp, and if allow_negate is set then also match | 43 | * Match flag 'opt' in *optsp, and if allow_negate is set then also match |
diff --git a/auth-options.h b/auth-options.h index 0dbfc325e..16871d754 100644 --- a/auth-options.h +++ b/auth-options.h | |||
@@ -1,15 +1,19 @@ | |||
1 | /* $OpenBSD: auth-options.h,v 1.24 2018/03/03 03:06:02 djm Exp $ */ | 1 | /* $OpenBSD: auth-options.h,v 1.25 2018/03/03 03:15:51 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Copyright (c) 2018 Damien Miller <djm@mindrot.org> |
5 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
6 | * All rights reserved | ||
7 | * | 5 | * |
8 | * As far as I am concerned, the code I have written for this software | 6 | * Permission to use, copy, modify, and distribute this software for any |
9 | * can be used freely for any purpose. Any derived versions of this | 7 | * purpose with or without fee is hereby granted, provided that the above |
10 | * software must be clearly marked as such, and if the derived work is | 8 | * copyright notice and this permission notice appear in all copies. |
11 | * incompatible with the protocol description in the RFC file, it must be | 9 | * |
12 | * called by a name other than "ssh" or "Secure Shell". | 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
13 | */ | 17 | */ |
14 | 18 | ||
15 | #ifndef AUTH_OPTIONS_H | 19 | #ifndef AUTH_OPTIONS_H |
@@ -18,30 +22,6 @@ | |||
18 | struct passwd; | 22 | struct passwd; |
19 | struct sshkey; | 23 | struct sshkey; |
20 | 24 | ||
21 | /* Linked list of custom environment strings */ | ||
22 | struct envstring { | ||
23 | struct envstring *next; | ||
24 | char *s; | ||
25 | }; | ||
26 | |||
27 | /* Flags that may be set in authorized_keys options. */ | ||
28 | extern int no_port_forwarding_flag; | ||
29 | extern int no_agent_forwarding_flag; | ||
30 | extern int no_x11_forwarding_flag; | ||
31 | extern int no_pty_flag; | ||
32 | extern int no_user_rc; | ||
33 | extern char *forced_command; | ||
34 | extern struct envstring *custom_environment; | ||
35 | extern int forced_tun_device; | ||
36 | extern int key_is_cert_authority; | ||
37 | extern char *authorized_principals; | ||
38 | |||
39 | int auth_parse_options(struct passwd *, char *, const char *, u_long); | ||
40 | void auth_clear_options(void); | ||
41 | int auth_cert_options(struct sshkey *, struct passwd *, const char **); | ||
42 | |||
43 | /* authorized_keys options handling */ | ||
44 | |||
45 | /* | 25 | /* |
46 | * sshauthopt represents key options parsed from authorized_keys or | 26 | * sshauthopt represents key options parsed from authorized_keys or |
47 | * from certificate extensions/options. | 27 | * from certificate extensions/options. |
diff --git a/auth-pam.c b/auth-pam.c index de29c04c9..50d2073d7 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -1077,7 +1077,7 @@ do_pam_chauthtok(void) | |||
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | void | 1079 | void |
1080 | do_pam_session(void) | 1080 | do_pam_session(struct ssh *ssh) |
1081 | { | 1081 | { |
1082 | debug3("PAM: opening session"); | 1082 | debug3("PAM: opening session"); |
1083 | 1083 | ||
@@ -1093,7 +1093,7 @@ do_pam_session(void) | |||
1093 | sshpam_session_open = 1; | 1093 | sshpam_session_open = 1; |
1094 | else { | 1094 | else { |
1095 | sshpam_session_open = 0; | 1095 | sshpam_session_open = 0; |
1096 | disable_forwarding(); | 1096 | auth_restrict_session(ssh); |
1097 | error("PAM: pam_open_session(): %s", | 1097 | error("PAM: pam_open_session(): %s", |
1098 | pam_strerror(sshpam_handle, sshpam_err)); | 1098 | pam_strerror(sshpam_handle, sshpam_err)); |
1099 | } | 1099 | } |
diff --git a/auth-pam.h b/auth-pam.h index c47b442e4..419860745 100644 --- a/auth-pam.h +++ b/auth-pam.h | |||
@@ -25,10 +25,12 @@ | |||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | #ifdef USE_PAM | 26 | #ifdef USE_PAM |
27 | 27 | ||
28 | struct ssh; | ||
29 | |||
28 | void start_pam(Authctxt *); | 30 | void start_pam(Authctxt *); |
29 | void finish_pam(void); | 31 | void finish_pam(void); |
30 | u_int do_pam_account(void); | 32 | u_int do_pam_account(void); |
31 | void do_pam_session(void); | 33 | void do_pam_session(struct ssh *); |
32 | void do_pam_setcred(int ); | 34 | void do_pam_setcred(int ); |
33 | void do_pam_chauthtok(void); | 35 | void do_pam_chauthtok(void); |
34 | int do_pam_putenv(char *, char *); | 36 | int do_pam_putenv(char *, char *); |
diff --git a/auth-passwd.c b/auth-passwd.c index 996c2cf71..6097fdd24 100644 --- a/auth-passwd.c +++ b/auth-passwd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-passwd.c,v 1.45 2016/07/21 01:39:35 dtucker Exp $ */ | 1 | /* $OpenBSD: auth-passwd.c,v 1.46 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -68,22 +68,15 @@ extern login_cap_t *lc; | |||
68 | 68 | ||
69 | #define MAX_PASSWORD_LEN 1024 | 69 | #define MAX_PASSWORD_LEN 1024 |
70 | 70 | ||
71 | void | ||
72 | disable_forwarding(void) | ||
73 | { | ||
74 | no_port_forwarding_flag = 1; | ||
75 | no_agent_forwarding_flag = 1; | ||
76 | no_x11_forwarding_flag = 1; | ||
77 | } | ||
78 | |||
79 | /* | 71 | /* |
80 | * Tries to authenticate the user using password. Returns true if | 72 | * Tries to authenticate the user using password. Returns true if |
81 | * authentication succeeds. | 73 | * authentication succeeds. |
82 | */ | 74 | */ |
83 | int | 75 | int |
84 | auth_password(Authctxt *authctxt, const char *password) | 76 | auth_password(struct ssh *ssh, const char *password) |
85 | { | 77 | { |
86 | struct passwd * pw = authctxt->pw; | 78 | Authctxt *authctxt = ssh->authctxt; |
79 | struct passwd *pw = authctxt->pw; | ||
87 | int result, ok = authctxt->valid; | 80 | int result, ok = authctxt->valid; |
88 | #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) | 81 | #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) |
89 | static int expire_checked = 0; | 82 | static int expire_checked = 0; |
@@ -128,9 +121,9 @@ auth_password(Authctxt *authctxt, const char *password) | |||
128 | authctxt->force_pwchange = 1; | 121 | authctxt->force_pwchange = 1; |
129 | } | 122 | } |
130 | #endif | 123 | #endif |
131 | result = sys_auth_passwd(authctxt, password); | 124 | result = sys_auth_passwd(ssh, password); |
132 | if (authctxt->force_pwchange) | 125 | if (authctxt->force_pwchange) |
133 | disable_forwarding(); | 126 | auth_restrict_session(ssh); |
134 | return (result && ok); | 127 | return (result && ok); |
135 | } | 128 | } |
136 | 129 | ||
@@ -170,19 +163,19 @@ warn_expiry(Authctxt *authctxt, auth_session_t *as) | |||
170 | } | 163 | } |
171 | 164 | ||
172 | int | 165 | int |
173 | sys_auth_passwd(Authctxt *authctxt, const char *password) | 166 | sys_auth_passwd(struct ssh *ssh, const char *password) |
174 | { | 167 | { |
175 | struct passwd *pw = authctxt->pw; | 168 | Authctxt *authctxt = ssh->authctxt; |
176 | auth_session_t *as; | 169 | auth_session_t *as; |
177 | static int expire_checked = 0; | 170 | static int expire_checked = 0; |
178 | 171 | ||
179 | as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh", | 172 | as = auth_usercheck(authctxt->pw->pw_name, authctxt->style, "auth-ssh", |
180 | (char *)password); | 173 | (char *)password); |
181 | if (as == NULL) | 174 | if (as == NULL) |
182 | return (0); | 175 | return (0); |
183 | if (auth_getstate(as) & AUTH_PWEXPIRED) { | 176 | if (auth_getstate(as) & AUTH_PWEXPIRED) { |
184 | auth_close(as); | 177 | auth_close(as); |
185 | disable_forwarding(); | 178 | auth_restrict_session(ssh); |
186 | authctxt->force_pwchange = 1; | 179 | authctxt->force_pwchange = 1; |
187 | return (1); | 180 | return (1); |
188 | } else { | 181 | } else { |
@@ -195,8 +188,9 @@ sys_auth_passwd(Authctxt *authctxt, const char *password) | |||
195 | } | 188 | } |
196 | #elif !defined(CUSTOM_SYS_AUTH_PASSWD) | 189 | #elif !defined(CUSTOM_SYS_AUTH_PASSWD) |
197 | int | 190 | int |
198 | sys_auth_passwd(Authctxt *authctxt, const char *password) | 191 | sys_auth_passwd(struct ssh *ssh, const char *password) |
199 | { | 192 | { |
193 | Authctxt *authctxt = ssh->authctxt; | ||
200 | struct passwd *pw = authctxt->pw; | 194 | struct passwd *pw = authctxt->pw; |
201 | char *encrypted_password, *salt = NULL; | 195 | char *encrypted_password, *salt = NULL; |
202 | 196 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.c,v 1.125 2018/01/08 15:21:49 markus Exp $ */ | 1 | /* $OpenBSD: auth.c,v 1.126 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -74,12 +74,14 @@ | |||
74 | #include "authfile.h" | 74 | #include "authfile.h" |
75 | #include "ssherr.h" | 75 | #include "ssherr.h" |
76 | #include "compat.h" | 76 | #include "compat.h" |
77 | #include "channels.h" | ||
77 | 78 | ||
78 | /* import */ | 79 | /* import */ |
79 | extern ServerOptions options; | 80 | extern ServerOptions options; |
80 | extern int use_privsep; | 81 | extern int use_privsep; |
81 | extern Buffer loginmsg; | 82 | extern Buffer loginmsg; |
82 | extern struct passwd *privsep_pw; | 83 | extern struct passwd *privsep_pw; |
84 | extern struct sshauthopt *auth_opts; | ||
83 | 85 | ||
84 | /* Debugging messages */ | 86 | /* Debugging messages */ |
85 | Buffer auth_debug; | 87 | Buffer auth_debug; |
@@ -386,10 +388,8 @@ auth_maxtries_exceeded(Authctxt *authctxt) | |||
386 | * Check whether root logins are disallowed. | 388 | * Check whether root logins are disallowed. |
387 | */ | 389 | */ |
388 | int | 390 | int |
389 | auth_root_allowed(const char *method) | 391 | auth_root_allowed(struct ssh *ssh, const char *method) |
390 | { | 392 | { |
391 | struct ssh *ssh = active_state; /* XXX */ | ||
392 | |||
393 | switch (options.permit_root_login) { | 393 | switch (options.permit_root_login) { |
394 | case PERMIT_YES: | 394 | case PERMIT_YES: |
395 | return 1; | 395 | return 1; |
@@ -400,7 +400,7 @@ auth_root_allowed(const char *method) | |||
400 | return 1; | 400 | return 1; |
401 | break; | 401 | break; |
402 | case PERMIT_FORCED_ONLY: | 402 | case PERMIT_FORCED_ONLY: |
403 | if (forced_command) { | 403 | if (auth_opts->force_command != NULL) { |
404 | logit("Root login accepted for forced command."); | 404 | logit("Root login accepted for forced command."); |
405 | return 1; | 405 | return 1; |
406 | } | 406 | } |
@@ -993,3 +993,173 @@ subprocess(const char *tag, struct passwd *pw, const char *command, | |||
993 | *child = f; | 993 | *child = f; |
994 | return pid; | 994 | return pid; |
995 | } | 995 | } |
996 | |||
997 | /* These functions link key/cert options to the auth framework */ | ||
998 | |||
999 | /* Log sshauthopt options locally and (optionally) for remote transmission */ | ||
1000 | void | ||
1001 | auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote) | ||
1002 | { | ||
1003 | int do_env = options.permit_user_env && opts->nenv > 0; | ||
1004 | int do_permitopen = opts->npermitopen > 0 && | ||
1005 | (options.allow_tcp_forwarding & FORWARD_LOCAL) != 0; | ||
1006 | size_t i; | ||
1007 | char msg[1024], tbuf[32]; | ||
1008 | |||
1009 | snprintf(tbuf, sizeof(tbuf), "%d", opts->force_tun_device); | ||
1010 | /* Try to keep this alphabetically sorted */ | ||
1011 | snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s", | ||
1012 | opts->permit_agent_forwarding_flag ? " agent-forwarding" : "", | ||
1013 | opts->force_command == NULL ? "" : " command", | ||
1014 | do_env ? " environment" : "", | ||
1015 | do_permitopen ? " permitopen" : "", | ||
1016 | opts->permit_port_forwarding_flag ? " port-forwarding" : "", | ||
1017 | opts->cert_principals == NULL ? "" : " principals", | ||
1018 | opts->permit_pty_flag ? " pty" : "", | ||
1019 | opts->force_tun_device == -1 ? "" : " tun=", | ||
1020 | opts->force_tun_device == -1 ? "" : tbuf, | ||
1021 | opts->permit_user_rc ? " user-rc" : "", | ||
1022 | opts->permit_x11_forwarding_flag ? " x11-forwarding" : ""); | ||
1023 | |||
1024 | debug("%s: %s", loc, msg); | ||
1025 | if (do_remote) | ||
1026 | auth_debug_add("%s: %s", loc, msg); | ||
1027 | |||
1028 | if (options.permit_user_env) { | ||
1029 | for (i = 0; i < opts->nenv; i++) { | ||
1030 | debug("%s: environment: %s", loc, opts->env[i]); | ||
1031 | if (do_remote) { | ||
1032 | auth_debug_add("%s: environment: %s", | ||
1033 | loc, opts->env[i]); | ||
1034 | } | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | /* Go into a little more details for the local logs. */ | ||
1039 | if (opts->cert_principals != NULL) { | ||
1040 | debug("%s: authorized principals: \"%s\"", | ||
1041 | loc, opts->cert_principals); | ||
1042 | } | ||
1043 | if (opts->force_command != NULL) | ||
1044 | debug("%s: forced command: \"%s\"", loc, opts->force_command); | ||
1045 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) { | ||
1046 | for (i = 0; i < opts->npermitopen; i++) { | ||
1047 | debug("%s: permitted open: %s", | ||
1048 | loc, opts->permitopen[i]); | ||
1049 | } | ||
1050 | } | ||
1051 | } | ||
1052 | |||
1053 | /* Activate a new set of key/cert options; merging with what is there. */ | ||
1054 | int | ||
1055 | auth_activate_options(struct ssh *ssh, struct sshauthopt *opts) | ||
1056 | { | ||
1057 | struct sshauthopt *old = auth_opts; | ||
1058 | const char *emsg = NULL; | ||
1059 | |||
1060 | debug("%s: setting new authentication options", __func__); | ||
1061 | if ((auth_opts = sshauthopt_merge(old, opts, &emsg)) == NULL) { | ||
1062 | error("Inconsistent authentication options: %s", emsg); | ||
1063 | return -1; | ||
1064 | } | ||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | /* Disable forwarding, etc for the session */ | ||
1069 | void | ||
1070 | auth_restrict_session(struct ssh *ssh) | ||
1071 | { | ||
1072 | struct sshauthopt *restricted; | ||
1073 | |||
1074 | debug("%s: restricting session", __func__); | ||
1075 | |||
1076 | /* A blank sshauthopt defaults to permitting nothing */ | ||
1077 | restricted = sshauthopt_new(); | ||
1078 | restricted->restricted = 1; | ||
1079 | |||
1080 | if (auth_activate_options(ssh, restricted) != 0) | ||
1081 | fatal("%s: failed to restrict session", __func__); | ||
1082 | sshauthopt_free(restricted); | ||
1083 | } | ||
1084 | |||
1085 | int | ||
1086 | auth_authorise_keyopts(struct ssh *ssh, struct passwd *pw, | ||
1087 | struct sshauthopt *opts, int allow_cert_authority, const char *loc) | ||
1088 | { | ||
1089 | const char *remote_ip = ssh_remote_ipaddr(ssh); | ||
1090 | const char *remote_host = auth_get_canonical_hostname(ssh, | ||
1091 | options.use_dns); | ||
1092 | |||
1093 | /* Consistency checks */ | ||
1094 | if (opts->cert_principals != NULL && !opts->cert_authority) { | ||
1095 | debug("%s: principals on non-CA key", loc); | ||
1096 | auth_debug_add("%s: principals on non-CA key", loc); | ||
1097 | /* deny access */ | ||
1098 | return -1; | ||
1099 | } | ||
1100 | /* cert-authority flag isn't valid in authorized_principals files */ | ||
1101 | if (!allow_cert_authority && opts->cert_authority) { | ||
1102 | debug("%s: cert-authority flag invalid here", loc); | ||
1103 | auth_debug_add("%s: cert-authority flag invalid here", loc); | ||
1104 | /* deny access */ | ||
1105 | return -1; | ||
1106 | } | ||
1107 | |||
1108 | /* Perform from= checks */ | ||
1109 | if (opts->required_from_host_keys != NULL) { | ||
1110 | switch (match_host_and_ip(remote_host, remote_ip, | ||
1111 | opts->required_from_host_keys )) { | ||
1112 | case 1: | ||
1113 | /* Host name matches. */ | ||
1114 | break; | ||
1115 | case -1: | ||
1116 | default: | ||
1117 | debug("%s: invalid from criteria", loc); | ||
1118 | auth_debug_add("%s: invalid from criteria", loc); | ||
1119 | /* FALLTHROUGH */ | ||
1120 | case 0: | ||
1121 | logit("%s: Authentication tried for %.100s with " | ||
1122 | "correct key but not from a permitted " | ||
1123 | "host (host=%.200s, ip=%.200s, required=%.200s).", | ||
1124 | loc, pw->pw_name, remote_host, remote_ip, | ||
1125 | opts->required_from_host_keys); | ||
1126 | auth_debug_add("%s: Your host '%.200s' is not " | ||
1127 | "permitted to use this key for login.", | ||
1128 | loc, remote_host); | ||
1129 | /* deny access */ | ||
1130 | return -1; | ||
1131 | } | ||
1132 | } | ||
1133 | /* Check source-address restriction from certificate */ | ||
1134 | if (opts->required_from_host_cert != NULL) { | ||
1135 | switch (addr_match_cidr_list(remote_ip, | ||
1136 | opts->required_from_host_cert)) { | ||
1137 | case 1: | ||
1138 | /* accepted */ | ||
1139 | break; | ||
1140 | case -1: | ||
1141 | default: | ||
1142 | /* invalid */ | ||
1143 | error("%s: Certificate source-address invalid", | ||
1144 | loc); | ||
1145 | /* FALLTHROUGH */ | ||
1146 | case 0: | ||
1147 | logit("%s: Authentication tried for %.100s with valid " | ||
1148 | "certificate but not from a permitted source " | ||
1149 | "address (%.200s).", loc, pw->pw_name, remote_ip); | ||
1150 | auth_debug_add("%s: Your address '%.200s' is not " | ||
1151 | "permitted to use this certificate for login.", | ||
1152 | loc, remote_ip); | ||
1153 | return -1; | ||
1154 | } | ||
1155 | } | ||
1156 | /* | ||
1157 | * | ||
1158 | * XXX this is spammy. We should report remotely only for keys | ||
1159 | * that are successful in actual auth attempts, and not PK_OK | ||
1160 | * tests. | ||
1161 | */ | ||
1162 | auth_log_authopts(loc, opts, 1); | ||
1163 | |||
1164 | return 0; | ||
1165 | } | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.h,v 1.94 2018/01/08 15:21:49 markus Exp $ */ | 1 | /* $OpenBSD: auth.h,v 1.95 2018/03/03 03:15:51 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -42,9 +42,11 @@ | |||
42 | #include <krb5.h> | 42 | #include <krb5.h> |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | struct passwd; | ||
45 | struct ssh; | 46 | struct ssh; |
46 | struct sshkey; | ||
47 | struct sshbuf; | 47 | struct sshbuf; |
48 | struct sshkey; | ||
49 | struct sshauthopt; | ||
48 | 50 | ||
49 | typedef struct Authctxt Authctxt; | 51 | typedef struct Authctxt Authctxt; |
50 | typedef struct Authmethod Authmethod; | 52 | typedef struct Authmethod Authmethod; |
@@ -128,11 +130,12 @@ struct KbdintDevice | |||
128 | int | 130 | int |
129 | auth_rhosts2(struct passwd *, const char *, const char *, const char *); | 131 | auth_rhosts2(struct passwd *, const char *, const char *, const char *); |
130 | 132 | ||
131 | int auth_password(Authctxt *, const char *); | 133 | int auth_password(struct ssh *, const char *); |
132 | 134 | ||
133 | int hostbased_key_allowed(struct passwd *, const char *, char *, | 135 | int hostbased_key_allowed(struct passwd *, const char *, char *, |
134 | struct sshkey *); | 136 | struct sshkey *); |
135 | int user_key_allowed(struct passwd *, struct sshkey *, int); | 137 | int user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int, |
138 | struct sshauthopt **); | ||
136 | int auth2_key_already_used(Authctxt *, const struct sshkey *); | 139 | int auth2_key_already_used(Authctxt *, const struct sshkey *); |
137 | 140 | ||
138 | /* | 141 | /* |
@@ -163,14 +166,12 @@ int auth_shadow_pwexpired(Authctxt *); | |||
163 | #include "audit.h" | 166 | #include "audit.h" |
164 | void remove_kbdint_device(const char *); | 167 | void remove_kbdint_device(const char *); |
165 | 168 | ||
166 | void disable_forwarding(void); | ||
167 | |||
168 | void do_authentication2(Authctxt *); | 169 | void do_authentication2(Authctxt *); |
169 | 170 | ||
170 | void auth_log(Authctxt *, int, int, const char *, const char *); | 171 | void auth_log(Authctxt *, int, int, const char *, const char *); |
171 | void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn)); | 172 | void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn)); |
172 | void userauth_finish(struct ssh *, int, const char *, const char *); | 173 | void userauth_finish(struct ssh *, int, const char *, const char *); |
173 | int auth_root_allowed(const char *); | 174 | int auth_root_allowed(struct ssh *, const char *); |
174 | 175 | ||
175 | void userauth_send_banner(const char *); | 176 | void userauth_send_banner(const char *); |
176 | 177 | ||
@@ -214,8 +215,17 @@ int get_hostkey_index(struct sshkey *, int, struct ssh *); | |||
214 | int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **, | 215 | int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **, |
215 | size_t *, const u_char *, size_t, const char *, u_int); | 216 | size_t *, const u_char *, size_t, const char *, u_int); |
216 | 217 | ||
218 | /* Key / cert options linkage to auth layer */ | ||
219 | const struct sshauthopt *auth_options(struct ssh *); | ||
220 | int auth_activate_options(struct ssh *, struct sshauthopt *); | ||
221 | void auth_restrict_session(struct ssh *); | ||
222 | int auth_authorise_keyopts(struct ssh *, struct passwd *pw, | ||
223 | struct sshauthopt *, int, const char *); | ||
224 | void auth_log_authopts(const char *, const struct sshauthopt *, int); | ||
225 | |||
217 | /* debug messages during authentication */ | 226 | /* debug messages during authentication */ |
218 | void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); | 227 | void auth_debug_add(const char *fmt,...) |
228 | __attribute__((format(printf, 1, 2))); | ||
219 | void auth_debug_send(void); | 229 | void auth_debug_send(void); |
220 | void auth_debug_reset(void); | 230 | void auth_debug_reset(void); |
221 | 231 | ||
@@ -227,7 +237,7 @@ struct passwd *fakepw(void); | |||
227 | pid_t subprocess(const char *, struct passwd *, | 237 | pid_t subprocess(const char *, struct passwd *, |
228 | const char *, int, char **, FILE **, u_int flags); | 238 | const char *, int, char **, FILE **, u_int flags); |
229 | 239 | ||
230 | int sys_auth_passwd(Authctxt *, const char *); | 240 | int sys_auth_passwd(struct ssh *, const char *); |
231 | 241 | ||
232 | #define SKEY_PROMPT "\nS/Key Password: " | 242 | #define SKEY_PROMPT "\nS/Key Password: " |
233 | 243 | ||
diff --git a/auth2-none.c b/auth2-none.c index 35d25fa63..8d4e9bb8c 100644 --- a/auth2-none.c +++ b/auth2-none.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-none.c,v 1.20 2017/05/30 14:29:59 markus Exp $ */ | 1 | /* $OpenBSD: auth2-none.c,v 1.21 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -68,7 +68,7 @@ userauth_none(struct ssh *ssh) | |||
68 | if ((r = sshpkt_get_end(ssh)) != 0) | 68 | if ((r = sshpkt_get_end(ssh)) != 0) |
69 | fatal("%s: %s", __func__, ssh_err(r)); | 69 | fatal("%s: %s", __func__, ssh_err(r)); |
70 | if (options.permit_empty_passwd && options.password_authentication) | 70 | if (options.permit_empty_passwd && options.password_authentication) |
71 | return (PRIVSEP(auth_password(ssh->authctxt, ""))); | 71 | return (PRIVSEP(auth_password(ssh, ""))); |
72 | return (0); | 72 | return (0); |
73 | } | 73 | } |
74 | 74 | ||
diff --git a/auth2-passwd.c b/auth2-passwd.c index 5f7ba3244..445016aec 100644 --- a/auth2-passwd.c +++ b/auth2-passwd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-passwd.c,v 1.14 2017/05/30 14:29:59 markus Exp $ */ | 1 | /* $OpenBSD: auth2-passwd.c,v 1.15 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -63,7 +63,7 @@ userauth_passwd(struct ssh *ssh) | |||
63 | 63 | ||
64 | if (change) | 64 | if (change) |
65 | logit("password change not supported"); | 65 | logit("password change not supported"); |
66 | else if (PRIVSEP(auth_password(ssh->authctxt, password)) == 1) | 66 | else if (PRIVSEP(auth_password(ssh, password)) == 1) |
67 | authenticated = 1; | 67 | authenticated = 1; |
68 | explicit_bzero(password, len); | 68 | explicit_bzero(password, len); |
69 | free(password); | 69 | free(password); |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 8fb7ffe71..8024b1d6a 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.76 2018/02/07 22:52:45 dtucker Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.77 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -88,6 +88,7 @@ static int | |||
88 | userauth_pubkey(struct ssh *ssh) | 88 | userauth_pubkey(struct ssh *ssh) |
89 | { | 89 | { |
90 | Authctxt *authctxt = ssh->authctxt; | 90 | Authctxt *authctxt = ssh->authctxt; |
91 | struct passwd *pw = authctxt->pw; | ||
91 | struct sshbuf *b; | 92 | struct sshbuf *b; |
92 | struct sshkey *key = NULL; | 93 | struct sshkey *key = NULL; |
93 | char *pkalg, *userstyle = NULL, *key_s = NULL, *ca_s = NULL; | 94 | char *pkalg, *userstyle = NULL, *key_s = NULL, *ca_s = NULL; |
@@ -95,6 +96,7 @@ userauth_pubkey(struct ssh *ssh) | |||
95 | size_t blen, slen; | 96 | size_t blen, slen; |
96 | int r, pktype; | 97 | int r, pktype; |
97 | int authenticated = 0; | 98 | int authenticated = 0; |
99 | struct sshauthopt *authopts = NULL; | ||
98 | 100 | ||
99 | if (!authctxt->valid) { | 101 | if (!authctxt->valid) { |
100 | debug2("%s: disabled because of invalid user", __func__); | 102 | debug2("%s: disabled because of invalid user", __func__); |
@@ -185,7 +187,7 @@ userauth_pubkey(struct ssh *ssh) | |||
185 | 187 | ||
186 | /* test for correct signature */ | 188 | /* test for correct signature */ |
187 | authenticated = 0; | 189 | authenticated = 0; |
188 | if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && | 190 | if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && |
189 | PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), | 191 | PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), |
190 | sshbuf_len(b), NULL, ssh->compat)) == 0) { | 192 | sshbuf_len(b), NULL, ssh->compat)) == 0) { |
191 | authenticated = 1; | 193 | authenticated = 1; |
@@ -210,7 +212,7 @@ userauth_pubkey(struct ssh *ssh) | |||
210 | * if a user is not allowed to login. is this an | 212 | * if a user is not allowed to login. is this an |
211 | * issue? -markus | 213 | * issue? -markus |
212 | */ | 214 | */ |
213 | if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) { | 215 | if (PRIVSEP(user_key_allowed(ssh, pw, key, 0, NULL))) { |
214 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK)) | 216 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK)) |
215 | != 0 || | 217 | != 0 || |
216 | (r = sshpkt_put_cstring(ssh, pkalg)) != 0 || | 218 | (r = sshpkt_put_cstring(ssh, pkalg)) != 0 || |
@@ -221,10 +223,14 @@ userauth_pubkey(struct ssh *ssh) | |||
221 | authctxt->postponed = 1; | 223 | authctxt->postponed = 1; |
222 | } | 224 | } |
223 | } | 225 | } |
224 | if (authenticated != 1) | ||
225 | auth_clear_options(); | ||
226 | done: | 226 | done: |
227 | if (authenticated == 1 && auth_activate_options(ssh, authopts) != 0) { | ||
228 | debug("%s: key options inconsistent with existing", __func__); | ||
229 | authenticated = 0; | ||
230 | } | ||
227 | debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); | 231 | debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); |
232 | |||
233 | sshauthopt_free(authopts); | ||
228 | sshkey_free(key); | 234 | sshkey_free(key); |
229 | free(userstyle); | 235 | free(userstyle); |
230 | free(pkalg); | 236 | free(pkalg); |
@@ -254,18 +260,77 @@ match_principals_option(const char *principal_list, struct sshkey_cert *cert) | |||
254 | return 0; | 260 | return 0; |
255 | } | 261 | } |
256 | 262 | ||
263 | /* | ||
264 | * Process a single authorized_principals format line. Returns 0 and sets | ||
265 | * authoptsp is principal is authorised, -1 otherwise. "loc" is used as a | ||
266 | * log preamble for file/line information. | ||
267 | */ | ||
268 | static int | ||
269 | check_principals_line(struct ssh *ssh, char *cp, const struct sshkey_cert *cert, | ||
270 | const char *loc, struct sshauthopt **authoptsp) | ||
271 | { | ||
272 | u_int i, found = 0; | ||
273 | char *ep, *line_opts; | ||
274 | const char *reason = NULL; | ||
275 | struct sshauthopt *opts = NULL; | ||
276 | |||
277 | if (authoptsp != NULL) | ||
278 | *authoptsp = NULL; | ||
279 | |||
280 | /* Trim trailing whitespace. */ | ||
281 | ep = cp + strlen(cp) - 1; | ||
282 | while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t')) | ||
283 | *ep-- = '\0'; | ||
284 | |||
285 | /* | ||
286 | * If the line has internal whitespace then assume it has | ||
287 | * key options. | ||
288 | */ | ||
289 | line_opts = NULL; | ||
290 | if ((ep = strrchr(cp, ' ')) != NULL || | ||
291 | (ep = strrchr(cp, '\t')) != NULL) { | ||
292 | for (; *ep == ' ' || *ep == '\t'; ep++) | ||
293 | ; | ||
294 | line_opts = cp; | ||
295 | cp = ep; | ||
296 | } | ||
297 | if ((opts = sshauthopt_parse(line_opts, &reason)) == NULL) { | ||
298 | debug("%s: bad principals options: %s", loc, reason); | ||
299 | auth_debug_add("%s: bad principals options: %s", loc, reason); | ||
300 | return -1; | ||
301 | } | ||
302 | /* Check principals in cert against those on line */ | ||
303 | for (i = 0; i < cert->nprincipals; i++) { | ||
304 | if (strcmp(cp, cert->principals[i]) != 0) | ||
305 | continue; | ||
306 | debug3("%s: matched principal \"%.100s\"", | ||
307 | loc, cert->principals[i]); | ||
308 | found = 1; | ||
309 | } | ||
310 | if (found && authoptsp != NULL) { | ||
311 | *authoptsp = opts; | ||
312 | opts = NULL; | ||
313 | } | ||
314 | sshauthopt_free(opts); | ||
315 | return found ? 0 : -1; | ||
316 | } | ||
317 | |||
257 | static int | 318 | static int |
258 | process_principals(FILE *f, const char *file, struct passwd *pw, | 319 | process_principals(struct ssh *ssh, FILE *f, const char *file, |
259 | const struct sshkey_cert *cert) | 320 | const struct sshkey_cert *cert, struct sshauthopt **authoptsp) |
260 | { | 321 | { |
261 | char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; | 322 | char loc[256], line[SSH_MAX_PUBKEY_BYTES], *cp, *ep; |
262 | u_long linenum = 0; | 323 | u_long linenum = 0; |
263 | u_int i, found_principal = 0; | 324 | u_int found_principal = 0; |
325 | |||
326 | if (authoptsp != NULL) | ||
327 | *authoptsp = NULL; | ||
264 | 328 | ||
265 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 329 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
266 | /* Always consume entire input */ | 330 | /* Always consume entire input */ |
267 | if (found_principal) | 331 | if (found_principal) |
268 | continue; | 332 | continue; |
333 | |||
269 | /* Skip leading whitespace. */ | 334 | /* Skip leading whitespace. */ |
270 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) | 335 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) |
271 | ; | 336 | ; |
@@ -274,50 +339,33 @@ process_principals(FILE *f, const char *file, struct passwd *pw, | |||
274 | *ep = '\0'; | 339 | *ep = '\0'; |
275 | if (!*cp || *cp == '\n') | 340 | if (!*cp || *cp == '\n') |
276 | continue; | 341 | continue; |
277 | /* Trim trailing whitespace. */ | 342 | |
278 | ep = cp + strlen(cp) - 1; | 343 | snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum); |
279 | while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t')) | 344 | if (check_principals_line(ssh, cp, cert, loc, authoptsp) == 0) |
280 | *ep-- = '\0'; | 345 | found_principal = 1; |
281 | /* | ||
282 | * If the line has internal whitespace then assume it has | ||
283 | * key options. | ||
284 | */ | ||
285 | line_opts = NULL; | ||
286 | if ((ep = strrchr(cp, ' ')) != NULL || | ||
287 | (ep = strrchr(cp, '\t')) != NULL) { | ||
288 | for (; *ep == ' ' || *ep == '\t'; ep++) | ||
289 | ; | ||
290 | line_opts = cp; | ||
291 | cp = ep; | ||
292 | } | ||
293 | for (i = 0; i < cert->nprincipals; i++) { | ||
294 | if (strcmp(cp, cert->principals[i]) == 0) { | ||
295 | debug3("%s:%lu: matched principal \"%.100s\"", | ||
296 | file, linenum, cert->principals[i]); | ||
297 | if (auth_parse_options(pw, line_opts, | ||
298 | file, linenum) != 1) | ||
299 | continue; | ||
300 | found_principal = 1; | ||
301 | continue; | ||
302 | } | ||
303 | } | ||
304 | } | 346 | } |
305 | return found_principal; | 347 | return found_principal; |
306 | } | 348 | } |
307 | 349 | ||
350 | /* XXX remove pw args here and elsewhere once ssh->authctxt is guaranteed */ | ||
351 | |||
308 | static int | 352 | static int |
309 | match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert) | 353 | match_principals_file(struct ssh *ssh, struct passwd *pw, char *file, |
354 | struct sshkey_cert *cert, struct sshauthopt **authoptsp) | ||
310 | { | 355 | { |
311 | FILE *f; | 356 | FILE *f; |
312 | int success; | 357 | int success; |
313 | 358 | ||
359 | if (authoptsp != NULL) | ||
360 | *authoptsp = NULL; | ||
361 | |||
314 | temporarily_use_uid(pw); | 362 | temporarily_use_uid(pw); |
315 | debug("trying authorized principals file %s", file); | 363 | debug("trying authorized principals file %s", file); |
316 | if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) { | 364 | if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) { |
317 | restore_uid(); | 365 | restore_uid(); |
318 | return 0; | 366 | return 0; |
319 | } | 367 | } |
320 | success = process_principals(f, file, pw, cert); | 368 | success = process_principals(ssh, f, file, cert, authoptsp); |
321 | fclose(f); | 369 | fclose(f); |
322 | restore_uid(); | 370 | restore_uid(); |
323 | return success; | 371 | return success; |
@@ -328,12 +376,13 @@ match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert) | |||
328 | * returns 1 if the principal is allowed or 0 otherwise. | 376 | * returns 1 if the principal is allowed or 0 otherwise. |
329 | */ | 377 | */ |
330 | static int | 378 | static int |
331 | match_principals_command(struct passwd *user_pw, const struct sshkey *key) | 379 | match_principals_command(struct ssh *ssh, struct passwd *user_pw, |
380 | const struct sshkey *key, struct sshauthopt **authoptsp) | ||
332 | { | 381 | { |
382 | struct passwd *runas_pw = NULL; | ||
333 | const struct sshkey_cert *cert = key->cert; | 383 | const struct sshkey_cert *cert = key->cert; |
334 | FILE *f = NULL; | 384 | FILE *f = NULL; |
335 | int r, ok, found_principal = 0; | 385 | int r, ok, found_principal = 0; |
336 | struct passwd *pw; | ||
337 | int i, ac = 0, uid_swapped = 0; | 386 | int i, ac = 0, uid_swapped = 0; |
338 | pid_t pid; | 387 | pid_t pid; |
339 | char *tmp, *username = NULL, *command = NULL, **av = NULL; | 388 | char *tmp, *username = NULL, *command = NULL, **av = NULL; |
@@ -341,6 +390,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key) | |||
341 | char serial_s[16]; | 390 | char serial_s[16]; |
342 | void (*osigchld)(int); | 391 | void (*osigchld)(int); |
343 | 392 | ||
393 | if (authoptsp != NULL) | ||
394 | *authoptsp = NULL; | ||
344 | if (options.authorized_principals_command == NULL) | 395 | if (options.authorized_principals_command == NULL) |
345 | return 0; | 396 | return 0; |
346 | if (options.authorized_principals_command_user == NULL) { | 397 | if (options.authorized_principals_command_user == NULL) { |
@@ -358,8 +409,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key) | |||
358 | /* Prepare and verify the user for the command */ | 409 | /* Prepare and verify the user for the command */ |
359 | username = percent_expand(options.authorized_principals_command_user, | 410 | username = percent_expand(options.authorized_principals_command_user, |
360 | "u", user_pw->pw_name, (char *)NULL); | 411 | "u", user_pw->pw_name, (char *)NULL); |
361 | pw = getpwnam(username); | 412 | runas_pw = getpwnam(username); |
362 | if (pw == NULL) { | 413 | if (runas_pw == NULL) { |
363 | error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s", | 414 | error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s", |
364 | username, strerror(errno)); | 415 | username, strerror(errno)); |
365 | goto out; | 416 | goto out; |
@@ -417,15 +468,15 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key) | |||
417 | /* Prepare a printable command for logs, etc. */ | 468 | /* Prepare a printable command for logs, etc. */ |
418 | command = argv_assemble(ac, av); | 469 | command = argv_assemble(ac, av); |
419 | 470 | ||
420 | if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command, | 471 | if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command, |
421 | ac, av, &f, | 472 | ac, av, &f, |
422 | SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) | 473 | SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) |
423 | goto out; | 474 | goto out; |
424 | 475 | ||
425 | uid_swapped = 1; | 476 | uid_swapped = 1; |
426 | temporarily_use_uid(pw); | 477 | temporarily_use_uid(runas_pw); |
427 | 478 | ||
428 | ok = process_principals(f, "(command)", pw, cert); | 479 | ok = process_principals(ssh, f, "(command)", cert, authoptsp); |
429 | 480 | ||
430 | fclose(f); | 481 | fclose(f); |
431 | f = NULL; | 482 | f = NULL; |
@@ -452,130 +503,225 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key) | |||
452 | free(keytext); | 503 | free(keytext); |
453 | return found_principal; | 504 | return found_principal; |
454 | } | 505 | } |
506 | |||
507 | static void | ||
508 | skip_space(char **cpp) | ||
509 | { | ||
510 | char *cp; | ||
511 | |||
512 | for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) | ||
513 | ; | ||
514 | *cpp = cp; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * Advanced *cpp past the end of key options, defined as the first unquoted | ||
519 | * whitespace character. Returns 0 on success or -1 on failure (e.g. | ||
520 | * unterminated quotes). | ||
521 | */ | ||
522 | static int | ||
523 | advance_past_options(char **cpp) | ||
524 | { | ||
525 | char *cp = *cpp; | ||
526 | int quoted = 0; | ||
527 | |||
528 | for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { | ||
529 | if (*cp == '\\' && cp[1] == '"') | ||
530 | cp++; /* Skip both */ | ||
531 | else if (*cp == '"') | ||
532 | quoted = !quoted; | ||
533 | } | ||
534 | *cpp = cp; | ||
535 | /* return failure for unterminated quotes */ | ||
536 | return (*cp == '\0' && quoted) ? -1 : 0; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Check a single line of an authorized_keys-format file. Returns 0 if key | ||
541 | * matches, -1 otherwise. Will return key/cert options via *authoptsp | ||
542 | * on success. "loc" is used as file/line location in log messages. | ||
543 | */ | ||
544 | static int | ||
545 | check_authkey_line(struct ssh *ssh, struct passwd *pw, struct sshkey *key, | ||
546 | char *cp, const char *loc, struct sshauthopt **authoptsp) | ||
547 | { | ||
548 | int want_keytype = sshkey_is_cert(key) ? KEY_UNSPEC : key->type; | ||
549 | struct sshkey *found = NULL; | ||
550 | struct sshauthopt *keyopts = NULL, *certopts = NULL, *finalopts = NULL; | ||
551 | char *key_options = NULL, *fp = NULL; | ||
552 | const char *reason = NULL; | ||
553 | int ret = -1; | ||
554 | |||
555 | if (authoptsp != NULL) | ||
556 | *authoptsp = NULL; | ||
557 | |||
558 | if ((found = sshkey_new(want_keytype)) == NULL) { | ||
559 | debug3("%s: keytype %d failed", __func__, want_keytype); | ||
560 | goto out; | ||
561 | } | ||
562 | |||
563 | /* XXX djm: peek at key type in line and skip if unwanted */ | ||
564 | |||
565 | if (sshkey_read(found, &cp) != 0) { | ||
566 | /* no key? check for options */ | ||
567 | debug2("%s: check options: '%s'", loc, cp); | ||
568 | key_options = cp; | ||
569 | if (advance_past_options(&cp) != 0) { | ||
570 | reason = "invalid key option string"; | ||
571 | goto fail_reason; | ||
572 | } | ||
573 | skip_space(&cp); | ||
574 | if (sshkey_read(found, &cp) != 0) { | ||
575 | /* still no key? advance to next line*/ | ||
576 | debug2("%s: advance: '%s'", loc, cp); | ||
577 | goto out; | ||
578 | } | ||
579 | } | ||
580 | /* Parse key options now; we need to know if this is a CA key */ | ||
581 | if ((keyopts = sshauthopt_parse(key_options, &reason)) == NULL) { | ||
582 | debug("%s: bad key options: %s", loc, reason); | ||
583 | auth_debug_add("%s: bad key options: %s", loc, reason); | ||
584 | goto out; | ||
585 | } | ||
586 | /* Ignore keys that don't match or incorrectly marked as CAs */ | ||
587 | if (sshkey_is_cert(key)) { | ||
588 | /* Certificate; check signature key against CA */ | ||
589 | if (!sshkey_equal(found, key->cert->signature_key) || | ||
590 | !keyopts->cert_authority) | ||
591 | goto out; | ||
592 | } else { | ||
593 | /* Plain key: check it against key found in file */ | ||
594 | if (!sshkey_equal(found, key) || keyopts->cert_authority) | ||
595 | goto out; | ||
596 | } | ||
597 | |||
598 | /* We have a candidate key, perform authorisation checks */ | ||
599 | if ((fp = sshkey_fingerprint(found, | ||
600 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) | ||
601 | fatal("%s: fingerprint failed", __func__); | ||
602 | |||
603 | debug("%s: matching %s found: %s %s", loc, | ||
604 | sshkey_is_cert(key) ? "CA" : "key", sshkey_type(found), fp); | ||
605 | |||
606 | if (auth_authorise_keyopts(ssh, pw, keyopts, | ||
607 | sshkey_is_cert(key), loc) != 0) { | ||
608 | reason = "Refused by key options"; | ||
609 | goto fail_reason; | ||
610 | } | ||
611 | /* That's all we need for plain keys. */ | ||
612 | if (!sshkey_is_cert(key)) { | ||
613 | verbose("Accepted key %s %s found at %s", | ||
614 | sshkey_type(found), fp, loc); | ||
615 | finalopts = keyopts; | ||
616 | keyopts = NULL; | ||
617 | goto success; | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * Additional authorisation for certificates. | ||
622 | */ | ||
623 | |||
624 | /* Parse and check options present in certificate */ | ||
625 | if ((certopts = sshauthopt_from_cert(key)) == NULL) { | ||
626 | reason = "Invalid certificate options"; | ||
627 | goto fail_reason; | ||
628 | } | ||
629 | if (auth_authorise_keyopts(ssh, pw, certopts, 0, loc) != 0) { | ||
630 | reason = "Refused by certificate options"; | ||
631 | goto fail_reason; | ||
632 | } | ||
633 | if ((finalopts = sshauthopt_merge(keyopts, certopts, &reason)) == NULL) | ||
634 | goto fail_reason; | ||
635 | |||
636 | /* | ||
637 | * If the user has specified a list of principals as | ||
638 | * a key option, then prefer that list to matching | ||
639 | * their username in the certificate principals list. | ||
640 | */ | ||
641 | if (keyopts->cert_principals != NULL && | ||
642 | !match_principals_option(keyopts->cert_principals, key->cert)) { | ||
643 | reason = "Certificate does not contain an authorized principal"; | ||
644 | goto fail_reason; | ||
645 | } | ||
646 | if (sshkey_cert_check_authority(key, 0, 0, | ||
647 | keyopts->cert_principals == NULL ? pw->pw_name : NULL, &reason) != 0) | ||
648 | goto fail_reason; | ||
649 | |||
650 | verbose("Accepted certificate ID \"%s\" (serial %llu) " | ||
651 | "signed by CA %s %s found at %s", | ||
652 | key->cert->key_id, | ||
653 | (unsigned long long)key->cert->serial, | ||
654 | sshkey_type(found), fp, loc); | ||
655 | |||
656 | success: | ||
657 | if (finalopts == NULL) | ||
658 | fatal("%s: internal error: missing options", __func__); | ||
659 | if (authoptsp != NULL) { | ||
660 | *authoptsp = finalopts; | ||
661 | finalopts = NULL; | ||
662 | } | ||
663 | /* success */ | ||
664 | ret = 0; | ||
665 | goto out; | ||
666 | |||
667 | fail_reason: | ||
668 | error("%s", reason); | ||
669 | auth_debug_add("%s", reason); | ||
670 | out: | ||
671 | free(fp); | ||
672 | sshauthopt_free(keyopts); | ||
673 | sshauthopt_free(certopts); | ||
674 | sshauthopt_free(finalopts); | ||
675 | sshkey_free(found); | ||
676 | return ret; | ||
677 | } | ||
678 | |||
455 | /* | 679 | /* |
456 | * Checks whether key is allowed in authorized_keys-format file, | 680 | * Checks whether key is allowed in authorized_keys-format file, |
457 | * returns 1 if the key is allowed or 0 otherwise. | 681 | * returns 1 if the key is allowed or 0 otherwise. |
458 | */ | 682 | */ |
459 | static int | 683 | static int |
460 | check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw) | 684 | check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f, |
685 | char *file, struct sshkey *key, struct sshauthopt **authoptsp) | ||
461 | { | 686 | { |
462 | char line[SSH_MAX_PUBKEY_BYTES]; | 687 | char *cp, line[SSH_MAX_PUBKEY_BYTES], loc[256]; |
463 | int found_key = 0; | 688 | int found_key = 0; |
464 | u_long linenum = 0; | 689 | u_long linenum = 0; |
465 | struct sshkey *found = NULL; | ||
466 | 690 | ||
467 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 691 | if (authoptsp != NULL) |
468 | char *cp, *key_options = NULL, *fp = NULL; | 692 | *authoptsp = NULL; |
469 | const char *reason = NULL; | ||
470 | 693 | ||
694 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | ||
471 | /* Always consume entire file */ | 695 | /* Always consume entire file */ |
472 | if (found_key) | 696 | if (found_key) |
473 | continue; | 697 | continue; |
474 | sshkey_free(found); | ||
475 | found = sshkey_new(sshkey_is_cert(key) ? KEY_UNSPEC : key->type); | ||
476 | if (found == NULL) | ||
477 | goto done; | ||
478 | auth_clear_options(); | ||
479 | 698 | ||
480 | /* Skip leading whitespace, empty and comment lines. */ | 699 | /* Skip leading whitespace, empty and comment lines. */ |
481 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) | 700 | cp = line; |
482 | ; | 701 | skip_space(&cp); |
483 | if (!*cp || *cp == '\n' || *cp == '#') | 702 | if (!*cp || *cp == '\n' || *cp == '#') |
484 | continue; | 703 | continue; |
485 | 704 | snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum); | |
486 | if (sshkey_read(found, &cp) != 0) { | 705 | if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0) |
487 | /* no key? check if there are options for this key */ | ||
488 | int quoted = 0; | ||
489 | debug2("user_key_allowed: check options: '%s'", cp); | ||
490 | key_options = cp; | ||
491 | for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { | ||
492 | if (*cp == '\\' && cp[1] == '"') | ||
493 | cp++; /* Skip both */ | ||
494 | else if (*cp == '"') | ||
495 | quoted = !quoted; | ||
496 | } | ||
497 | /* Skip remaining whitespace. */ | ||
498 | for (; *cp == ' ' || *cp == '\t'; cp++) | ||
499 | ; | ||
500 | if (sshkey_read(found, &cp) != 0) { | ||
501 | debug2("user_key_allowed: advance: '%s'", cp); | ||
502 | /* still no key? advance to next line*/ | ||
503 | continue; | ||
504 | } | ||
505 | } | ||
506 | if (sshkey_is_cert(key)) { | ||
507 | if (!sshkey_equal(found, key->cert->signature_key)) | ||
508 | continue; | ||
509 | if (auth_parse_options(pw, key_options, file, | ||
510 | linenum) != 1) | ||
511 | continue; | ||
512 | if (!key_is_cert_authority) | ||
513 | continue; | ||
514 | if ((fp = sshkey_fingerprint(found, | ||
515 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) | ||
516 | continue; | ||
517 | debug("matching CA found: file %s, line %lu, %s %s", | ||
518 | file, linenum, sshkey_type(found), fp); | ||
519 | /* | ||
520 | * If the user has specified a list of principals as | ||
521 | * a key option, then prefer that list to matching | ||
522 | * their username in the certificate principals list. | ||
523 | */ | ||
524 | if (authorized_principals != NULL && | ||
525 | !match_principals_option(authorized_principals, | ||
526 | key->cert)) { | ||
527 | reason = "Certificate does not contain an " | ||
528 | "authorized principal"; | ||
529 | fail_reason: | ||
530 | free(fp); | ||
531 | error("%s", reason); | ||
532 | auth_debug_add("%s", reason); | ||
533 | continue; | ||
534 | } | ||
535 | if (sshkey_cert_check_authority(key, 0, 0, | ||
536 | authorized_principals == NULL ? pw->pw_name : NULL, | ||
537 | &reason) != 0) | ||
538 | goto fail_reason; | ||
539 | if (auth_cert_options(key, pw, &reason) != 0) | ||
540 | goto fail_reason; | ||
541 | verbose("Accepted certificate ID \"%s\" (serial %llu) " | ||
542 | "signed by %s CA %s via %s", key->cert->key_id, | ||
543 | (unsigned long long)key->cert->serial, | ||
544 | sshkey_type(found), fp, file); | ||
545 | free(fp); | ||
546 | found_key = 1; | ||
547 | break; | ||
548 | } else if (sshkey_equal(found, key)) { | ||
549 | if (auth_parse_options(pw, key_options, file, | ||
550 | linenum) != 1) | ||
551 | continue; | ||
552 | if (key_is_cert_authority) | ||
553 | continue; | ||
554 | if ((fp = sshkey_fingerprint(found, | ||
555 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) | ||
556 | continue; | ||
557 | debug("matching key found: file %s, line %lu %s %s", | ||
558 | file, linenum, sshkey_type(found), fp); | ||
559 | free(fp); | ||
560 | found_key = 1; | 706 | found_key = 1; |
561 | continue; | ||
562 | } | ||
563 | } | 707 | } |
564 | done: | ||
565 | sshkey_free(found); | ||
566 | if (!found_key) | ||
567 | debug2("key not found"); | ||
568 | return found_key; | 708 | return found_key; |
569 | } | 709 | } |
570 | 710 | ||
571 | /* Authenticate a certificate key against TrustedUserCAKeys */ | 711 | /* Authenticate a certificate key against TrustedUserCAKeys */ |
572 | static int | 712 | static int |
573 | user_cert_trusted_ca(struct passwd *pw, struct sshkey *key) | 713 | user_cert_trusted_ca(struct ssh *ssh, struct passwd *pw, struct sshkey *key, |
714 | struct sshauthopt **authoptsp) | ||
574 | { | 715 | { |
575 | char *ca_fp, *principals_file = NULL; | 716 | char *ca_fp, *principals_file = NULL; |
576 | const char *reason; | 717 | const char *reason; |
718 | struct sshauthopt *principals_opts = NULL, *cert_opts = NULL; | ||
719 | struct sshauthopt *final_opts = NULL; | ||
577 | int r, ret = 0, found_principal = 0, use_authorized_principals; | 720 | int r, ret = 0, found_principal = 0, use_authorized_principals; |
578 | 721 | ||
722 | if (authoptsp != NULL) | ||
723 | *authoptsp = NULL; | ||
724 | |||
579 | if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL) | 725 | if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL) |
580 | return 0; | 726 | return 0; |
581 | 727 | ||
@@ -596,36 +742,69 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key) | |||
596 | * against the username. | 742 | * against the username. |
597 | */ | 743 | */ |
598 | if ((principals_file = authorized_principals_file(pw)) != NULL) { | 744 | if ((principals_file = authorized_principals_file(pw)) != NULL) { |
599 | if (match_principals_file(principals_file, pw, key->cert)) | 745 | if (match_principals_file(ssh, pw, principals_file, |
746 | key->cert, &principals_opts)) | ||
600 | found_principal = 1; | 747 | found_principal = 1; |
601 | } | 748 | } |
602 | /* Try querying command if specified */ | 749 | /* Try querying command if specified */ |
603 | if (!found_principal && match_principals_command(pw, key)) | 750 | if (!found_principal && match_principals_command(ssh, pw, key, |
751 | &principals_opts)) | ||
604 | found_principal = 1; | 752 | found_principal = 1; |
605 | /* If principals file or command is specified, then require a match */ | 753 | /* If principals file or command is specified, then require a match */ |
606 | use_authorized_principals = principals_file != NULL || | 754 | use_authorized_principals = principals_file != NULL || |
607 | options.authorized_principals_command != NULL; | 755 | options.authorized_principals_command != NULL; |
608 | if (!found_principal && use_authorized_principals) { | 756 | if (!found_principal && use_authorized_principals) { |
609 | reason = "Certificate does not contain an authorized principal"; | 757 | reason = "Certificate does not contain an authorized principal"; |
610 | fail_reason: | 758 | goto fail_reason; |
611 | error("%s", reason); | ||
612 | auth_debug_add("%s", reason); | ||
613 | goto out; | ||
614 | } | 759 | } |
760 | if (use_authorized_principals && principals_opts == NULL) | ||
761 | fatal("%s: internal error: missing principals_opts", __func__); | ||
615 | if (sshkey_cert_check_authority(key, 0, 1, | 762 | if (sshkey_cert_check_authority(key, 0, 1, |
616 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) | 763 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) |
617 | goto fail_reason; | 764 | goto fail_reason; |
618 | if (auth_cert_options(key, pw, &reason) != 0) | 765 | |
766 | /* Check authority from options in key and from principals file/cmd */ | ||
767 | if ((cert_opts = sshauthopt_from_cert(key)) == NULL) { | ||
768 | reason = "Invalid certificate options"; | ||
769 | goto fail_reason; | ||
770 | } | ||
771 | if (auth_authorise_keyopts(ssh, pw, cert_opts, 0, "cert") != 0) { | ||
772 | reason = "Refused by certificate options"; | ||
619 | goto fail_reason; | 773 | goto fail_reason; |
774 | } | ||
775 | if (principals_opts == NULL) { | ||
776 | final_opts = cert_opts; | ||
777 | cert_opts = NULL; | ||
778 | } else { | ||
779 | if (auth_authorise_keyopts(ssh, pw, principals_opts, 0, | ||
780 | "principals") != 0) { | ||
781 | reason = "Refused by certificate principals options"; | ||
782 | goto fail_reason; | ||
783 | } | ||
784 | if ((final_opts = sshauthopt_merge(principals_opts, | ||
785 | cert_opts, &reason)) == NULL) { | ||
786 | fail_reason: | ||
787 | error("%s", reason); | ||
788 | auth_debug_add("%s", reason); | ||
789 | goto out; | ||
790 | } | ||
791 | } | ||
620 | 792 | ||
793 | /* Success */ | ||
621 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " | 794 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " |
622 | "%s CA %s via %s", key->cert->key_id, | 795 | "%s CA %s via %s", key->cert->key_id, |
623 | (unsigned long long)key->cert->serial, | 796 | (unsigned long long)key->cert->serial, |
624 | sshkey_type(key->cert->signature_key), ca_fp, | 797 | sshkey_type(key->cert->signature_key), ca_fp, |
625 | options.trusted_user_ca_keys); | 798 | options.trusted_user_ca_keys); |
799 | if (authoptsp != NULL) { | ||
800 | *authoptsp = final_opts; | ||
801 | final_opts = NULL; | ||
802 | } | ||
626 | ret = 1; | 803 | ret = 1; |
627 | |||
628 | out: | 804 | out: |
805 | sshauthopt_free(principals_opts); | ||
806 | sshauthopt_free(cert_opts); | ||
807 | sshauthopt_free(final_opts); | ||
629 | free(principals_file); | 808 | free(principals_file); |
630 | free(ca_fp); | 809 | free(ca_fp); |
631 | return ret; | 810 | return ret; |
@@ -636,17 +815,22 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key) | |||
636 | * returns 1 if the key is allowed or 0 otherwise. | 815 | * returns 1 if the key is allowed or 0 otherwise. |
637 | */ | 816 | */ |
638 | static int | 817 | static int |
639 | user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file) | 818 | user_key_allowed2(struct ssh *ssh, struct passwd *pw, struct sshkey *key, |
819 | char *file, struct sshauthopt **authoptsp) | ||
640 | { | 820 | { |
641 | FILE *f; | 821 | FILE *f; |
642 | int found_key = 0; | 822 | int found_key = 0; |
643 | 823 | ||
824 | if (authoptsp != NULL) | ||
825 | *authoptsp = NULL; | ||
826 | |||
644 | /* Temporarily use the user's uid. */ | 827 | /* Temporarily use the user's uid. */ |
645 | temporarily_use_uid(pw); | 828 | temporarily_use_uid(pw); |
646 | 829 | ||
647 | debug("trying public key file %s", file); | 830 | debug("trying public key file %s", file); |
648 | if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) { | 831 | if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) { |
649 | found_key = check_authkeys_file(f, file, key, pw); | 832 | found_key = check_authkeys_file(ssh, pw, f, file, |
833 | key, authoptsp); | ||
650 | fclose(f); | 834 | fclose(f); |
651 | } | 835 | } |
652 | 836 | ||
@@ -659,17 +843,20 @@ user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file) | |||
659 | * returns 1 if the key is allowed or 0 otherwise. | 843 | * returns 1 if the key is allowed or 0 otherwise. |
660 | */ | 844 | */ |
661 | static int | 845 | static int |
662 | user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key) | 846 | user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw, |
847 | struct sshkey *key, struct sshauthopt **authoptsp) | ||
663 | { | 848 | { |
849 | struct passwd *runas_pw = NULL; | ||
664 | FILE *f = NULL; | 850 | FILE *f = NULL; |
665 | int r, ok, found_key = 0; | 851 | int r, ok, found_key = 0; |
666 | struct passwd *pw; | ||
667 | int i, uid_swapped = 0, ac = 0; | 852 | int i, uid_swapped = 0, ac = 0; |
668 | pid_t pid; | 853 | pid_t pid; |
669 | char *username = NULL, *key_fp = NULL, *keytext = NULL; | 854 | char *username = NULL, *key_fp = NULL, *keytext = NULL; |
670 | char *tmp, *command = NULL, **av = NULL; | 855 | char *tmp, *command = NULL, **av = NULL; |
671 | void (*osigchld)(int); | 856 | void (*osigchld)(int); |
672 | 857 | ||
858 | if (authoptsp != NULL) | ||
859 | *authoptsp = NULL; | ||
673 | if (options.authorized_keys_command == NULL) | 860 | if (options.authorized_keys_command == NULL) |
674 | return 0; | 861 | return 0; |
675 | if (options.authorized_keys_command_user == NULL) { | 862 | if (options.authorized_keys_command_user == NULL) { |
@@ -686,8 +873,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key) | |||
686 | /* Prepare and verify the user for the command */ | 873 | /* Prepare and verify the user for the command */ |
687 | username = percent_expand(options.authorized_keys_command_user, | 874 | username = percent_expand(options.authorized_keys_command_user, |
688 | "u", user_pw->pw_name, (char *)NULL); | 875 | "u", user_pw->pw_name, (char *)NULL); |
689 | pw = getpwnam(username); | 876 | runas_pw = getpwnam(username); |
690 | if (pw == NULL) { | 877 | if (runas_pw == NULL) { |
691 | error("AuthorizedKeysCommandUser \"%s\" not found: %s", | 878 | error("AuthorizedKeysCommandUser \"%s\" not found: %s", |
692 | username, strerror(errno)); | 879 | username, strerror(errno)); |
693 | goto out; | 880 | goto out; |
@@ -745,15 +932,16 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key) | |||
745 | xasprintf(&command, "%s %s", av[0], av[1]); | 932 | xasprintf(&command, "%s %s", av[0], av[1]); |
746 | } | 933 | } |
747 | 934 | ||
748 | if ((pid = subprocess("AuthorizedKeysCommand", pw, command, | 935 | if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command, |
749 | ac, av, &f, | 936 | ac, av, &f, |
750 | SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) | 937 | SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) |
751 | goto out; | 938 | goto out; |
752 | 939 | ||
753 | uid_swapped = 1; | 940 | uid_swapped = 1; |
754 | temporarily_use_uid(pw); | 941 | temporarily_use_uid(runas_pw); |
755 | 942 | ||
756 | ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); | 943 | ok = check_authkeys_file(ssh, user_pw, f, |
944 | options.authorized_keys_command, key, authoptsp); | ||
757 | 945 | ||
758 | fclose(f); | 946 | fclose(f); |
759 | f = NULL; | 947 | f = NULL; |
@@ -783,10 +971,14 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key) | |||
783 | * Check whether key authenticates and authorises the user. | 971 | * Check whether key authenticates and authorises the user. |
784 | */ | 972 | */ |
785 | int | 973 | int |
786 | user_key_allowed(struct passwd *pw, struct sshkey *key, int auth_attempt) | 974 | user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, |
975 | int auth_attempt, struct sshauthopt **authoptsp) | ||
787 | { | 976 | { |
788 | u_int success, i; | 977 | u_int success, i; |
789 | char *file; | 978 | char *file; |
979 | struct sshauthopt *opts = NULL; | ||
980 | if (authoptsp != NULL) | ||
981 | *authoptsp = NULL; | ||
790 | 982 | ||
791 | if (auth_key_is_revoked(key)) | 983 | if (auth_key_is_revoked(key)) |
792 | return 0; | 984 | return 0; |
@@ -794,25 +986,31 @@ user_key_allowed(struct passwd *pw, struct sshkey *key, int auth_attempt) | |||
794 | auth_key_is_revoked(key->cert->signature_key)) | 986 | auth_key_is_revoked(key->cert->signature_key)) |
795 | return 0; | 987 | return 0; |
796 | 988 | ||
797 | success = user_cert_trusted_ca(pw, key); | 989 | if ((success = user_cert_trusted_ca(ssh, pw, key, &opts)) != 0) |
798 | if (success) | 990 | goto out; |
799 | return success; | 991 | sshauthopt_free(opts); |
992 | opts = NULL; | ||
800 | 993 | ||
801 | success = user_key_command_allowed2(pw, key); | 994 | if ((success = user_key_command_allowed2(ssh, pw, key, &opts)) != 0) |
802 | if (success > 0) | 995 | goto out; |
803 | return success; | 996 | sshauthopt_free(opts); |
997 | opts = NULL; | ||
804 | 998 | ||
805 | for (i = 0; !success && i < options.num_authkeys_files; i++) { | 999 | for (i = 0; !success && i < options.num_authkeys_files; i++) { |
806 | |||
807 | if (strcasecmp(options.authorized_keys_files[i], "none") == 0) | 1000 | if (strcasecmp(options.authorized_keys_files[i], "none") == 0) |
808 | continue; | 1001 | continue; |
809 | file = expand_authorized_keys( | 1002 | file = expand_authorized_keys( |
810 | options.authorized_keys_files[i], pw); | 1003 | options.authorized_keys_files[i], pw); |
811 | 1004 | success = user_key_allowed2(ssh, pw, key, file, &opts); | |
812 | success = user_key_allowed2(pw, key, file); | ||
813 | free(file); | 1005 | free(file); |
814 | } | 1006 | } |
815 | 1007 | ||
1008 | out: | ||
1009 | if (success && authoptsp != NULL) { | ||
1010 | *authoptsp = opts; | ||
1011 | opts = NULL; | ||
1012 | } | ||
1013 | sshauthopt_free(opts); | ||
816 | return success; | 1014 | return success; |
817 | } | 1015 | } |
818 | 1016 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2.c,v 1.144 2018/01/23 05:27:21 djm Exp $ */ | 1 | /* $OpenBSD: auth2.c,v 1.145 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -310,7 +310,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, | |||
310 | 310 | ||
311 | /* Special handling for root */ | 311 | /* Special handling for root */ |
312 | if (authenticated && authctxt->pw->pw_uid == 0 && | 312 | if (authenticated && authctxt->pw->pw_uid == 0 && |
313 | !auth_root_allowed(method)) { | 313 | !auth_root_allowed(ssh, method)) { |
314 | authenticated = 0; | 314 | authenticated = 0; |
315 | #ifdef SSH_AUDIT_EVENTS | 315 | #ifdef SSH_AUDIT_EVENTS |
316 | PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); | 316 | PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.124 2018/03/02 03:02:11 djm Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.125 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -1921,6 +1921,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name, | |||
1921 | } | 1921 | } |
1922 | 1922 | ||
1923 | /* Allocate space and format the variable in the appropriate slot. */ | 1923 | /* Allocate space and format the variable in the appropriate slot. */ |
1924 | /* XXX xasprintf */ | ||
1924 | env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); | 1925 | env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); |
1925 | snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); | 1926 | snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); |
1926 | } | 1927 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.179 2018/02/05 05:37:46 tb Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.180 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -116,6 +116,7 @@ extern u_char session_id[]; | |||
116 | extern Buffer auth_debug; | 116 | extern Buffer auth_debug; |
117 | extern int auth_debug_init; | 117 | extern int auth_debug_init; |
118 | extern Buffer loginmsg; | 118 | extern Buffer loginmsg; |
119 | extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ | ||
119 | 120 | ||
120 | /* State exported from the child */ | 121 | /* State exported from the child */ |
121 | static struct sshbuf *child_state; | 122 | static struct sshbuf *child_state; |
@@ -172,6 +173,7 @@ static Authctxt *authctxt; | |||
172 | static u_char *key_blob = NULL; | 173 | static u_char *key_blob = NULL; |
173 | static u_int key_bloblen = 0; | 174 | static u_int key_bloblen = 0; |
174 | static int key_blobtype = MM_NOKEY; | 175 | static int key_blobtype = MM_NOKEY; |
176 | static struct sshauthopt *key_opts = NULL; | ||
175 | static char *hostbased_cuser = NULL; | 177 | static char *hostbased_cuser = NULL; |
176 | static char *hostbased_chost = NULL; | 178 | static char *hostbased_chost = NULL; |
177 | static char *auth_method = "unknown"; | 179 | static char *auth_method = "unknown"; |
@@ -252,7 +254,6 @@ struct mon_table mon_dispatch_postauth20[] = { | |||
252 | struct mon_table *mon_dispatch; | 254 | struct mon_table *mon_dispatch; |
253 | 255 | ||
254 | /* Specifies if a certain message is allowed at the moment */ | 256 | /* Specifies if a certain message is allowed at the moment */ |
255 | |||
256 | static void | 257 | static void |
257 | monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) | 258 | monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) |
258 | { | 259 | { |
@@ -297,6 +298,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
297 | 298 | ||
298 | authctxt = _authctxt; | 299 | authctxt = _authctxt; |
299 | memset(authctxt, 0, sizeof(*authctxt)); | 300 | memset(authctxt, 0, sizeof(*authctxt)); |
301 | ssh->authctxt = authctxt; | ||
300 | 302 | ||
301 | authctxt->loginmsg = &loginmsg; | 303 | authctxt->loginmsg = &loginmsg; |
302 | 304 | ||
@@ -331,7 +333,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
331 | fatal("%s: unexpected authentication from %d", | 333 | fatal("%s: unexpected authentication from %d", |
332 | __func__, ent->type); | 334 | __func__, ent->type); |
333 | if (authctxt->pw->pw_uid == 0 && | 335 | if (authctxt->pw->pw_uid == 0 && |
334 | !auth_root_allowed(auth_method)) | 336 | !auth_root_allowed(ssh, auth_method)) |
335 | authenticated = 0; | 337 | authenticated = 0; |
336 | #ifdef USE_PAM | 338 | #ifdef USE_PAM |
337 | /* PAM needs to perform account checks after auth */ | 339 | /* PAM needs to perform account checks after auth */ |
@@ -365,6 +367,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
365 | 367 | ||
366 | debug("%s: %s has been authenticated by privileged process", | 368 | debug("%s: %s has been authenticated by privileged process", |
367 | __func__, authctxt->user); | 369 | __func__, authctxt->user); |
370 | ssh->authctxt = NULL; | ||
368 | ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); | 371 | ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
369 | 372 | ||
370 | mm_get_keystate(pmonitor); | 373 | mm_get_keystate(pmonitor); |
@@ -413,7 +416,7 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
413 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | 416 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
414 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | 417 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); |
415 | 418 | ||
416 | if (!no_pty_flag) { | 419 | if (auth_opts->permit_pty_flag) { |
417 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); | 420 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); |
418 | monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); | 421 | monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); |
419 | } | 422 | } |
@@ -558,9 +561,11 @@ monitor_reset_key_state(void) | |||
558 | free(key_blob); | 561 | free(key_blob); |
559 | free(hostbased_cuser); | 562 | free(hostbased_cuser); |
560 | free(hostbased_chost); | 563 | free(hostbased_chost); |
564 | sshauthopt_free(key_opts); | ||
561 | key_blob = NULL; | 565 | key_blob = NULL; |
562 | key_bloblen = 0; | 566 | key_bloblen = 0; |
563 | key_blobtype = MM_NOKEY; | 567 | key_blobtype = MM_NOKEY; |
568 | key_opts = NULL; | ||
564 | hostbased_cuser = NULL; | 569 | hostbased_cuser = NULL; |
565 | hostbased_chost = NULL; | 570 | hostbased_chost = NULL; |
566 | } | 571 | } |
@@ -828,6 +833,7 @@ mm_answer_authserv(int sock, Buffer *m) | |||
828 | int | 833 | int |
829 | mm_answer_authpassword(int sock, Buffer *m) | 834 | mm_answer_authpassword(int sock, Buffer *m) |
830 | { | 835 | { |
836 | struct ssh *ssh = active_state; /* XXX */ | ||
831 | static int call_count; | 837 | static int call_count; |
832 | char *passwd; | 838 | char *passwd; |
833 | int authenticated; | 839 | int authenticated; |
@@ -838,7 +844,7 @@ mm_answer_authpassword(int sock, Buffer *m) | |||
838 | passwd = buffer_get_string(m, &plen); | 844 | passwd = buffer_get_string(m, &plen); |
839 | /* Only authenticate if the context is valid */ | 845 | /* Only authenticate if the context is valid */ |
840 | authenticated = options.password_authentication && | 846 | authenticated = options.password_authentication && |
841 | auth_password(authctxt, passwd); | 847 | auth_password(ssh, passwd); |
842 | explicit_bzero(passwd, strlen(passwd)); | 848 | explicit_bzero(passwd, strlen(passwd)); |
843 | free(passwd); | 849 | free(passwd); |
844 | 850 | ||
@@ -1129,15 +1135,16 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) | |||
1129 | int | 1135 | int |
1130 | mm_answer_keyallowed(int sock, Buffer *m) | 1136 | mm_answer_keyallowed(int sock, Buffer *m) |
1131 | { | 1137 | { |
1138 | struct ssh *ssh = active_state; /* XXX */ | ||
1132 | struct sshkey *key; | 1139 | struct sshkey *key; |
1133 | char *cuser, *chost; | 1140 | char *cuser, *chost; |
1134 | u_char *blob; | 1141 | u_char *blob; |
1135 | u_int bloblen, pubkey_auth_attempt; | 1142 | u_int bloblen, pubkey_auth_attempt; |
1136 | enum mm_keytype type = 0; | 1143 | enum mm_keytype type = 0; |
1137 | int allowed = 0; | 1144 | int r, allowed = 0; |
1145 | struct sshauthopt *opts = NULL; | ||
1138 | 1146 | ||
1139 | debug3("%s entering", __func__); | 1147 | debug3("%s entering", __func__); |
1140 | |||
1141 | type = buffer_get_int(m); | 1148 | type = buffer_get_int(m); |
1142 | cuser = buffer_get_string(m, NULL); | 1149 | cuser = buffer_get_string(m, NULL); |
1143 | chost = buffer_get_string(m, NULL); | 1150 | chost = buffer_get_string(m, NULL); |
@@ -1156,28 +1163,31 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1156 | 1163 | ||
1157 | switch (type) { | 1164 | switch (type) { |
1158 | case MM_USERKEY: | 1165 | case MM_USERKEY: |
1159 | allowed = options.pubkey_authentication && | ||
1160 | !auth2_key_already_used(authctxt, key) && | ||
1161 | match_pattern_list(sshkey_ssh_name(key), | ||
1162 | options.pubkey_key_types, 0) == 1 && | ||
1163 | user_key_allowed(authctxt->pw, key, | ||
1164 | pubkey_auth_attempt); | ||
1165 | auth_method = "publickey"; | 1166 | auth_method = "publickey"; |
1166 | if (options.pubkey_authentication && | 1167 | if (!options.pubkey_authentication) |
1167 | (!pubkey_auth_attempt || allowed != 1)) | 1168 | break; |
1168 | auth_clear_options(); | 1169 | if (auth2_key_already_used(authctxt, key)) |
1170 | break; | ||
1171 | if (match_pattern_list(sshkey_ssh_name(key), | ||
1172 | options.pubkey_key_types, 0) != 1) | ||
1173 | break; | ||
1174 | allowed = user_key_allowed(ssh, authctxt->pw, key, | ||
1175 | pubkey_auth_attempt, &opts); | ||
1169 | break; | 1176 | break; |
1170 | case MM_HOSTKEY: | 1177 | case MM_HOSTKEY: |
1171 | allowed = options.hostbased_authentication && | 1178 | auth_method = "hostbased"; |
1172 | !auth2_key_already_used(authctxt, key) && | 1179 | if (!options.hostbased_authentication) |
1173 | match_pattern_list(sshkey_ssh_name(key), | 1180 | break; |
1174 | options.hostbased_key_types, 0) == 1 && | 1181 | if (auth2_key_already_used(authctxt, key)) |
1175 | hostbased_key_allowed(authctxt->pw, | 1182 | break; |
1183 | if (match_pattern_list(sshkey_ssh_name(key), | ||
1184 | options.hostbased_key_types, 0) != 1) | ||
1185 | break; | ||
1186 | allowed = hostbased_key_allowed(authctxt->pw, | ||
1176 | cuser, chost, key); | 1187 | cuser, chost, key); |
1177 | auth2_record_info(authctxt, | 1188 | auth2_record_info(authctxt, |
1178 | "client user \"%.100s\", client host \"%.100s\"", | 1189 | "client user \"%.100s\", client host \"%.100s\"", |
1179 | cuser, chost); | 1190 | cuser, chost); |
1180 | auth_method = "hostbased"; | ||
1181 | break; | 1191 | break; |
1182 | default: | 1192 | default: |
1183 | fatal("%s: unknown key type %d", __func__, type); | 1193 | fatal("%s: unknown key type %d", __func__, type); |
@@ -1185,7 +1195,10 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1185 | } | 1195 | } |
1186 | } | 1196 | } |
1187 | 1197 | ||
1188 | debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed"); | 1198 | debug3("%s: %s authentication%s: %s key is %s", __func__, |
1199 | auth_method, pubkey_auth_attempt ? "" : " test", | ||
1200 | (key == NULL || !authctxt->valid) ? "invalid" : sshkey_type(key), | ||
1201 | allowed ? "allowed" : "not allowed"); | ||
1189 | 1202 | ||
1190 | auth2_record_key(authctxt, 0, key); | 1203 | auth2_record_key(authctxt, 0, key); |
1191 | sshkey_free(key); | 1204 | sshkey_free(key); |
@@ -1198,6 +1211,7 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1198 | key_blob = blob; | 1211 | key_blob = blob; |
1199 | key_bloblen = bloblen; | 1212 | key_bloblen = bloblen; |
1200 | key_blobtype = type; | 1213 | key_blobtype = type; |
1214 | key_opts = opts; | ||
1201 | hostbased_cuser = cuser; | 1215 | hostbased_cuser = cuser; |
1202 | hostbased_chost = chost; | 1216 | hostbased_chost = chost; |
1203 | } else { | 1217 | } else { |
@@ -1210,10 +1224,13 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1210 | 1224 | ||
1211 | buffer_clear(m); | 1225 | buffer_clear(m); |
1212 | buffer_put_int(m, allowed); | 1226 | buffer_put_int(m, allowed); |
1213 | buffer_put_int(m, forced_command != NULL); | 1227 | if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0) |
1214 | 1228 | fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); | |
1215 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); | 1229 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); |
1216 | 1230 | ||
1231 | if (!allowed) | ||
1232 | sshauthopt_free(opts); | ||
1233 | |||
1217 | return (0); | 1234 | return (0); |
1218 | } | 1235 | } |
1219 | 1236 | ||
@@ -1336,6 +1353,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, | |||
1336 | int | 1353 | int |
1337 | mm_answer_keyverify(int sock, struct sshbuf *m) | 1354 | mm_answer_keyverify(int sock, struct sshbuf *m) |
1338 | { | 1355 | { |
1356 | struct ssh *ssh = active_state; /* XXX */ | ||
1339 | struct sshkey *key; | 1357 | struct sshkey *key; |
1340 | u_char *signature, *data, *blob; | 1358 | u_char *signature, *data, *blob; |
1341 | char *sigalg; | 1359 | char *sigalg; |
@@ -1390,6 +1408,8 @@ mm_answer_keyverify(int sock, struct sshbuf *m) | |||
1390 | free(data); | 1408 | free(data); |
1391 | free(sigalg); | 1409 | free(sigalg); |
1392 | 1410 | ||
1411 | if (key_blobtype == MM_USERKEY) | ||
1412 | auth_activate_options(ssh, key_opts); | ||
1393 | monitor_reset_key_state(); | 1413 | monitor_reset_key_state(); |
1394 | 1414 | ||
1395 | sshkey_free(key); | 1415 | sshkey_free(key); |
diff --git a/monitor_wrap.c b/monitor_wrap.c index cce318bc5..9666bda4b 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.c,v 1.98 2018/01/08 15:14:44 markus Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.c,v 1.99 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -351,7 +351,7 @@ mm_inform_authserv(char *service, char *style) | |||
351 | 351 | ||
352 | /* Do the password authentication */ | 352 | /* Do the password authentication */ |
353 | int | 353 | int |
354 | mm_auth_password(Authctxt *authctxt, char *password) | 354 | mm_auth_password(struct ssh *ssh, char *password) |
355 | { | 355 | { |
356 | Buffer m; | 356 | Buffer m; |
357 | int authenticated = 0; | 357 | int authenticated = 0; |
@@ -378,34 +378,38 @@ mm_auth_password(Authctxt *authctxt, char *password) | |||
378 | } | 378 | } |
379 | 379 | ||
380 | int | 380 | int |
381 | mm_user_key_allowed(struct passwd *pw, struct sshkey *key, | 381 | mm_user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, |
382 | int pubkey_auth_attempt) | 382 | int pubkey_auth_attempt, struct sshauthopt **authoptp) |
383 | { | 383 | { |
384 | return (mm_key_allowed(MM_USERKEY, NULL, NULL, key, | 384 | return (mm_key_allowed(MM_USERKEY, NULL, NULL, key, |
385 | pubkey_auth_attempt)); | 385 | pubkey_auth_attempt, authoptp)); |
386 | } | 386 | } |
387 | 387 | ||
388 | int | 388 | int |
389 | mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host, | 389 | mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host, |
390 | struct sshkey *key) | 390 | struct sshkey *key) |
391 | { | 391 | { |
392 | return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0)); | 392 | return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0, NULL)); |
393 | } | 393 | } |
394 | 394 | ||
395 | int | 395 | int |
396 | mm_key_allowed(enum mm_keytype type, const char *user, const char *host, | 396 | mm_key_allowed(enum mm_keytype type, const char *user, const char *host, |
397 | struct sshkey *key, int pubkey_auth_attempt) | 397 | struct sshkey *key, int pubkey_auth_attempt, struct sshauthopt **authoptp) |
398 | { | 398 | { |
399 | Buffer m; | 399 | Buffer m; |
400 | u_char *blob; | 400 | u_char *blob; |
401 | u_int len; | 401 | u_int len; |
402 | int allowed = 0, have_forced = 0; | 402 | int r, allowed = 0; |
403 | struct sshauthopt *opts = NULL; | ||
403 | 404 | ||
404 | debug3("%s entering", __func__); | 405 | debug3("%s entering", __func__); |
405 | 406 | ||
407 | if (authoptp != NULL) | ||
408 | *authoptp = NULL; | ||
409 | |||
406 | /* Convert the key to a blob and the pass it over */ | 410 | /* Convert the key to a blob and the pass it over */ |
407 | if (!key_to_blob(key, &blob, &len)) | 411 | if (!key_to_blob(key, &blob, &len)) |
408 | return (0); | 412 | return 0; |
409 | 413 | ||
410 | buffer_init(&m); | 414 | buffer_init(&m); |
411 | buffer_put_int(&m, type); | 415 | buffer_put_int(&m, type); |
@@ -418,18 +422,24 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, | |||
418 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); | 422 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); |
419 | 423 | ||
420 | debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); | 424 | debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); |
421 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); | 425 | mm_request_receive_expect(pmonitor->m_recvfd, |
426 | MONITOR_ANS_KEYALLOWED, &m); | ||
422 | 427 | ||
423 | allowed = buffer_get_int(&m); | 428 | allowed = buffer_get_int(&m); |
424 | 429 | if (allowed && type == MM_USERKEY) { | |
425 | /* fake forced command */ | 430 | if ((r = sshauthopt_deserialise(&m, &opts)) != 0) |
426 | auth_clear_options(); | 431 | fatal("%s: sshauthopt_deserialise: %s", |
427 | have_forced = buffer_get_int(&m); | 432 | __func__, ssh_err(r)); |
428 | forced_command = have_forced ? xstrdup("true") : NULL; | 433 | } |
429 | |||
430 | buffer_free(&m); | 434 | buffer_free(&m); |
431 | 435 | ||
432 | return (allowed); | 436 | if (authoptp != NULL) { |
437 | *authoptp = opts; | ||
438 | opts = NULL; | ||
439 | } | ||
440 | sshauthopt_free(opts); | ||
441 | |||
442 | return allowed; | ||
433 | } | 443 | } |
434 | 444 | ||
435 | /* | 445 | /* |
diff --git a/monitor_wrap.h b/monitor_wrap.h index f5af1e819..762332704 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.h,v 1.36 2017/12/18 02:25:15 djm Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.h,v 1.37 2018/03/03 03:15:51 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
@@ -35,6 +35,8 @@ enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY }; | |||
35 | 35 | ||
36 | struct monitor; | 36 | struct monitor; |
37 | struct Authctxt; | 37 | struct Authctxt; |
38 | struct sshkey; | ||
39 | struct sshauthopt; | ||
38 | 40 | ||
39 | void mm_log_handler(LogLevel, const char *, void *); | 41 | void mm_log_handler(LogLevel, const char *, void *); |
40 | int mm_is_monitor(void); | 42 | int mm_is_monitor(void); |
@@ -44,10 +46,11 @@ int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, | |||
44 | void mm_inform_authserv(char *, char *); | 46 | void mm_inform_authserv(char *, char *); |
45 | struct passwd *mm_getpwnamallow(const char *); | 47 | struct passwd *mm_getpwnamallow(const char *); |
46 | char *mm_auth2_read_banner(void); | 48 | char *mm_auth2_read_banner(void); |
47 | int mm_auth_password(struct Authctxt *, char *); | 49 | int mm_auth_password(struct ssh *, char *); |
48 | int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *, | 50 | int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *, |
49 | int); | 51 | int, struct sshauthopt **); |
50 | int mm_user_key_allowed(struct passwd *, struct sshkey *, int); | 52 | int mm_user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int, |
53 | struct sshauthopt **); | ||
51 | int mm_hostbased_key_allowed(struct passwd *, const char *, | 54 | int mm_hostbased_key_allowed(struct passwd *, const char *, |
52 | const char *, struct sshkey *); | 55 | const char *, struct sshkey *); |
53 | int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, | 56 | int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, |
diff --git a/serverloop.c b/serverloop.c index 7e2abd52f..d6fe24cc1 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.204 2018/02/11 21:16:56 dtucker Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.205 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -82,6 +82,7 @@ extern ServerOptions options; | |||
82 | 82 | ||
83 | /* XXX */ | 83 | /* XXX */ |
84 | extern Authctxt *the_authctxt; | 84 | extern Authctxt *the_authctxt; |
85 | extern struct sshauthopt *auth_opts; | ||
85 | extern int use_privsep; | 86 | extern int use_privsep; |
86 | 87 | ||
87 | static int no_more_sessions = 0; /* Disallow further sessions. */ | 88 | static int no_more_sessions = 0; /* Disallow further sessions. */ |
@@ -456,12 +457,13 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg) | |||
456 | originator_port = packet_get_int(); | 457 | originator_port = packet_get_int(); |
457 | packet_check_eom(); | 458 | packet_check_eom(); |
458 | 459 | ||
459 | debug("server_request_direct_tcpip: originator %s port %d, target %s " | 460 | debug("%s: originator %s port %d, target %s port %d", __func__, |
460 | "port %d", originator, originator_port, target, target_port); | 461 | originator, originator_port, target, target_port); |
461 | 462 | ||
462 | /* XXX fine grained permissions */ | 463 | /* XXX fine grained permissions */ |
463 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && | 464 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && |
464 | !no_port_forwarding_flag && !options.disable_forwarding) { | 465 | auth_opts->permit_port_forwarding_flag && |
466 | !options.disable_forwarding) { | ||
465 | c = channel_connect_to_port(ssh, target, target_port, | 467 | c = channel_connect_to_port(ssh, target, target_port, |
466 | "direct-tcpip", "direct-tcpip", reason, errmsg); | 468 | "direct-tcpip", "direct-tcpip", reason, errmsg); |
467 | } else { | 469 | } else { |
@@ -487,20 +489,20 @@ server_request_direct_streamlocal(struct ssh *ssh) | |||
487 | struct passwd *pw = the_authctxt->pw; | 489 | struct passwd *pw = the_authctxt->pw; |
488 | 490 | ||
489 | if (pw == NULL || !the_authctxt->valid) | 491 | if (pw == NULL || !the_authctxt->valid) |
490 | fatal("server_input_global_request: no/invalid user"); | 492 | fatal("%s: no/invalid user", __func__); |
491 | 493 | ||
492 | target = packet_get_string(NULL); | 494 | target = packet_get_string(NULL); |
493 | originator = packet_get_string(NULL); | 495 | originator = packet_get_string(NULL); |
494 | originator_port = packet_get_int(); | 496 | originator_port = packet_get_int(); |
495 | packet_check_eom(); | 497 | packet_check_eom(); |
496 | 498 | ||
497 | debug("server_request_direct_streamlocal: originator %s port %d, target %s", | 499 | debug("%s: originator %s port %d, target %s", __func__, |
498 | originator, originator_port, target); | 500 | originator, originator_port, target); |
499 | 501 | ||
500 | /* XXX fine grained permissions */ | 502 | /* XXX fine grained permissions */ |
501 | if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && | 503 | if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && |
502 | !no_port_forwarding_flag && !options.disable_forwarding && | 504 | auth_opts->permit_port_forwarding_flag && |
503 | (pw->pw_uid == 0 || use_privsep)) { | 505 | !options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) { |
504 | c = channel_connect_to_path(ssh, target, | 506 | c = channel_connect_to_path(ssh, target, |
505 | "direct-streamlocal@openssh.com", "direct-streamlocal"); | 507 | "direct-streamlocal@openssh.com", "direct-streamlocal"); |
506 | } else { | 508 | } else { |
@@ -519,8 +521,7 @@ static Channel * | |||
519 | server_request_tun(struct ssh *ssh) | 521 | server_request_tun(struct ssh *ssh) |
520 | { | 522 | { |
521 | Channel *c = NULL; | 523 | Channel *c = NULL; |
522 | int mode, tun; | 524 | int mode, tun, sock; |
523 | int sock; | ||
524 | char *tmp, *ifname = NULL; | 525 | char *tmp, *ifname = NULL; |
525 | 526 | ||
526 | mode = packet_get_int(); | 527 | mode = packet_get_int(); |
@@ -539,10 +540,10 @@ server_request_tun(struct ssh *ssh) | |||
539 | } | 540 | } |
540 | 541 | ||
541 | tun = packet_get_int(); | 542 | tun = packet_get_int(); |
542 | if (forced_tun_device != -1) { | 543 | if (auth_opts->force_tun_device != -1) { |
543 | if (tun != SSH_TUNID_ANY && forced_tun_device != tun) | 544 | if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) |
544 | goto done; | 545 | goto done; |
545 | tun = forced_tun_device; | 546 | tun = auth_opts->force_tun_device; |
546 | } | 547 | } |
547 | sock = tun_open(tun, mode, &ifname); | 548 | sock = tun_open(tun, mode, &ifname); |
548 | if (sock < 0) | 549 | if (sock < 0) |
@@ -767,7 +768,8 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) | |||
767 | 768 | ||
768 | /* check permissions */ | 769 | /* check permissions */ |
769 | if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || | 770 | if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || |
770 | no_port_forwarding_flag || options.disable_forwarding || | 771 | !auth_opts->permit_port_forwarding_flag || |
772 | options.disable_forwarding || | ||
771 | (!want_reply && fwd.listen_port == 0) || | 773 | (!want_reply && fwd.listen_port == 0) || |
772 | (fwd.listen_port != 0 && | 774 | (fwd.listen_port != 0 && |
773 | !bind_permitted(fwd.listen_port, pw->pw_uid))) { | 775 | !bind_permitted(fwd.listen_port, pw->pw_uid))) { |
@@ -805,7 +807,8 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) | |||
805 | 807 | ||
806 | /* check permissions */ | 808 | /* check permissions */ |
807 | if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 | 809 | if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 |
808 | || no_port_forwarding_flag || options.disable_forwarding || | 810 | || !auth_opts->permit_port_forwarding_flag || |
811 | options.disable_forwarding || | ||
809 | (pw->pw_uid != 0 && !use_privsep)) { | 812 | (pw->pw_uid != 0 && !use_privsep)) { |
810 | success = 0; | 813 | success = 0; |
811 | packet_send_debug("Server has disabled " | 814 | packet_send_debug("Server has disabled " |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.293 2017/10/23 05:08:00 djm Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.294 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -140,6 +140,7 @@ extern u_int utmp_len; | |||
140 | extern int startup_pipe; | 140 | extern int startup_pipe; |
141 | extern void destroy_sensitive_data(void); | 141 | extern void destroy_sensitive_data(void); |
142 | extern Buffer loginmsg; | 142 | extern Buffer loginmsg; |
143 | extern struct sshauthopt *auth_opts; | ||
143 | char *tun_fwd_ifnames; /* serverloop.c */ | 144 | char *tun_fwd_ifnames; /* serverloop.c */ |
144 | 145 | ||
145 | /* original command from peer. */ | 146 | /* original command from peer. */ |
@@ -288,14 +289,42 @@ prepare_auth_info_file(struct passwd *pw, struct sshbuf *info) | |||
288 | restore_uid(); | 289 | restore_uid(); |
289 | } | 290 | } |
290 | 291 | ||
292 | static void | ||
293 | set_permitopen_from_authopts(struct ssh *ssh, const struct sshauthopt *opts) | ||
294 | { | ||
295 | char *tmp, *cp, *host; | ||
296 | int port; | ||
297 | size_t i; | ||
298 | |||
299 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) | ||
300 | return; | ||
301 | channel_clear_permitted_opens(ssh); | ||
302 | for (i = 0; i < auth_opts->npermitopen; i++) { | ||
303 | tmp = cp = xstrdup(auth_opts->permitopen[i]); | ||
304 | /* This shouldn't fail as it has already been checked */ | ||
305 | if ((host = hpdelim(&cp)) == NULL) | ||
306 | fatal("%s: internal error: hpdelim", __func__); | ||
307 | host = cleanhostname(host); | ||
308 | if (cp == NULL || (port = permitopen_port(cp)) < 0) | ||
309 | fatal("%s: internal error: permitopen port", | ||
310 | __func__); | ||
311 | channel_add_permitted_opens(ssh, host, port); | ||
312 | free(tmp); | ||
313 | } | ||
314 | } | ||
315 | |||
291 | void | 316 | void |
292 | do_authenticated(struct ssh *ssh, Authctxt *authctxt) | 317 | do_authenticated(struct ssh *ssh, Authctxt *authctxt) |
293 | { | 318 | { |
294 | setproctitle("%s", authctxt->pw->pw_name); | 319 | setproctitle("%s", authctxt->pw->pw_name); |
295 | 320 | ||
321 | auth_log_authopts("active", auth_opts, 0); | ||
322 | |||
296 | /* setup the channel layer */ | 323 | /* setup the channel layer */ |
297 | /* XXX - streamlocal? */ | 324 | /* XXX - streamlocal? */ |
298 | if (no_port_forwarding_flag || options.disable_forwarding || | 325 | set_permitopen_from_authopts(ssh, auth_opts); |
326 | if (!auth_opts->permit_port_forwarding_flag || | ||
327 | options.disable_forwarding || | ||
299 | (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) | 328 | (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) |
300 | channel_disable_adm_local_opens(ssh); | 329 | channel_disable_adm_local_opens(ssh); |
301 | else | 330 | else |
@@ -642,9 +671,9 @@ do_exec(struct ssh *ssh, Session *s, const char *command) | |||
642 | original_command = command; | 671 | original_command = command; |
643 | command = options.adm_forced_command; | 672 | command = options.adm_forced_command; |
644 | forced = "(config)"; | 673 | forced = "(config)"; |
645 | } else if (forced_command) { | 674 | } else if (auth_opts->force_command != NULL) { |
646 | original_command = command; | 675 | original_command = command; |
647 | command = forced_command; | 676 | command = auth_opts->force_command; |
648 | forced = "(key-option)"; | 677 | forced = "(key-option)"; |
649 | } | 678 | } |
650 | if (forced != NULL) { | 679 | if (forced != NULL) { |
@@ -947,8 +976,9 @@ static char ** | |||
947 | do_setup_env(struct ssh *ssh, Session *s, const char *shell) | 976 | do_setup_env(struct ssh *ssh, Session *s, const char *shell) |
948 | { | 977 | { |
949 | char buf[256]; | 978 | char buf[256]; |
979 | size_t n; | ||
950 | u_int i, envsize; | 980 | u_int i, envsize; |
951 | char **env, *laddr; | 981 | char *ocp, *cp, **env, *laddr; |
952 | struct passwd *pw = s->pw; | 982 | struct passwd *pw = s->pw; |
953 | #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) | 983 | #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) |
954 | char *path = NULL; | 984 | char *path = NULL; |
@@ -1023,20 +1053,17 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1023 | if (getenv("TZ")) | 1053 | if (getenv("TZ")) |
1024 | child_set_env(&env, &envsize, "TZ", getenv("TZ")); | 1054 | child_set_env(&env, &envsize, "TZ", getenv("TZ")); |
1025 | 1055 | ||
1026 | /* Set custom environment options from RSA authentication. */ | 1056 | /* Set custom environment options from pubkey authentication. */ |
1027 | while (custom_environment) { | 1057 | if (options.permit_user_env) { |
1028 | struct envstring *ce = custom_environment; | 1058 | for (n = 0 ; n < auth_opts->nenv; n++) { |
1029 | char *str = ce->s; | 1059 | ocp = xstrdup(auth_opts->env[n]); |
1030 | 1060 | cp = strchr(ocp, '='); | |
1031 | for (i = 0; str[i] != '=' && str[i]; i++) | 1061 | if (*cp == '=') { |
1032 | ; | 1062 | *cp = '\0'; |
1033 | if (str[i] == '=') { | 1063 | child_set_env(&env, &envsize, ocp, cp + 1); |
1034 | str[i] = 0; | 1064 | } |
1035 | child_set_env(&env, &envsize, str, str + i + 1); | 1065 | free(ocp); |
1036 | } | 1066 | } |
1037 | custom_environment = ce->next; | ||
1038 | free(ce->s); | ||
1039 | free(ce); | ||
1040 | } | 1067 | } |
1041 | 1068 | ||
1042 | /* SSH_CLIENT deprecated */ | 1069 | /* SSH_CLIENT deprecated */ |
@@ -1138,7 +1165,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1138 | * first in this order). | 1165 | * first in this order). |
1139 | */ | 1166 | */ |
1140 | static void | 1167 | static void |
1141 | do_rc_files(Session *s, const char *shell) | 1168 | do_rc_files(struct ssh *ssh, Session *s, const char *shell) |
1142 | { | 1169 | { |
1143 | FILE *f = NULL; | 1170 | FILE *f = NULL; |
1144 | char cmd[1024]; | 1171 | char cmd[1024]; |
@@ -1150,7 +1177,7 @@ do_rc_files(Session *s, const char *shell) | |||
1150 | 1177 | ||
1151 | /* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */ | 1178 | /* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */ |
1152 | if (!s->is_subsystem && options.adm_forced_command == NULL && | 1179 | if (!s->is_subsystem && options.adm_forced_command == NULL && |
1153 | !no_user_rc && options.permit_user_rc && | 1180 | auth_opts->permit_user_rc && options.permit_user_rc && |
1154 | stat(_PATH_SSH_USER_RC, &st) >= 0) { | 1181 | stat(_PATH_SSH_USER_RC, &st) >= 0) { |
1155 | snprintf(cmd, sizeof cmd, "%s -c '%s %s'", | 1182 | snprintf(cmd, sizeof cmd, "%s -c '%s %s'", |
1156 | shell, _PATH_BSHELL, _PATH_SSH_USER_RC); | 1183 | shell, _PATH_BSHELL, _PATH_SSH_USER_RC); |
@@ -1570,7 +1597,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) | |||
1570 | 1597 | ||
1571 | closefrom(STDERR_FILENO + 1); | 1598 | closefrom(STDERR_FILENO + 1); |
1572 | 1599 | ||
1573 | do_rc_files(s, shell); | 1600 | do_rc_files(ssh, s, shell); |
1574 | 1601 | ||
1575 | /* restore SIGPIPE for child */ | 1602 | /* restore SIGPIPE for child */ |
1576 | signal(SIGPIPE, SIG_DFL); | 1603 | signal(SIGPIPE, SIG_DFL); |
@@ -1833,8 +1860,8 @@ session_pty_req(struct ssh *ssh, Session *s) | |||
1833 | u_int len; | 1860 | u_int len; |
1834 | int n_bytes; | 1861 | int n_bytes; |
1835 | 1862 | ||
1836 | if (no_pty_flag || !options.permit_tty) { | 1863 | if (!auth_opts->permit_pty_flag || !options.permit_tty) { |
1837 | debug("Allocating a pty not permitted for this authentication."); | 1864 | debug("Allocating a pty not permitted for this connection."); |
1838 | return 0; | 1865 | return 0; |
1839 | } | 1866 | } |
1840 | if (s->ttyfd != -1) { | 1867 | if (s->ttyfd != -1) { |
@@ -2022,9 +2049,11 @@ static int | |||
2022 | session_auth_agent_req(struct ssh *ssh, Session *s) | 2049 | session_auth_agent_req(struct ssh *ssh, Session *s) |
2023 | { | 2050 | { |
2024 | static int called = 0; | 2051 | static int called = 0; |
2052 | |||
2025 | packet_check_eom(); | 2053 | packet_check_eom(); |
2026 | if (no_agent_forwarding_flag || !options.allow_agent_forwarding) { | 2054 | if (!auth_opts->permit_agent_forwarding_flag || |
2027 | debug("session_auth_agent_req: no_agent_forwarding_flag"); | 2055 | !options.allow_agent_forwarding) { |
2056 | debug("%s: agent forwarding disabled", __func__); | ||
2028 | return 0; | 2057 | return 0; |
2029 | } | 2058 | } |
2030 | if (called) { | 2059 | if (called) { |
@@ -2402,8 +2431,8 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) | |||
2402 | char hostname[NI_MAXHOST]; | 2431 | char hostname[NI_MAXHOST]; |
2403 | u_int i; | 2432 | u_int i; |
2404 | 2433 | ||
2405 | if (no_x11_forwarding_flag) { | 2434 | if (!auth_opts->permit_x11_forwarding_flag) { |
2406 | packet_send_debug("X11 forwarding disabled in user configuration file."); | 2435 | packet_send_debug("X11 forwarding disabled by key options."); |
2407 | return 0; | 2436 | return 0; |
2408 | } | 2437 | } |
2409 | if (!options.x11_forwarding) { | 2438 | if (!options.x11_forwarding) { |
@@ -2412,7 +2441,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) | |||
2412 | } | 2441 | } |
2413 | if (options.xauth_location == NULL || | 2442 | if (options.xauth_location == NULL || |
2414 | (stat(options.xauth_location, &st) == -1)) { | 2443 | (stat(options.xauth_location, &st) == -1)) { |
2415 | packet_send_debug("No xauth program; cannot forward with spoofing."); | 2444 | packet_send_debug("No xauth program; cannot forward X11."); |
2416 | return 0; | 2445 | return 0; |
2417 | } | 2446 | } |
2418 | if (s->display != NULL) { | 2447 | if (s->display != NULL) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.505 2018/02/23 15:58:38 markus Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.506 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -119,6 +119,7 @@ | |||
119 | #endif | 119 | #endif |
120 | #include "monitor_wrap.h" | 120 | #include "monitor_wrap.h" |
121 | #include "ssh-sandbox.h" | 121 | #include "ssh-sandbox.h" |
122 | #include "auth-options.h" | ||
122 | #include "version.h" | 123 | #include "version.h" |
123 | #include "ssherr.h" | 124 | #include "ssherr.h" |
124 | 125 | ||
@@ -232,6 +233,9 @@ static int privsep_chroot = 1; | |||
232 | /* global authentication context */ | 233 | /* global authentication context */ |
233 | Authctxt *the_authctxt = NULL; | 234 | Authctxt *the_authctxt = NULL; |
234 | 235 | ||
236 | /* global key/cert auth options. XXX move to permanent ssh->authctxt? */ | ||
237 | struct sshauthopt *auth_opts = NULL; | ||
238 | |||
235 | /* sshd_config buffer */ | 239 | /* sshd_config buffer */ |
236 | Buffer cfg; | 240 | Buffer cfg; |
237 | 241 | ||
@@ -2066,6 +2070,10 @@ main(int ac, char **av) | |||
2066 | /* XXX global for cleanup, access from other modules */ | 2070 | /* XXX global for cleanup, access from other modules */ |
2067 | the_authctxt = authctxt; | 2071 | the_authctxt = authctxt; |
2068 | 2072 | ||
2073 | /* Set default key authentication options */ | ||
2074 | if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL) | ||
2075 | fatal("allocation failed"); | ||
2076 | |||
2069 | /* prepare buffer to collect messages to display to user after login */ | 2077 | /* prepare buffer to collect messages to display to user after login */ |
2070 | buffer_init(&loginmsg); | 2078 | buffer_init(&loginmsg); |
2071 | auth_debug_reset(); | 2079 | auth_debug_reset(); |
@@ -2122,7 +2130,7 @@ main(int ac, char **av) | |||
2122 | #ifdef USE_PAM | 2130 | #ifdef USE_PAM |
2123 | if (options.use_pam) { | 2131 | if (options.use_pam) { |
2124 | do_pam_setcred(1); | 2132 | do_pam_setcred(1); |
2125 | do_pam_session(); | 2133 | do_pam_session(ssh); |
2126 | } | 2134 | } |
2127 | #endif | 2135 | #endif |
2128 | 2136 | ||