summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.depend7
-rw-r--r--auth-options.c650
-rw-r--r--auth-options.h46
-rw-r--r--auth-pam.c4
-rw-r--r--auth-pam.h4
-rw-r--r--auth-passwd.c30
-rw-r--r--auth.c180
-rw-r--r--auth.h28
-rw-r--r--auth2-none.c4
-rw-r--r--auth2-passwd.c4
-rw-r--r--auth2-pubkey.c532
-rw-r--r--auth2.c4
-rw-r--r--misc.c3
-rw-r--r--monitor.c70
-rw-r--r--monitor_wrap.c44
-rw-r--r--monitor_wrap.h11
-rw-r--r--serverloop.c33
-rw-r--r--session.c85
-rw-r--r--sshd.c12
19 files changed, 767 insertions, 984 deletions
diff --git a/.depend b/.depend
index 4c6b49d54..0893a87ab 100644
--- a/.depend
+++ b/.depend
@@ -7,8 +7,7 @@ audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-c
7audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 7audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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
8auth-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 8auth-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
9auth-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 9auth-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
10auth-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 10auth-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
11auth-options.o: audit.h loginrec.h
12auth-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 11auth-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
13auth-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 12auth-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
14auth-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 13auth-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
16auth-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 15auth-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
17auth-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 16auth-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
18auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 17auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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
19auth.o: dispatch.h opacket.h authfile.h monitor_wrap.h ssherr.h compat.h 18auth.o: dispatch.h opacket.h authfile.h monitor_wrap.h ssherr.h compat.h channels.h
20auth2-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 19auth2-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
21auth2-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 20auth2-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
22auth2-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 21auth2-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
161sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 160sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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
162sshconnect2.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 161sshconnect2.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
163sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 162sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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
164sshd.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 163sshd.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
165ssherr.o: ssherr.h 164ssherr.o: ssherr.h
166sshkey-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 165sshkey-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
167sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 166sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 */
61int no_port_forwarding_flag = 0;
62int no_agent_forwarding_flag = 0;
63int no_x11_forwarding_flag = 0;
64int no_pty_flag = 0;
65int no_user_rc = 0;
66int key_is_cert_authority = 0;
67
68/* "command=" option. */
69char *forced_command = NULL;
70
71/* "environment=" options. */
72struct envstring *custom_environment = NULL;
73
74/* "tunnel=" option. */
75int forced_tun_device = -1;
76
77/* "principals=" option. */
78char *authorized_principals = NULL;
79
80extern ServerOptions options;
81
82/* XXX refactor to be stateless */
83
84void
85auth_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 */
117static int
118match_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 */
144int
145auth_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 }
445next_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
463bad_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
475static int
476parse_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 */
627int
628auth_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 @@
18struct passwd; 22struct passwd;
19struct sshkey; 23struct sshkey;
20 24
21/* Linked list of custom environment strings */
22struct envstring {
23 struct envstring *next;
24 char *s;
25};
26
27/* Flags that may be set in authorized_keys options. */
28extern int no_port_forwarding_flag;
29extern int no_agent_forwarding_flag;
30extern int no_x11_forwarding_flag;
31extern int no_pty_flag;
32extern int no_user_rc;
33extern char *forced_command;
34extern struct envstring *custom_environment;
35extern int forced_tun_device;
36extern int key_is_cert_authority;
37extern char *authorized_principals;
38
39int auth_parse_options(struct passwd *, char *, const char *, u_long);
40void auth_clear_options(void);
41int 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
1079void 1079void
1080do_pam_session(void) 1080do_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
28struct ssh;
29
28void start_pam(Authctxt *); 30void start_pam(Authctxt *);
29void finish_pam(void); 31void finish_pam(void);
30u_int do_pam_account(void); 32u_int do_pam_account(void);
31void do_pam_session(void); 33void do_pam_session(struct ssh *);
32void do_pam_setcred(int ); 34void do_pam_setcred(int );
33void do_pam_chauthtok(void); 35void do_pam_chauthtok(void);
34int do_pam_putenv(char *, char *); 36int 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
71void
72disable_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 */
83int 75int
84auth_password(Authctxt *authctxt, const char *password) 76auth_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
172int 165int
173sys_auth_passwd(Authctxt *authctxt, const char *password) 166sys_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)
197int 190int
198sys_auth_passwd(Authctxt *authctxt, const char *password) 191sys_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
diff --git a/auth.c b/auth.c
index fd02eff07..041a09e3f 100644
--- a/auth.c
+++ b/auth.c
@@ -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 */
79extern ServerOptions options; 80extern ServerOptions options;
80extern int use_privsep; 81extern int use_privsep;
81extern Buffer loginmsg; 82extern Buffer loginmsg;
82extern struct passwd *privsep_pw; 83extern struct passwd *privsep_pw;
84extern struct sshauthopt *auth_opts;
83 85
84/* Debugging messages */ 86/* Debugging messages */
85Buffer auth_debug; 87Buffer 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 */
388int 390int
389auth_root_allowed(const char *method) 391auth_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 */
1000void
1001auth_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. */
1054int
1055auth_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 */
1069void
1070auth_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
1085int
1086auth_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}
diff --git a/auth.h b/auth.h
index 64f3c2eb5..23ce67caf 100644
--- a/auth.h
+++ b/auth.h
@@ -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
45struct passwd;
45struct ssh; 46struct ssh;
46struct sshkey;
47struct sshbuf; 47struct sshbuf;
48struct sshkey;
49struct sshauthopt;
48 50
49typedef struct Authctxt Authctxt; 51typedef struct Authctxt Authctxt;
50typedef struct Authmethod Authmethod; 52typedef struct Authmethod Authmethod;
@@ -128,11 +130,12 @@ struct KbdintDevice
128int 130int
129auth_rhosts2(struct passwd *, const char *, const char *, const char *); 131auth_rhosts2(struct passwd *, const char *, const char *, const char *);
130 132
131int auth_password(Authctxt *, const char *); 133int auth_password(struct ssh *, const char *);
132 134
133int hostbased_key_allowed(struct passwd *, const char *, char *, 135int hostbased_key_allowed(struct passwd *, const char *, char *,
134 struct sshkey *); 136 struct sshkey *);
135int user_key_allowed(struct passwd *, struct sshkey *, int); 137int user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int,
138 struct sshauthopt **);
136int auth2_key_already_used(Authctxt *, const struct sshkey *); 139int 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"
164void remove_kbdint_device(const char *); 167void remove_kbdint_device(const char *);
165 168
166void disable_forwarding(void);
167
168void do_authentication2(Authctxt *); 169void do_authentication2(Authctxt *);
169 170
170void auth_log(Authctxt *, int, int, const char *, const char *); 171void auth_log(Authctxt *, int, int, const char *, const char *);
171void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn)); 172void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn));
172void userauth_finish(struct ssh *, int, const char *, const char *); 173void userauth_finish(struct ssh *, int, const char *, const char *);
173int auth_root_allowed(const char *); 174int auth_root_allowed(struct ssh *, const char *);
174 175
175void userauth_send_banner(const char *); 176void userauth_send_banner(const char *);
176 177
@@ -214,8 +215,17 @@ int get_hostkey_index(struct sshkey *, int, struct ssh *);
214int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **, 215int 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 */
219const struct sshauthopt *auth_options(struct ssh *);
220int auth_activate_options(struct ssh *, struct sshauthopt *);
221void auth_restrict_session(struct ssh *);
222int auth_authorise_keyopts(struct ssh *, struct passwd *pw,
223 struct sshauthopt *, int, const char *);
224void auth_log_authopts(const char *, const struct sshauthopt *, int);
225
217/* debug messages during authentication */ 226/* debug messages during authentication */
218void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); 227void auth_debug_add(const char *fmt,...)
228 __attribute__((format(printf, 1, 2)));
219void auth_debug_send(void); 229void auth_debug_send(void);
220void auth_debug_reset(void); 230void auth_debug_reset(void);
221 231
@@ -227,7 +237,7 @@ struct passwd *fakepw(void);
227pid_t subprocess(const char *, struct passwd *, 237pid_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
230int sys_auth_passwd(Authctxt *, const char *); 240int 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
88userauth_pubkey(struct ssh *ssh) 88userauth_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();
226done: 226done:
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 */
268static int
269check_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
257static int 318static int
258process_principals(FILE *f, const char *file, struct passwd *pw, 319process_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
308static int 352static int
309match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert) 353match_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 */
330static int 378static int
331match_principals_command(struct passwd *user_pw, const struct sshkey *key) 379match_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
507static void
508skip_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 */
522static int
523advance_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 */
544static int
545check_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 */
459static int 683static int
460check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw) 684check_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 */
572static int 712static int
573user_cert_trusted_ca(struct passwd *pw, struct sshkey *key) 713user_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 */
638static int 817static int
639user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file) 818user_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 */
661static int 845static int
662user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key) 846user_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 */
785int 973int
786user_key_allowed(struct passwd *pw, struct sshkey *key, int auth_attempt) 974user_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
diff --git a/auth2.c b/auth2.c
index c80911aeb..e0034229a 100644
--- a/auth2.c
+++ b/auth2.c
@@ -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));
diff --git a/misc.c b/misc.c
index b45a9ec63..1e660b021 100644
--- a/misc.c
+++ b/misc.c
@@ -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}
diff --git a/monitor.c b/monitor.c
index e4ac3ccfd..c68e1b0d9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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[];
116extern Buffer auth_debug; 116extern Buffer auth_debug;
117extern int auth_debug_init; 117extern int auth_debug_init;
118extern Buffer loginmsg; 118extern Buffer loginmsg;
119extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */
119 120
120/* State exported from the child */ 121/* State exported from the child */
121static struct sshbuf *child_state; 122static struct sshbuf *child_state;
@@ -172,6 +173,7 @@ static Authctxt *authctxt;
172static u_char *key_blob = NULL; 173static u_char *key_blob = NULL;
173static u_int key_bloblen = 0; 174static u_int key_bloblen = 0;
174static int key_blobtype = MM_NOKEY; 175static int key_blobtype = MM_NOKEY;
176static struct sshauthopt *key_opts = NULL;
175static char *hostbased_cuser = NULL; 177static char *hostbased_cuser = NULL;
176static char *hostbased_chost = NULL; 178static char *hostbased_chost = NULL;
177static char *auth_method = "unknown"; 179static char *auth_method = "unknown";
@@ -252,7 +254,6 @@ struct mon_table mon_dispatch_postauth20[] = {
252struct mon_table *mon_dispatch; 254struct 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
256static void 257static void
257monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) 258monitor_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)
828int 833int
829mm_answer_authpassword(int sock, Buffer *m) 834mm_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)
1129int 1135int
1130mm_answer_keyallowed(int sock, Buffer *m) 1136mm_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,
1336int 1353int
1337mm_answer_keyverify(int sock, struct sshbuf *m) 1354mm_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 */
353int 353int
354mm_auth_password(Authctxt *authctxt, char *password) 354mm_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
380int 380int
381mm_user_key_allowed(struct passwd *pw, struct sshkey *key, 381mm_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
388int 388int
389mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host, 389mm_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
395int 395int
396mm_key_allowed(enum mm_keytype type, const char *user, const char *host, 396mm_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
36struct monitor; 36struct monitor;
37struct Authctxt; 37struct Authctxt;
38struct sshkey;
39struct sshauthopt;
38 40
39void mm_log_handler(LogLevel, const char *, void *); 41void mm_log_handler(LogLevel, const char *, void *);
40int mm_is_monitor(void); 42int mm_is_monitor(void);
@@ -44,10 +46,11 @@ int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int,
44void mm_inform_authserv(char *, char *); 46void mm_inform_authserv(char *, char *);
45struct passwd *mm_getpwnamallow(const char *); 47struct passwd *mm_getpwnamallow(const char *);
46char *mm_auth2_read_banner(void); 48char *mm_auth2_read_banner(void);
47int mm_auth_password(struct Authctxt *, char *); 49int mm_auth_password(struct ssh *, char *);
48int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *, 50int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *,
49 int); 51 int, struct sshauthopt **);
50int mm_user_key_allowed(struct passwd *, struct sshkey *, int); 52int mm_user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int,
53 struct sshauthopt **);
51int mm_hostbased_key_allowed(struct passwd *, const char *, 54int mm_hostbased_key_allowed(struct passwd *, const char *,
52 const char *, struct sshkey *); 55 const char *, struct sshkey *);
53int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, 56int 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 */
84extern Authctxt *the_authctxt; 84extern Authctxt *the_authctxt;
85extern struct sshauthopt *auth_opts;
85extern int use_privsep; 86extern int use_privsep;
86 87
87static int no_more_sessions = 0; /* Disallow further sessions. */ 88static 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 *
519server_request_tun(struct ssh *ssh) 521server_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 "
diff --git a/session.c b/session.c
index 51c5ea0ec..58826db16 100644
--- a/session.c
+++ b/session.c
@@ -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;
140extern int startup_pipe; 140extern int startup_pipe;
141extern void destroy_sensitive_data(void); 141extern void destroy_sensitive_data(void);
142extern Buffer loginmsg; 142extern Buffer loginmsg;
143extern struct sshauthopt *auth_opts;
143char *tun_fwd_ifnames; /* serverloop.c */ 144char *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
292static void
293set_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
291void 316void
292do_authenticated(struct ssh *ssh, Authctxt *authctxt) 317do_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 **
947do_setup_env(struct ssh *ssh, Session *s, const char *shell) 976do_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 */
1140static void 1167static void
1141do_rc_files(Session *s, const char *shell) 1168do_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
2022session_auth_agent_req(struct ssh *ssh, Session *s) 2049session_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) {
diff --git a/sshd.c b/sshd.c
index 0b9a7ec46..fd95b681b 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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 */
233Authctxt *the_authctxt = NULL; 234Authctxt *the_authctxt = NULL;
234 235
236/* global key/cert auth options. XXX move to permanent ssh->authctxt? */
237struct sshauthopt *auth_opts = NULL;
238
235/* sshd_config buffer */ 239/* sshd_config buffer */
236Buffer cfg; 240Buffer 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