diff options
-rw-r--r-- | .depend | 6 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | atomicio.h | 4 | ||||
-rw-r--r-- | kex.c | 294 | ||||
-rw-r--r-- | kex.h | 20 | ||||
-rw-r--r-- | kexc25519.c | 10 | ||||
-rw-r--r-- | kexc25519c.c | 6 | ||||
-rw-r--r-- | kexc25519s.c | 6 | ||||
-rw-r--r-- | kexdh.c | 10 | ||||
-rw-r--r-- | kexdhc.c | 6 | ||||
-rw-r--r-- | kexdhs.c | 6 | ||||
-rw-r--r-- | kexecdh.c | 10 | ||||
-rw-r--r-- | kexecdhc.c | 6 | ||||
-rw-r--r-- | kexecdhs.c | 6 | ||||
-rw-r--r-- | kexgex.c | 10 | ||||
-rw-r--r-- | kexgexc.c | 6 | ||||
-rw-r--r-- | kexgexs.c | 6 | ||||
-rw-r--r-- | misc.c | 77 | ||||
-rw-r--r-- | misc.h | 5 | ||||
-rw-r--r-- | packet.c | 42 | ||||
-rw-r--r-- | ssh.c | 4 | ||||
-rw-r--r-- | ssh.h | 6 | ||||
-rw-r--r-- | ssh_api.c | 125 | ||||
-rw-r--r-- | sshconnect.c | 187 | ||||
-rw-r--r-- | sshconnect.h | 15 | ||||
-rw-r--r-- | sshconnect2.c | 49 | ||||
-rw-r--r-- | sshd.c | 118 |
27 files changed, 548 insertions, 494 deletions
@@ -60,8 +60,8 @@ gss-serv.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-comp | |||
60 | hash.o: crypto_api.h includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 digest.h log.h ssherr.h | 60 | hash.o: crypto_api.h includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 digest.h log.h ssherr.h |
61 | hmac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 sshbuf.h digest.h hmac.h | 61 | hmac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 sshbuf.h digest.h hmac.h |
62 | hostfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 xmalloc.h match.h sshkey.h hostfile.h log.h misc.h ssherr.h digest.h hmac.h | 62 | hostfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 xmalloc.h match.h sshkey.h hostfile.h log.h misc.h ssherr.h digest.h hmac.h |
63 | kex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h log.h match.h misc.h monitor.h ssherr.h sshbuf.h | 63 | kex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 ssh.h ssh2.h atomicio.h version.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h log.h match.h misc.h |
64 | kex.o: digest.h | 64 | kex.o: monitor.h ssherr.h sshbuf.h digest.h |
65 | kexc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 sshbuf.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h log.h digest.h ssherr.h | 65 | kexc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 sshbuf.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h log.h digest.h ssherr.h |
66 | kexc25519c.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h log.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssh2.h sshbuf.h digest.h ssherr.h | 66 | kexc25519c.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h log.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssh2.h sshbuf.h digest.h ssherr.h |
67 | kexc25519s.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h kex.h mac.h log.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssh2.h sshbuf.h ssherr.h | 67 | kexc25519s.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/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 sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h kex.h mac.h log.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h ssh2.h sshbuf.h ssherr.h |
@@ -149,7 +149,7 @@ sshbuf-getput-crypto.o: includes.h config.h defines.h platform.h openbsd-compat/ | |||
149 | sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 ssherr.h sshbuf.h | 149 | sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 ssherr.h sshbuf.h |
150 | sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 ssherr.h sshbuf.h misc.h | 150 | sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 ssherr.h sshbuf.h misc.h |
151 | sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h compat.h sshkey.h sshconnect.h log.h misc.h readconf.h atomicio.h dns.h monitor_fdpass.h ssh2.h version.h authfile.h | 151 | sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/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 xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h opacket.h compat.h sshkey.h sshconnect.h log.h misc.h readconf.h atomicio.h dns.h monitor_fdpass.h ssh2.h version.h authfile.h |
152 | sshconnect.o: ssherr.h authfd.h | 152 | sshconnect.o: ssherr.h authfd.h kex.h mac.h |
153 | sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h myproposal.h | 153 | sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h opacket.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h myproposal.h |
154 | sshconnect2.o: 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 | 154 | sshconnect2.o: 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 |
155 | sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./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 sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h | 155 | sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/rmd160.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/getopt.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./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 sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h |
diff --git a/Makefile.in b/Makefile.in index 126b2c742..6ffccb482 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -186,7 +186,7 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o | |||
186 | ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o | 186 | ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o |
187 | $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) | 187 | $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
188 | 188 | ||
189 | ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o | 189 | ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o compat.o |
190 | $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) | 190 | $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
191 | 191 | ||
192 | ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o | 192 | ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o |
diff --git a/atomicio.h b/atomicio.h index 0d728ac86..8b3cc6e21 100644 --- a/atomicio.h +++ b/atomicio.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: atomicio.h,v 1.11 2010/09/22 22:58:51 djm Exp $ */ | 1 | /* $OpenBSD: atomicio.h,v 1.12 2018/12/27 03:25:25 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2006 Damien Miller. All rights reserved. |
@@ -29,6 +29,8 @@ | |||
29 | #ifndef _ATOMICIO_H | 29 | #ifndef _ATOMICIO_H |
30 | #define _ATOMICIO_H | 30 | #define _ATOMICIO_H |
31 | 31 | ||
32 | struct iovec; | ||
33 | |||
32 | /* | 34 | /* |
33 | * Ensure all of data on socket comes through. f==read || f==vwrite | 35 | * Ensure all of data on socket comes through. f==read || f==vwrite |
34 | */ | 36 | */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.c,v 1.142 2018/12/07 03:39:40 djm Exp $ */ | 1 | /* $OpenBSD: kex.c,v 1.143 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -25,19 +25,25 @@ | |||
25 | 25 | ||
26 | #include "includes.h" | 26 | #include "includes.h" |
27 | 27 | ||
28 | 28 | #include <sys/types.h> | |
29 | #include <errno.h> | ||
29 | #include <signal.h> | 30 | #include <signal.h> |
30 | #include <stdarg.h> | 31 | #include <stdarg.h> |
31 | #include <stdio.h> | 32 | #include <stdio.h> |
32 | #include <stdlib.h> | 33 | #include <stdlib.h> |
33 | #include <string.h> | 34 | #include <string.h> |
35 | #include <unistd.h> | ||
36 | #include <poll.h> | ||
34 | 37 | ||
35 | #ifdef WITH_OPENSSL | 38 | #ifdef WITH_OPENSSL |
36 | #include <openssl/crypto.h> | 39 | #include <openssl/crypto.h> |
37 | #include <openssl/dh.h> | 40 | #include <openssl/dh.h> |
38 | #endif | 41 | #endif |
39 | 42 | ||
43 | #include "ssh.h" | ||
40 | #include "ssh2.h" | 44 | #include "ssh2.h" |
45 | #include "atomicio.h" | ||
46 | #include "version.h" | ||
41 | #include "packet.h" | 47 | #include "packet.h" |
42 | #include "compat.h" | 48 | #include "compat.h" |
43 | #include "cipher.h" | 49 | #include "cipher.h" |
@@ -578,32 +584,20 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) | |||
578 | return SSH_ERR_INTERNAL_ERROR; | 584 | return SSH_ERR_INTERNAL_ERROR; |
579 | } | 585 | } |
580 | 586 | ||
581 | int | 587 | struct kex * |
582 | kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp) | 588 | kex_new(void) |
583 | { | 589 | { |
584 | struct kex *kex; | 590 | struct kex *kex; |
585 | int r; | ||
586 | 591 | ||
587 | *kexp = NULL; | 592 | if ((kex = calloc(1, sizeof(*kex))) == NULL || |
588 | if ((kex = calloc(1, sizeof(*kex))) == NULL) | 593 | (kex->peer = sshbuf_new()) == NULL || |
589 | return SSH_ERR_ALLOC_FAIL; | 594 | (kex->my = sshbuf_new()) == NULL || |
590 | if ((kex->peer = sshbuf_new()) == NULL || | 595 | (kex->client_version = sshbuf_new()) == NULL || |
591 | (kex->my = sshbuf_new()) == NULL) { | 596 | (kex->server_version = sshbuf_new()) == NULL) { |
592 | r = SSH_ERR_ALLOC_FAIL; | ||
593 | goto out; | ||
594 | } | ||
595 | if ((r = kex_prop2buf(kex->my, proposal)) != 0) | ||
596 | goto out; | ||
597 | kex->done = 0; | ||
598 | kex->flags = KEX_INITIAL; | ||
599 | kex_reset_dispatch(ssh); | ||
600 | ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); | ||
601 | r = 0; | ||
602 | *kexp = kex; | ||
603 | out: | ||
604 | if (r != 0) | ||
605 | kex_free(kex); | 597 | kex_free(kex); |
606 | return r; | 598 | return NULL; |
599 | } | ||
600 | return kex; | ||
607 | } | 601 | } |
608 | 602 | ||
609 | void | 603 | void |
@@ -642,6 +636,9 @@ kex_free(struct kex *kex) | |||
642 | { | 636 | { |
643 | u_int mode; | 637 | u_int mode; |
644 | 638 | ||
639 | if (kex == NULL) | ||
640 | return; | ||
641 | |||
645 | #ifdef WITH_OPENSSL | 642 | #ifdef WITH_OPENSSL |
646 | DH_free(kex->dh); | 643 | DH_free(kex->dh); |
647 | #ifdef OPENSSL_HAS_ECC | 644 | #ifdef OPENSSL_HAS_ECC |
@@ -654,9 +651,9 @@ kex_free(struct kex *kex) | |||
654 | } | 651 | } |
655 | sshbuf_free(kex->peer); | 652 | sshbuf_free(kex->peer); |
656 | sshbuf_free(kex->my); | 653 | sshbuf_free(kex->my); |
654 | sshbuf_free(kex->client_version); | ||
655 | sshbuf_free(kex->server_version); | ||
657 | free(kex->session_id); | 656 | free(kex->session_id); |
658 | free(kex->client_version_string); | ||
659 | free(kex->server_version_string); | ||
660 | free(kex->failed_choice); | 657 | free(kex->failed_choice); |
661 | free(kex->hostkey_alg); | 658 | free(kex->hostkey_alg); |
662 | free(kex->name); | 659 | free(kex->name); |
@@ -664,11 +661,24 @@ kex_free(struct kex *kex) | |||
664 | } | 661 | } |
665 | 662 | ||
666 | int | 663 | int |
664 | kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) | ||
665 | { | ||
666 | int r; | ||
667 | |||
668 | if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0) | ||
669 | return r; | ||
670 | ssh->kex->flags = KEX_INITIAL; | ||
671 | kex_reset_dispatch(ssh); | ||
672 | ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | int | ||
667 | kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) | 677 | kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) |
668 | { | 678 | { |
669 | int r; | 679 | int r; |
670 | 680 | ||
671 | if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) | 681 | if ((r = kex_ready(ssh, proposal)) != 0) |
672 | return r; | 682 | return r; |
673 | if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */ | 683 | if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */ |
674 | kex_free(ssh->kex); | 684 | kex_free(ssh->kex); |
@@ -1043,3 +1053,233 @@ dump_digest(char *msg, u_char *digest, int len) | |||
1043 | sshbuf_dump_data(digest, len, stderr); | 1053 | sshbuf_dump_data(digest, len, stderr); |
1044 | } | 1054 | } |
1045 | #endif | 1055 | #endif |
1056 | |||
1057 | /* | ||
1058 | * Send a plaintext error message to the peer, suffixed by \r\n. | ||
1059 | * Only used during banner exchange, and there only for the server. | ||
1060 | */ | ||
1061 | static void | ||
1062 | send_error(struct ssh *ssh, char *msg) | ||
1063 | { | ||
1064 | char *crnl = "\r\n"; | ||
1065 | |||
1066 | if (!ssh->kex->server) | ||
1067 | return; | ||
1068 | |||
1069 | if (atomicio(vwrite, ssh_packet_get_connection_out(ssh), | ||
1070 | msg, strlen(msg)) != strlen(msg) || | ||
1071 | atomicio(vwrite, ssh_packet_get_connection_out(ssh), | ||
1072 | crnl, strlen(crnl)) != strlen(crnl)) | ||
1073 | error("%s: write: %.100s", __func__, strerror(errno)); | ||
1074 | } | ||
1075 | |||
1076 | /* | ||
1077 | * Sends our identification string and waits for the peer's. Will block for | ||
1078 | * up to timeout_ms (or indefinitely if timeout_ms <= 0). | ||
1079 | * Returns on 0 success or a ssherr.h code on failure. | ||
1080 | */ | ||
1081 | int | ||
1082 | kex_exchange_identification(struct ssh *ssh, int timeout_ms, | ||
1083 | const char *version_addendum) | ||
1084 | { | ||
1085 | int remote_major, remote_minor, mismatch; | ||
1086 | size_t len, i, n; | ||
1087 | int r, expect_nl; | ||
1088 | u_char c; | ||
1089 | struct sshbuf *our_version = ssh->kex->server ? | ||
1090 | ssh->kex->server_version : ssh->kex->client_version; | ||
1091 | struct sshbuf *peer_version = ssh->kex->server ? | ||
1092 | ssh->kex->client_version : ssh->kex->server_version; | ||
1093 | char *our_version_string = NULL, *peer_version_string = NULL; | ||
1094 | char *cp, *remote_version = NULL; | ||
1095 | |||
1096 | /* Prepare and send our banner */ | ||
1097 | sshbuf_reset(our_version); | ||
1098 | if (version_addendum != NULL && *version_addendum == '\0') | ||
1099 | version_addendum = NULL; | ||
1100 | if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", | ||
1101 | PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, | ||
1102 | version_addendum == NULL ? "" : " ", | ||
1103 | version_addendum == NULL ? "" : version_addendum)) != 0) { | ||
1104 | error("%s: sshbuf_putf: %s", __func__, ssh_err(r)); | ||
1105 | goto out; | ||
1106 | } | ||
1107 | |||
1108 | if (atomicio(vwrite, ssh_packet_get_connection_out(ssh), | ||
1109 | sshbuf_mutable_ptr(our_version), | ||
1110 | sshbuf_len(our_version)) != sshbuf_len(our_version)) { | ||
1111 | error("%s: write: %.100s", __func__, strerror(errno)); | ||
1112 | r = SSH_ERR_SYSTEM_ERROR; | ||
1113 | goto out; | ||
1114 | } | ||
1115 | if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */ | ||
1116 | error("%s: sshbuf_consume_end: %s", __func__, ssh_err(r)); | ||
1117 | goto out; | ||
1118 | } | ||
1119 | our_version_string = sshbuf_dup_string(our_version); | ||
1120 | if (our_version_string == NULL) { | ||
1121 | error("%s: sshbuf_dup_string failed", __func__); | ||
1122 | r = SSH_ERR_ALLOC_FAIL; | ||
1123 | goto out; | ||
1124 | } | ||
1125 | debug("Local version string %.100s", our_version_string); | ||
1126 | |||
1127 | /* Read other side's version identification. */ | ||
1128 | for (n = 0; ; n++) { | ||
1129 | if (n >= SSH_MAX_PRE_BANNER_LINES) { | ||
1130 | send_error(ssh, "No SSH identification string " | ||
1131 | "received."); | ||
1132 | error("%s: No SSH version received in first %u lines " | ||
1133 | "from server", __func__, SSH_MAX_PRE_BANNER_LINES); | ||
1134 | r = SSH_ERR_INVALID_FORMAT; | ||
1135 | goto out; | ||
1136 | } | ||
1137 | sshbuf_reset(peer_version); | ||
1138 | expect_nl = 0; | ||
1139 | for (i = 0; ; i++) { | ||
1140 | if (timeout_ms > 0) { | ||
1141 | r = waitrfd(ssh_packet_get_connection_in(ssh), | ||
1142 | &timeout_ms); | ||
1143 | if (r == -1 && errno == ETIMEDOUT) { | ||
1144 | send_error(ssh, "Timed out waiting " | ||
1145 | "for SSH identification string."); | ||
1146 | error("Connection timed out during " | ||
1147 | "banner exchange"); | ||
1148 | r = SSH_ERR_CONN_TIMEOUT; | ||
1149 | goto out; | ||
1150 | } else if (r == -1) { | ||
1151 | error("%s: %s", | ||
1152 | __func__, strerror(errno)); | ||
1153 | r = SSH_ERR_SYSTEM_ERROR; | ||
1154 | goto out; | ||
1155 | } | ||
1156 | } | ||
1157 | |||
1158 | len = atomicio(read, ssh_packet_get_connection_in(ssh), | ||
1159 | &c, 1); | ||
1160 | if (len != 1 && errno == EPIPE) { | ||
1161 | error("%s: Connection closed by remote host", | ||
1162 | __func__); | ||
1163 | r = SSH_ERR_CONN_CLOSED; | ||
1164 | goto out; | ||
1165 | } else if (len != 1) { | ||
1166 | error("%s: read: %.100s", | ||
1167 | __func__, strerror(errno)); | ||
1168 | r = SSH_ERR_SYSTEM_ERROR; | ||
1169 | goto out; | ||
1170 | } | ||
1171 | if (c == '\r') { | ||
1172 | expect_nl = 1; | ||
1173 | continue; | ||
1174 | } | ||
1175 | if (c == '\n') | ||
1176 | break; | ||
1177 | if (c == '\0' || expect_nl) { | ||
1178 | error("%s: banner line contains invalid " | ||
1179 | "characters", __func__); | ||
1180 | goto invalid; | ||
1181 | } | ||
1182 | if ((r = sshbuf_put_u8(peer_version, c)) != 0) { | ||
1183 | error("%s: sshbuf_put: %s", | ||
1184 | __func__, ssh_err(r)); | ||
1185 | goto out; | ||
1186 | } | ||
1187 | if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) { | ||
1188 | error("%s: banner line too long", __func__); | ||
1189 | goto invalid; | ||
1190 | } | ||
1191 | } | ||
1192 | /* Is this an actual protocol banner? */ | ||
1193 | if (sshbuf_len(peer_version) > 4 && | ||
1194 | memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0) | ||
1195 | break; | ||
1196 | /* If not, then just log the line and continue */ | ||
1197 | if ((cp = sshbuf_dup_string(peer_version)) == NULL) { | ||
1198 | error("%s: sshbuf_dup_string failed", __func__); | ||
1199 | r = SSH_ERR_ALLOC_FAIL; | ||
1200 | goto out; | ||
1201 | } | ||
1202 | /* Do not accept lines before the SSH ident from a client */ | ||
1203 | if (ssh->kex->server) { | ||
1204 | error("%s: client sent invalid protocol identifier " | ||
1205 | "\"%.256s\"", __func__, cp); | ||
1206 | free(cp); | ||
1207 | goto invalid; | ||
1208 | } | ||
1209 | debug("%s: banner line %zu: %s", __func__, n, cp); | ||
1210 | free(cp); | ||
1211 | } | ||
1212 | peer_version_string = sshbuf_dup_string(peer_version); | ||
1213 | if (peer_version_string == NULL) | ||
1214 | error("%s: sshbuf_dup_string failed", __func__); | ||
1215 | /* XXX must be same size for sscanf */ | ||
1216 | if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) { | ||
1217 | error("%s: calloc failed", __func__); | ||
1218 | r = SSH_ERR_ALLOC_FAIL; | ||
1219 | goto out; | ||
1220 | } | ||
1221 | |||
1222 | /* | ||
1223 | * Check that the versions match. In future this might accept | ||
1224 | * several versions and set appropriate flags to handle them. | ||
1225 | */ | ||
1226 | if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n", | ||
1227 | &remote_major, &remote_minor, remote_version) != 3) { | ||
1228 | error("Bad remote protocol version identification: '%.100s'", | ||
1229 | peer_version_string); | ||
1230 | invalid: | ||
1231 | send_error(ssh, "Invalid SSH identification string."); | ||
1232 | r = SSH_ERR_INVALID_FORMAT; | ||
1233 | goto out; | ||
1234 | } | ||
1235 | debug("Remote protocol version %d.%d, remote software version %.100s", | ||
1236 | remote_major, remote_minor, remote_version); | ||
1237 | ssh->compat = compat_datafellows(remote_version); | ||
1238 | |||
1239 | mismatch = 0; | ||
1240 | switch (remote_major) { | ||
1241 | case 2: | ||
1242 | break; | ||
1243 | case 1: | ||
1244 | if (remote_minor != 99) | ||
1245 | mismatch = 1; | ||
1246 | break; | ||
1247 | default: | ||
1248 | mismatch = 1; | ||
1249 | break; | ||
1250 | } | ||
1251 | if (mismatch) { | ||
1252 | error("Protocol major versions differ: %d vs. %d", | ||
1253 | PROTOCOL_MAJOR_2, remote_major); | ||
1254 | send_error(ssh, "Protocol major versions differ."); | ||
1255 | r = SSH_ERR_NO_PROTOCOL_VERSION; | ||
1256 | goto out; | ||
1257 | } | ||
1258 | |||
1259 | if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) { | ||
1260 | logit("probed from %s port %d with %s. Don't panic.", | ||
1261 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
1262 | peer_version_string); | ||
1263 | r = SSH_ERR_CONN_CLOSED; /* XXX */ | ||
1264 | goto out; | ||
1265 | } | ||
1266 | if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) { | ||
1267 | logit("scanned from %s port %d with %s. Don't panic.", | ||
1268 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
1269 | peer_version_string); | ||
1270 | r = SSH_ERR_CONN_CLOSED; /* XXX */ | ||
1271 | goto out; | ||
1272 | } | ||
1273 | if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) { | ||
1274 | logit("Remote version \"%.100s\" uses unsafe RSA signature " | ||
1275 | "scheme; disabling use of RSA keys", remote_version); | ||
1276 | } | ||
1277 | /* success */ | ||
1278 | r = 0; | ||
1279 | out: | ||
1280 | free(our_version_string); | ||
1281 | free(peer_version_string); | ||
1282 | free(remote_version); | ||
1283 | return r; | ||
1284 | } | ||
1285 | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.92 2018/12/07 03:39:40 djm Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.93 2018/12/27 03:25:25 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -145,12 +145,12 @@ struct kex { | |||
145 | int ext_info_c; | 145 | int ext_info_c; |
146 | struct sshbuf *my; | 146 | struct sshbuf *my; |
147 | struct sshbuf *peer; | 147 | struct sshbuf *peer; |
148 | struct sshbuf *client_version; | ||
149 | struct sshbuf *server_version; | ||
148 | sig_atomic_t done; | 150 | sig_atomic_t done; |
149 | u_int flags; | 151 | u_int flags; |
150 | int hash_alg; | 152 | int hash_alg; |
151 | int ec_nid; | 153 | int ec_nid; |
152 | char *client_version_string; | ||
153 | char *server_version_string; | ||
154 | char *failed_choice; | 154 | char *failed_choice; |
155 | int (*verify_host_key)(struct sshkey *, struct ssh *); | 155 | int (*verify_host_key)(struct sshkey *, struct ssh *); |
156 | struct sshkey *(*load_host_public_key)(int, int, struct ssh *); | 156 | struct sshkey *(*load_host_public_key)(int, int, struct ssh *); |
@@ -173,7 +173,10 @@ char *kex_alg_list(char); | |||
173 | char *kex_names_cat(const char *, const char *); | 173 | char *kex_names_cat(const char *, const char *); |
174 | int kex_assemble_names(char **, const char *, const char *); | 174 | int kex_assemble_names(char **, const char *, const char *); |
175 | 175 | ||
176 | int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); | 176 | int kex_exchange_identification(struct ssh *, int, const char *); |
177 | |||
178 | struct kex *kex_new(void); | ||
179 | int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); | ||
177 | int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); | 180 | int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); |
178 | void kex_free_newkeys(struct newkeys *); | 181 | void kex_free_newkeys(struct newkeys *); |
179 | void kex_free(struct kex *); | 182 | void kex_free(struct kex *); |
@@ -199,22 +202,23 @@ int kexecdh_server(struct ssh *); | |||
199 | int kexc25519_client(struct ssh *); | 202 | int kexc25519_client(struct ssh *); |
200 | int kexc25519_server(struct ssh *); | 203 | int kexc25519_server(struct ssh *); |
201 | 204 | ||
202 | int kex_dh_hash(int, const char *, const char *, | 205 | int kex_dh_hash(int, const struct sshbuf *, const struct sshbuf *, |
203 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, | 206 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, |
204 | const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); | 207 | const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); |
205 | 208 | ||
206 | int kexgex_hash(int, const char *, const char *, | 209 | int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, |
207 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, | 210 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, |
208 | int, int, int, | 211 | int, int, int, |
209 | const BIGNUM *, const BIGNUM *, const BIGNUM *, | 212 | const BIGNUM *, const BIGNUM *, const BIGNUM *, |
210 | const BIGNUM *, const BIGNUM *, | 213 | const BIGNUM *, const BIGNUM *, |
211 | u_char *, size_t *); | 214 | u_char *, size_t *); |
212 | 215 | ||
213 | int kex_ecdh_hash(int, const EC_GROUP *, const char *, const char *, | 216 | int kex_ecdh_hash(int, const EC_GROUP *, |
217 | const struct sshbuf *, const struct sshbuf *, | ||
214 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, | 218 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, |
215 | const EC_POINT *, const EC_POINT *, const BIGNUM *, u_char *, size_t *); | 219 | const EC_POINT *, const EC_POINT *, const BIGNUM *, u_char *, size_t *); |
216 | 220 | ||
217 | int kex_c25519_hash(int, const char *, const char *, | 221 | int kex_c25519_hash(int, const struct sshbuf *, const struct sshbuf *, |
218 | const u_char *, size_t, const u_char *, size_t, | 222 | const u_char *, size_t, const u_char *, size_t, |
219 | const u_char *, size_t, const u_char *, const u_char *, | 223 | const u_char *, size_t, const u_char *, const u_char *, |
220 | const u_char *, size_t, u_char *, size_t *); | 224 | const u_char *, size_t, u_char *, size_t *); |
diff --git a/kexc25519.c b/kexc25519.c index 0897b8c51..712dd523d 100644 --- a/kexc25519.c +++ b/kexc25519.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexc25519.c,v 1.10 2016/05/02 08:49:03 djm Exp $ */ | 1 | /* $OpenBSD: kexc25519.c,v 1.11 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -84,8 +84,8 @@ kexc25519_shared_key(const u_char key[CURVE25519_SIZE], | |||
84 | int | 84 | int |
85 | kex_c25519_hash( | 85 | kex_c25519_hash( |
86 | int hash_alg, | 86 | int hash_alg, |
87 | const char *client_version_string, | 87 | const struct sshbuf *client_version, |
88 | const char *server_version_string, | 88 | const struct sshbuf *server_version, |
89 | const u_char *ckexinit, size_t ckexinitlen, | 89 | const u_char *ckexinit, size_t ckexinitlen, |
90 | const u_char *skexinit, size_t skexinitlen, | 90 | const u_char *skexinit, size_t skexinitlen, |
91 | const u_char *serverhostkeyblob, size_t sbloblen, | 91 | const u_char *serverhostkeyblob, size_t sbloblen, |
@@ -101,8 +101,8 @@ kex_c25519_hash( | |||
101 | return SSH_ERR_INVALID_ARGUMENT; | 101 | return SSH_ERR_INVALID_ARGUMENT; |
102 | if ((b = sshbuf_new()) == NULL) | 102 | if ((b = sshbuf_new()) == NULL) |
103 | return SSH_ERR_ALLOC_FAIL; | 103 | return SSH_ERR_ALLOC_FAIL; |
104 | if ((r = sshbuf_put_cstring(b, client_version_string)) < 0 || | 104 | if ((r = sshbuf_put_stringb(b, client_version)) < 0 || |
105 | (r = sshbuf_put_cstring(b, server_version_string)) < 0 || | 105 | (r = sshbuf_put_stringb(b, server_version)) < 0 || |
106 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ | 106 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ |
107 | (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 || | 107 | (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 || |
108 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || | 108 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || |
diff --git a/kexc25519c.c b/kexc25519c.c index a8d92149c..75e7d8c57 100644 --- a/kexc25519c.c +++ b/kexc25519c.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexc25519c.c,v 1.9 2017/12/18 02:25:15 djm Exp $ */ | 1 | /* $OpenBSD: kexc25519c.c,v 1.10 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -129,8 +129,8 @@ input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
129 | hashlen = sizeof(hash); | 129 | hashlen = sizeof(hash); |
130 | if ((r = kex_c25519_hash( | 130 | if ((r = kex_c25519_hash( |
131 | kex->hash_alg, | 131 | kex->hash_alg, |
132 | kex->client_version_string, | 132 | kex->client_version, |
133 | kex->server_version_string, | 133 | kex->server_version, |
134 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 134 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
135 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 135 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
136 | server_host_key_blob, sbloblen, | 136 | server_host_key_blob, sbloblen, |
diff --git a/kexc25519s.c b/kexc25519s.c index 0800a7a4b..81f816e56 100644 --- a/kexc25519s.c +++ b/kexc25519s.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexc25519s.c,v 1.11 2017/05/31 04:19:28 djm Exp $ */ | 1 | /* $OpenBSD: kexc25519s.c,v 1.12 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -110,8 +110,8 @@ input_kex_c25519_init(int type, u_int32_t seq, struct ssh *ssh) | |||
110 | hashlen = sizeof(hash); | 110 | hashlen = sizeof(hash); |
111 | if ((r = kex_c25519_hash( | 111 | if ((r = kex_c25519_hash( |
112 | kex->hash_alg, | 112 | kex->hash_alg, |
113 | kex->client_version_string, | 113 | kex->client_version, |
114 | kex->server_version_string, | 114 | kex->server_version, |
115 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 115 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
116 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 116 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
117 | server_host_key_blob, sbloblen, | 117 | server_host_key_blob, sbloblen, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdh.c,v 1.26 2016/05/02 10:26:04 djm Exp $ */ | 1 | /* $OpenBSD: kexdh.c,v 1.27 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -46,8 +46,8 @@ | |||
46 | int | 46 | int |
47 | kex_dh_hash( | 47 | kex_dh_hash( |
48 | int hash_alg, | 48 | int hash_alg, |
49 | const char *client_version_string, | 49 | const struct sshbuf *client_version, |
50 | const char *server_version_string, | 50 | const struct sshbuf *server_version, |
51 | const u_char *ckexinit, size_t ckexinitlen, | 51 | const u_char *ckexinit, size_t ckexinitlen, |
52 | const u_char *skexinit, size_t skexinitlen, | 52 | const u_char *skexinit, size_t skexinitlen, |
53 | const u_char *serverhostkeyblob, size_t sbloblen, | 53 | const u_char *serverhostkeyblob, size_t sbloblen, |
@@ -63,8 +63,8 @@ kex_dh_hash( | |||
63 | return SSH_ERR_INVALID_ARGUMENT; | 63 | return SSH_ERR_INVALID_ARGUMENT; |
64 | if ((b = sshbuf_new()) == NULL) | 64 | if ((b = sshbuf_new()) == NULL) |
65 | return SSH_ERR_ALLOC_FAIL; | 65 | return SSH_ERR_ALLOC_FAIL; |
66 | if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || | 66 | if ((r = sshbuf_put_stringb(b, client_version)) < 0 || |
67 | (r = sshbuf_put_cstring(b, server_version_string)) != 0 || | 67 | (r = sshbuf_put_stringb(b, server_version)) < 0 || |
68 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ | 68 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ |
69 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || | 69 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || |
70 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | 70 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdhc.c,v 1.22 2018/02/07 02:06:51 jsing Exp $ */ | 1 | /* $OpenBSD: kexdhc.c,v 1.24 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -178,8 +178,8 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) | |||
178 | hashlen = sizeof(hash); | 178 | hashlen = sizeof(hash); |
179 | if ((r = kex_dh_hash( | 179 | if ((r = kex_dh_hash( |
180 | kex->hash_alg, | 180 | kex->hash_alg, |
181 | kex->client_version_string, | 181 | kex->client_version, |
182 | kex->server_version_string, | 182 | kex->server_version, |
183 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 183 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
184 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 184 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
185 | server_host_key_blob, sbloblen, | 185 | server_host_key_blob, sbloblen, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdhs.c,v 1.27 2018/04/10 00:10:49 djm Exp $ */ | 1 | /* $OpenBSD: kexdhs.c,v 1.29 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -166,8 +166,8 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) | |||
166 | hashlen = sizeof(hash); | 166 | hashlen = sizeof(hash); |
167 | if ((r = kex_dh_hash( | 167 | if ((r = kex_dh_hash( |
168 | kex->hash_alg, | 168 | kex->hash_alg, |
169 | kex->client_version_string, | 169 | kex->client_version, |
170 | kex->server_version_string, | 170 | kex->server_version, |
171 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 171 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
172 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 172 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
173 | server_host_key_blob, sbloblen, | 173 | server_host_key_blob, sbloblen, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexecdh.c,v 1.6 2015/01/19 20:16:15 markus Exp $ */ | 1 | /* $OpenBSD: kexecdh.c,v 1.7 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -50,8 +50,8 @@ int | |||
50 | kex_ecdh_hash( | 50 | kex_ecdh_hash( |
51 | int hash_alg, | 51 | int hash_alg, |
52 | const EC_GROUP *ec_group, | 52 | const EC_GROUP *ec_group, |
53 | const char *client_version_string, | 53 | const struct sshbuf *client_version, |
54 | const char *server_version_string, | 54 | const struct sshbuf *server_version, |
55 | const u_char *ckexinit, size_t ckexinitlen, | 55 | const u_char *ckexinit, size_t ckexinitlen, |
56 | const u_char *skexinit, size_t skexinitlen, | 56 | const u_char *skexinit, size_t skexinitlen, |
57 | const u_char *serverhostkeyblob, size_t sbloblen, | 57 | const u_char *serverhostkeyblob, size_t sbloblen, |
@@ -67,8 +67,8 @@ kex_ecdh_hash( | |||
67 | return SSH_ERR_INVALID_ARGUMENT; | 67 | return SSH_ERR_INVALID_ARGUMENT; |
68 | if ((b = sshbuf_new()) == NULL) | 68 | if ((b = sshbuf_new()) == NULL) |
69 | return SSH_ERR_ALLOC_FAIL; | 69 | return SSH_ERR_ALLOC_FAIL; |
70 | if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || | 70 | if ((r = sshbuf_put_stringb(b, client_version)) < 0 || |
71 | (r = sshbuf_put_cstring(b, server_version_string)) != 0 || | 71 | (r = sshbuf_put_stringb(b, server_version)) < 0 || |
72 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ | 72 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ |
73 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || | 73 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || |
74 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | 74 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || |
diff --git a/kexecdhc.c b/kexecdhc.c index ac146a362..af556dc58 100644 --- a/kexecdhc.c +++ b/kexecdhc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexecdhc.c,v 1.13 2018/02/07 02:06:51 jsing Exp $ */ | 1 | /* $OpenBSD: kexecdhc.c,v 1.14 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -175,8 +175,8 @@ input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
175 | if ((r = kex_ecdh_hash( | 175 | if ((r = kex_ecdh_hash( |
176 | kex->hash_alg, | 176 | kex->hash_alg, |
177 | group, | 177 | group, |
178 | kex->client_version_string, | 178 | kex->client_version, |
179 | kex->server_version_string, | 179 | kex->server_version, |
180 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 180 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
181 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 181 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
182 | server_host_key_blob, sbloblen, | 182 | server_host_key_blob, sbloblen, |
diff --git a/kexecdhs.c b/kexecdhs.c index af4f30309..c690feffe 100644 --- a/kexecdhs.c +++ b/kexecdhs.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexecdhs.c,v 1.17 2018/02/07 02:06:51 jsing Exp $ */ | 1 | /* $OpenBSD: kexecdhs.c,v 1.18 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -145,8 +145,8 @@ input_kex_ecdh_init(int type, u_int32_t seq, struct ssh *ssh) | |||
145 | if ((r = kex_ecdh_hash( | 145 | if ((r = kex_ecdh_hash( |
146 | kex->hash_alg, | 146 | kex->hash_alg, |
147 | group, | 147 | group, |
148 | kex->client_version_string, | 148 | kex->client_version, |
149 | kex->server_version_string, | 149 | kex->server_version, |
150 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 150 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
151 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 151 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
152 | server_host_key_blob, sbloblen, | 152 | server_host_key_blob, sbloblen, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexgex.c,v 1.29 2015/01/19 20:16:15 markus Exp $ */ | 1 | /* $OpenBSD: kexgex.c,v 1.30 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -46,8 +46,8 @@ | |||
46 | int | 46 | int |
47 | kexgex_hash( | 47 | kexgex_hash( |
48 | int hash_alg, | 48 | int hash_alg, |
49 | const char *client_version_string, | 49 | const struct sshbuf *client_version, |
50 | const char *server_version_string, | 50 | const struct sshbuf *server_version, |
51 | const u_char *ckexinit, size_t ckexinitlen, | 51 | const u_char *ckexinit, size_t ckexinitlen, |
52 | const u_char *skexinit, size_t skexinitlen, | 52 | const u_char *skexinit, size_t skexinitlen, |
53 | const u_char *serverhostkeyblob, size_t sbloblen, | 53 | const u_char *serverhostkeyblob, size_t sbloblen, |
@@ -66,8 +66,8 @@ kexgex_hash( | |||
66 | return SSH_ERR_INVALID_ARGUMENT; | 66 | return SSH_ERR_INVALID_ARGUMENT; |
67 | if ((b = sshbuf_new()) == NULL) | 67 | if ((b = sshbuf_new()) == NULL) |
68 | return SSH_ERR_ALLOC_FAIL; | 68 | return SSH_ERR_ALLOC_FAIL; |
69 | if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || | 69 | if ((r = sshbuf_put_stringb(b, client_version)) < 0 || |
70 | (r = sshbuf_put_cstring(b, server_version_string)) != 0 || | 70 | (r = sshbuf_put_stringb(b, server_version)) < 0 || |
71 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ | 71 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ |
72 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || | 72 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || |
73 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | 73 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexgexc.c,v 1.27 2018/02/07 02:06:51 jsing Exp $ */ | 1 | /* $OpenBSD: kexgexc.c,v 1.29 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -222,8 +222,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
222 | hashlen = sizeof(hash); | 222 | hashlen = sizeof(hash); |
223 | if ((r = kexgex_hash( | 223 | if ((r = kexgex_hash( |
224 | kex->hash_alg, | 224 | kex->hash_alg, |
225 | kex->client_version_string, | 225 | kex->client_version, |
226 | kex->server_version_string, | 226 | kex->server_version, |
227 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 227 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
228 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 228 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
229 | server_host_key_blob, sbloblen, | 229 | server_host_key_blob, sbloblen, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexgexs.c,v 1.35 2018/10/04 00:04:41 djm Exp $ */ | 1 | /* $OpenBSD: kexgexs.c,v 1.36 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -198,8 +198,8 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) | |||
198 | hashlen = sizeof(hash); | 198 | hashlen = sizeof(hash); |
199 | if ((r = kexgex_hash( | 199 | if ((r = kexgex_hash( |
200 | kex->hash_alg, | 200 | kex->hash_alg, |
201 | kex->client_version_string, | 201 | kex->client_version, |
202 | kex->server_version_string, | 202 | kex->server_version, |
203 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 203 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
204 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 204 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
205 | server_host_key_blob, sbloblen, | 205 | server_host_key_blob, sbloblen, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.135 2018/12/07 04:36:09 dtucker Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.136 2018/12/27 03:25:25 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. |
@@ -38,6 +38,7 @@ | |||
38 | #ifdef HAVE_LIBGEN_H | 38 | #ifdef HAVE_LIBGEN_H |
39 | # include <libgen.h> | 39 | # include <libgen.h> |
40 | #endif | 40 | #endif |
41 | #include <poll.h> | ||
41 | #include <signal.h> | 42 | #include <signal.h> |
42 | #include <stdarg.h> | 43 | #include <stdarg.h> |
43 | #include <stdio.h> | 44 | #include <stdio.h> |
@@ -234,6 +235,80 @@ set_rdomain(int fd, const char *name) | |||
234 | #endif | 235 | #endif |
235 | } | 236 | } |
236 | 237 | ||
238 | /* | ||
239 | * Wait up to *timeoutp milliseconds for fd to be readable. Updates | ||
240 | * *timeoutp with time remaining. | ||
241 | * Returns 0 if fd ready or -1 on timeout or error (see errno). | ||
242 | */ | ||
243 | int | ||
244 | waitrfd(int fd, int *timeoutp) | ||
245 | { | ||
246 | struct pollfd pfd; | ||
247 | struct timeval t_start; | ||
248 | int oerrno, r; | ||
249 | |||
250 | monotime_tv(&t_start); | ||
251 | pfd.fd = fd; | ||
252 | pfd.events = POLLIN; | ||
253 | for (; *timeoutp >= 0;) { | ||
254 | r = poll(&pfd, 1, *timeoutp); | ||
255 | oerrno = errno; | ||
256 | ms_subtract_diff(&t_start, timeoutp); | ||
257 | errno = oerrno; | ||
258 | if (r > 0) | ||
259 | return 0; | ||
260 | else if (r == -1 && errno != EAGAIN) | ||
261 | return -1; | ||
262 | else if (r == 0) | ||
263 | break; | ||
264 | } | ||
265 | /* timeout */ | ||
266 | errno = ETIMEDOUT; | ||
267 | return -1; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Attempt a non-blocking connect(2) to the specified address, waiting up to | ||
272 | * *timeoutp milliseconds for the connection to complete. If the timeout is | ||
273 | * <=0, then wait indefinitely. | ||
274 | * | ||
275 | * Returns 0 on success or -1 on failure. | ||
276 | */ | ||
277 | int | ||
278 | timeout_connect(int sockfd, const struct sockaddr *serv_addr, | ||
279 | socklen_t addrlen, int *timeoutp) | ||
280 | { | ||
281 | int optval = 0; | ||
282 | socklen_t optlen = sizeof(optval); | ||
283 | |||
284 | /* No timeout: just do a blocking connect() */ | ||
285 | if (timeoutp == NULL || *timeoutp <= 0) | ||
286 | return connect(sockfd, serv_addr, addrlen); | ||
287 | |||
288 | set_nonblock(sockfd); | ||
289 | if (connect(sockfd, serv_addr, addrlen) == 0) { | ||
290 | /* Succeeded already? */ | ||
291 | unset_nonblock(sockfd); | ||
292 | return 0; | ||
293 | } else if (errno != EINPROGRESS) | ||
294 | return -1; | ||
295 | |||
296 | if (waitrfd(sockfd, timeoutp) == -1) | ||
297 | return -1; | ||
298 | |||
299 | /* Completed or failed */ | ||
300 | if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) { | ||
301 | debug("getsockopt: %s", strerror(errno)); | ||
302 | return -1; | ||
303 | } | ||
304 | if (optval != 0) { | ||
305 | errno = optval; | ||
306 | return -1; | ||
307 | } | ||
308 | unset_nonblock(sockfd); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
237 | /* Characters considered whitespace in strsep calls. */ | 312 | /* Characters considered whitespace in strsep calls. */ |
238 | #define WHITESPACE " \t\r\n" | 313 | #define WHITESPACE " \t\r\n" |
239 | #define QUOTE "\"" | 314 | #define QUOTE "\"" |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.h,v 1.77 2018/12/07 04:36:09 dtucker Exp $ */ | 1 | /* $OpenBSD: misc.h,v 1.78 2018/12/27 03:25:25 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <sys/time.h> | 18 | #include <sys/time.h> |
19 | #include <sys/types.h> | 19 | #include <sys/types.h> |
20 | #include <sys/socket.h> | ||
20 | 21 | ||
21 | /* Data structure for representing a forwarding request. */ | 22 | /* Data structure for representing a forwarding request. */ |
22 | struct Forward { | 23 | struct Forward { |
@@ -51,6 +52,8 @@ void set_nodelay(int); | |||
51 | int set_reuseaddr(int); | 52 | int set_reuseaddr(int); |
52 | char *get_rdomain(int); | 53 | char *get_rdomain(int); |
53 | int set_rdomain(int, const char *); | 54 | int set_rdomain(int, const char *); |
55 | int waitrfd(int, int *); | ||
56 | int timeout_connect(int, const struct sockaddr *, socklen_t, int *); | ||
54 | int a2port(const char *); | 57 | int a2port(const char *); |
55 | int a2tun(const char *, int *); | 58 | int a2tun(const char *, int *); |
56 | char *put_host_port(const char *, u_short); | 59 | char *put_host_port(const char *, u_short); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.277 2018/07/16 03:09:13 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.278 2018/12/27 03:25:25 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 |
@@ -58,6 +58,7 @@ | |||
58 | #include <string.h> | 58 | #include <string.h> |
59 | #include <unistd.h> | 59 | #include <unistd.h> |
60 | #include <limits.h> | 60 | #include <limits.h> |
61 | #include <poll.h> | ||
61 | #include <signal.h> | 62 | #include <signal.h> |
62 | #include <time.h> | 63 | #include <time.h> |
63 | 64 | ||
@@ -228,6 +229,7 @@ ssh_alloc_session_state(void) | |||
228 | 229 | ||
229 | if ((ssh = calloc(1, sizeof(*ssh))) == NULL || | 230 | if ((ssh = calloc(1, sizeof(*ssh))) == NULL || |
230 | (state = calloc(1, sizeof(*state))) == NULL || | 231 | (state = calloc(1, sizeof(*state))) == NULL || |
232 | (ssh->kex = kex_new()) == NULL || | ||
231 | (state->input = sshbuf_new()) == NULL || | 233 | (state->input = sshbuf_new()) == NULL || |
232 | (state->output = sshbuf_new()) == NULL || | 234 | (state->output = sshbuf_new()) == NULL || |
233 | (state->outgoing_packet = sshbuf_new()) == NULL || | 235 | (state->outgoing_packet = sshbuf_new()) == NULL || |
@@ -250,6 +252,10 @@ ssh_alloc_session_state(void) | |||
250 | ssh->state = state; | 252 | ssh->state = state; |
251 | return ssh; | 253 | return ssh; |
252 | fail: | 254 | fail: |
255 | if (ssh) { | ||
256 | kex_free(ssh->kex); | ||
257 | free(ssh); | ||
258 | } | ||
253 | if (state) { | 259 | if (state) { |
254 | sshbuf_free(state->input); | 260 | sshbuf_free(state->input); |
255 | sshbuf_free(state->output); | 261 | sshbuf_free(state->output); |
@@ -257,7 +263,6 @@ ssh_alloc_session_state(void) | |||
257 | sshbuf_free(state->outgoing_packet); | 263 | sshbuf_free(state->outgoing_packet); |
258 | free(state); | 264 | free(state); |
259 | } | 265 | } |
260 | free(ssh); | ||
261 | return NULL; | 266 | return NULL; |
262 | } | 267 | } |
263 | 268 | ||
@@ -272,8 +277,7 @@ ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx) | |||
272 | int | 277 | int |
273 | ssh_packet_is_rekeying(struct ssh *ssh) | 278 | ssh_packet_is_rekeying(struct ssh *ssh) |
274 | { | 279 | { |
275 | return ssh->state->rekeying || | 280 | return ssh->state->rekeying || ssh->kex->done == 0; |
276 | (ssh->kex != NULL && ssh->kex->done == 0); | ||
277 | } | 281 | } |
278 | 282 | ||
279 | /* | 283 | /* |
@@ -932,7 +936,7 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) | |||
932 | return 0; | 936 | return 0; |
933 | 937 | ||
934 | /* Haven't keyed yet or KEX in progress. */ | 938 | /* Haven't keyed yet or KEX in progress. */ |
935 | if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh)) | 939 | if (ssh_packet_is_rekeying(ssh)) |
936 | return 0; | 940 | return 0; |
937 | 941 | ||
938 | /* Peer can't rekey */ | 942 | /* Peer can't rekey */ |
@@ -2123,6 +2127,7 @@ void | |||
2123 | ssh_packet_set_server(struct ssh *ssh) | 2127 | ssh_packet_set_server(struct ssh *ssh) |
2124 | { | 2128 | { |
2125 | ssh->state->server_side = 1; | 2129 | ssh->state->server_side = 1; |
2130 | ssh->kex->server = 1; /* XXX unify? */ | ||
2126 | } | 2131 | } |
2127 | 2132 | ||
2128 | void | 2133 | void |
@@ -2175,9 +2180,9 @@ kex_to_blob(struct sshbuf *m, struct kex *kex) | |||
2175 | (r = sshbuf_put_u32(m, kex->kex_type)) != 0 || | 2180 | (r = sshbuf_put_u32(m, kex->kex_type)) != 0 || |
2176 | (r = sshbuf_put_stringb(m, kex->my)) != 0 || | 2181 | (r = sshbuf_put_stringb(m, kex->my)) != 0 || |
2177 | (r = sshbuf_put_stringb(m, kex->peer)) != 0 || | 2182 | (r = sshbuf_put_stringb(m, kex->peer)) != 0 || |
2178 | (r = sshbuf_put_u32(m, kex->flags)) != 0 || | 2183 | (r = sshbuf_put_stringb(m, kex->client_version)) != 0 || |
2179 | (r = sshbuf_put_cstring(m, kex->client_version_string)) != 0 || | 2184 | (r = sshbuf_put_stringb(m, kex->server_version)) != 0 || |
2180 | (r = sshbuf_put_cstring(m, kex->server_version_string)) != 0) | 2185 | (r = sshbuf_put_u32(m, kex->flags)) != 0) |
2181 | return r; | 2186 | return r; |
2182 | return 0; | 2187 | return 0; |
2183 | } | 2188 | } |
@@ -2327,12 +2332,8 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp) | |||
2327 | struct kex *kex; | 2332 | struct kex *kex; |
2328 | int r; | 2333 | int r; |
2329 | 2334 | ||
2330 | if ((kex = calloc(1, sizeof(struct kex))) == NULL || | 2335 | if ((kex = kex_new()) == NULL) |
2331 | (kex->my = sshbuf_new()) == NULL || | 2336 | return SSH_ERR_ALLOC_FAIL; |
2332 | (kex->peer = sshbuf_new()) == NULL) { | ||
2333 | r = SSH_ERR_ALLOC_FAIL; | ||
2334 | goto out; | ||
2335 | } | ||
2336 | if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 || | 2337 | if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 || |
2337 | (r = sshbuf_get_u32(m, &kex->we_need)) != 0 || | 2338 | (r = sshbuf_get_u32(m, &kex->we_need)) != 0 || |
2338 | (r = sshbuf_get_cstring(m, &kex->hostkey_alg, NULL)) != 0 || | 2339 | (r = sshbuf_get_cstring(m, &kex->hostkey_alg, NULL)) != 0 || |
@@ -2341,23 +2342,20 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp) | |||
2341 | (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 || | 2342 | (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 || |
2342 | (r = sshbuf_get_stringb(m, kex->my)) != 0 || | 2343 | (r = sshbuf_get_stringb(m, kex->my)) != 0 || |
2343 | (r = sshbuf_get_stringb(m, kex->peer)) != 0 || | 2344 | (r = sshbuf_get_stringb(m, kex->peer)) != 0 || |
2344 | (r = sshbuf_get_u32(m, &kex->flags)) != 0 || | 2345 | (r = sshbuf_get_stringb(m, kex->client_version)) != 0 || |
2345 | (r = sshbuf_get_cstring(m, &kex->client_version_string, NULL)) != 0 || | 2346 | (r = sshbuf_get_stringb(m, kex->server_version)) != 0 || |
2346 | (r = sshbuf_get_cstring(m, &kex->server_version_string, NULL)) != 0) | 2347 | (r = sshbuf_get_u32(m, &kex->flags)) != 0) |
2347 | goto out; | 2348 | goto out; |
2348 | kex->server = 1; | 2349 | kex->server = 1; |
2349 | kex->done = 1; | 2350 | kex->done = 1; |
2350 | r = 0; | 2351 | r = 0; |
2351 | out: | 2352 | out: |
2352 | if (r != 0 || kexp == NULL) { | 2353 | if (r != 0 || kexp == NULL) { |
2353 | if (kex != NULL) { | 2354 | kex_free(kex); |
2354 | sshbuf_free(kex->my); | ||
2355 | sshbuf_free(kex->peer); | ||
2356 | free(kex); | ||
2357 | } | ||
2358 | if (kexp != NULL) | 2355 | if (kexp != NULL) |
2359 | *kexp = NULL; | 2356 | *kexp = NULL; |
2360 | } else { | 2357 | } else { |
2358 | kex_free(*kexp); | ||
2361 | *kexp = kex; | 2359 | *kexp = kex; |
2362 | } | 2360 | } |
2363 | return r; | 2361 | return r; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.496 2018/11/23 05:08:07 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.497 2018/12/27 03:25:25 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 |
@@ -1490,7 +1490,7 @@ main(int ac, char **av) | |||
1490 | signal(SIGCHLD, main_sigchld_handler); | 1490 | signal(SIGCHLD, main_sigchld_handler); |
1491 | 1491 | ||
1492 | /* Log into the remote system. Never returns if the login fails. */ | 1492 | /* Log into the remote system. Never returns if the login fails. */ |
1493 | ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, | 1493 | ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr, |
1494 | options.port, pw, timeout_ms); | 1494 | options.port, pw, timeout_ms); |
1495 | 1495 | ||
1496 | if (packet_connection_is_on_socket()) { | 1496 | if (packet_connection_is_on_socket()) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.h,v 1.88 2018/06/06 18:29:18 markus Exp $ */ | 1 | /* $OpenBSD: ssh.h,v 1.89 2018/12/27 03:25:25 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -93,3 +93,7 @@ | |||
93 | 93 | ||
94 | /* Listen backlog for sshd, ssh-agent and forwarding sockets */ | 94 | /* Listen backlog for sshd, ssh-agent and forwarding sockets */ |
95 | #define SSH_LISTEN_BACKLOG 128 | 95 | #define SSH_LISTEN_BACKLOG 128 |
96 | |||
97 | /* Limits for banner exchange */ | ||
98 | #define SSH_MAX_BANNER_LEN 8192 | ||
99 | #define SSH_MAX_PRE_BANNER_LINES 1024 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh_api.c,v 1.8 2017/04/30 23:13:25 djm Exp $ */ | 1 | /* $OpenBSD: ssh_api.c,v 1.9 2018/12/27 03:25:25 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2012 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2012 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -34,8 +34,8 @@ | |||
34 | #include <string.h> | 34 | #include <string.h> |
35 | 35 | ||
36 | int _ssh_exchange_banner(struct ssh *); | 36 | int _ssh_exchange_banner(struct ssh *); |
37 | int _ssh_send_banner(struct ssh *, char **); | 37 | int _ssh_send_banner(struct ssh *, struct sshbuf *); |
38 | int _ssh_read_banner(struct ssh *, char **); | 38 | int _ssh_read_banner(struct ssh *, struct sshbuf *); |
39 | int _ssh_order_hostkeyalgs(struct ssh *); | 39 | int _ssh_order_hostkeyalgs(struct ssh *); |
40 | int _ssh_verify_host_key(struct sshkey *, struct ssh *); | 40 | int _ssh_verify_host_key(struct sshkey *, struct ssh *); |
41 | struct sshkey *_ssh_host_public_key(int, int, struct ssh *); | 41 | struct sshkey *_ssh_host_public_key(int, int, struct ssh *); |
@@ -92,7 +92,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) | |||
92 | 92 | ||
93 | /* Initialize key exchange */ | 93 | /* Initialize key exchange */ |
94 | proposal = kex_params ? kex_params->proposal : myproposal; | 94 | proposal = kex_params ? kex_params->proposal : myproposal; |
95 | if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) { | 95 | if ((r = kex_ready(ssh, proposal)) != 0) { |
96 | ssh_free(ssh); | 96 | ssh_free(ssh); |
97 | return r; | 97 | return r; |
98 | } | 98 | } |
@@ -236,8 +236,8 @@ ssh_packet_next(struct ssh *ssh, u_char *typep) | |||
236 | * enough data. | 236 | * enough data. |
237 | */ | 237 | */ |
238 | *typep = SSH_MSG_NONE; | 238 | *typep = SSH_MSG_NONE; |
239 | if (ssh->kex->client_version_string == NULL || | 239 | if (sshbuf_len(ssh->kex->client_version) == 0 || |
240 | ssh->kex->server_version_string == NULL) | 240 | sshbuf_len(ssh->kex->server_version) == 0) |
241 | return _ssh_exchange_banner(ssh); | 241 | return _ssh_exchange_banner(ssh); |
242 | /* | 242 | /* |
243 | * If we enough data and a dispatch function then | 243 | * If we enough data and a dispatch function then |
@@ -312,39 +312,46 @@ ssh_input_space(struct ssh *ssh, size_t len) | |||
312 | 312 | ||
313 | /* Read other side's version identification. */ | 313 | /* Read other side's version identification. */ |
314 | int | 314 | int |
315 | _ssh_read_banner(struct ssh *ssh, char **bannerp) | 315 | _ssh_read_banner(struct ssh *ssh, struct sshbuf *banner) |
316 | { | 316 | { |
317 | struct sshbuf *input; | 317 | struct sshbuf *input = ssh_packet_get_input(ssh); |
318 | const char *s; | ||
319 | char buf[256], remote_version[256]; /* must be same size! */ | ||
320 | const char *mismatch = "Protocol mismatch.\r\n"; | 318 | const char *mismatch = "Protocol mismatch.\r\n"; |
321 | int r, remote_major, remote_minor; | 319 | const u_char *s = sshbuf_ptr(input); |
322 | size_t i, n, j, len; | 320 | u_char c; |
321 | char *cp, *remote_version; | ||
322 | int r, remote_major, remote_minor, expect_nl; | ||
323 | size_t n, j; | ||
323 | 324 | ||
324 | *bannerp = NULL; | ||
325 | input = ssh_packet_get_input(ssh); | ||
326 | len = sshbuf_len(input); | ||
327 | s = (const char *)sshbuf_ptr(input); | ||
328 | for (j = n = 0;;) { | 325 | for (j = n = 0;;) { |
329 | for (i = 0; i < sizeof(buf) - 1; i++) { | 326 | sshbuf_reset(banner); |
330 | if (j >= len) | 327 | expect_nl = 0; |
331 | return (0); | 328 | for (;;) { |
332 | buf[i] = s[j++]; | 329 | if (j >= sshbuf_len(input)) |
333 | if (buf[i] == '\r') { | 330 | return 0; /* insufficient data in input buf */ |
334 | buf[i] = '\n'; | 331 | c = s[j++]; |
335 | buf[i + 1] = 0; | 332 | if (c == '\r') { |
336 | continue; /**XXX wait for \n */ | 333 | expect_nl = 1; |
334 | continue; | ||
337 | } | 335 | } |
338 | if (buf[i] == '\n') { | 336 | if (c == '\n') |
339 | buf[i + 1] = 0; | ||
340 | break; | 337 | break; |
341 | } | 338 | if (expect_nl) |
339 | goto bad; | ||
340 | if ((r = sshbuf_put_u8(banner, c)) != 0) | ||
341 | return r; | ||
342 | if (sshbuf_len(banner) > SSH_MAX_BANNER_LEN) | ||
343 | goto bad; | ||
342 | } | 344 | } |
343 | buf[sizeof(buf) - 1] = 0; | 345 | if (sshbuf_len(banner) >= 4 && |
344 | if (strncmp(buf, "SSH-", 4) == 0) | 346 | memcmp(sshbuf_ptr(banner), "SSH-", 4) == 0) |
345 | break; | 347 | break; |
346 | debug("ssh_exchange_identification: %s", buf); | 348 | if ((cp = sshbuf_dup_string(banner)) == NULL) |
347 | if (ssh->kex->server || ++n > 65536) { | 349 | return SSH_ERR_ALLOC_FAIL; |
350 | debug("%s: %s", __func__, cp); | ||
351 | free(cp); | ||
352 | /* Accept lines before banner only on client */ | ||
353 | if (ssh->kex->server || ++n > SSH_MAX_PRE_BANNER_LINES) { | ||
354 | bad: | ||
348 | if ((r = sshbuf_put(ssh_packet_get_output(ssh), | 355 | if ((r = sshbuf_put(ssh_packet_get_output(ssh), |
349 | mismatch, strlen(mismatch))) != 0) | 356 | mismatch, strlen(mismatch))) != 0) |
350 | return r; | 357 | return r; |
@@ -354,11 +361,17 @@ _ssh_read_banner(struct ssh *ssh, char **bannerp) | |||
354 | if ((r = sshbuf_consume(input, j)) != 0) | 361 | if ((r = sshbuf_consume(input, j)) != 0) |
355 | return r; | 362 | return r; |
356 | 363 | ||
364 | if ((cp = sshbuf_dup_string(banner)) == NULL) | ||
365 | return SSH_ERR_ALLOC_FAIL; | ||
366 | /* XXX remote version must be the same size as banner for sscanf */ | ||
367 | if ((remote_version = calloc(1, sshbuf_len(banner))) == NULL) | ||
368 | return SSH_ERR_ALLOC_FAIL; | ||
369 | |||
357 | /* | 370 | /* |
358 | * Check that the versions match. In future this might accept | 371 | * Check that the versions match. In future this might accept |
359 | * several versions and set appropriate flags to handle them. | 372 | * several versions and set appropriate flags to handle them. |
360 | */ | 373 | */ |
361 | if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", | 374 | if (sscanf(cp, "SSH-%d.%d-%[^\n]\n", |
362 | &remote_major, &remote_minor, remote_version) != 3) | 375 | &remote_major, &remote_minor, remote_version) != 3) |
363 | return SSH_ERR_INVALID_FORMAT; | 376 | return SSH_ERR_INVALID_FORMAT; |
364 | debug("Remote protocol version %d.%d, remote software version %.100s", | 377 | debug("Remote protocol version %d.%d, remote software version %.100s", |
@@ -371,27 +384,29 @@ _ssh_read_banner(struct ssh *ssh, char **bannerp) | |||
371 | } | 384 | } |
372 | if (remote_major != 2) | 385 | if (remote_major != 2) |
373 | return SSH_ERR_PROTOCOL_MISMATCH; | 386 | return SSH_ERR_PROTOCOL_MISMATCH; |
374 | chop(buf); | 387 | debug("Remote version string %.100s", cp); |
375 | debug("Remote version string %.100s", buf); | 388 | free(cp); |
376 | if ((*bannerp = strdup(buf)) == NULL) | ||
377 | return SSH_ERR_ALLOC_FAIL; | ||
378 | return 0; | 389 | return 0; |
379 | } | 390 | } |
380 | 391 | ||
381 | /* Send our own protocol version identification. */ | 392 | /* Send our own protocol version identification. */ |
382 | int | 393 | int |
383 | _ssh_send_banner(struct ssh *ssh, char **bannerp) | 394 | _ssh_send_banner(struct ssh *ssh, struct sshbuf *banner) |
384 | { | 395 | { |
385 | char buf[256]; | 396 | char *cp; |
386 | int r; | 397 | int r; |
387 | 398 | ||
388 | snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION); | 399 | if ((r = sshbuf_putf(banner, "SSH-2.0-%.100s\r\n", SSH_VERSION)) != 0) |
389 | if ((r = sshbuf_put(ssh_packet_get_output(ssh), buf, strlen(buf))) != 0) | 400 | return r; |
401 | if ((r = sshbuf_putb(ssh_packet_get_output(ssh), banner)) != 0) | ||
402 | return r; | ||
403 | /* Remove trailing \r\n */ | ||
404 | if ((r = sshbuf_consume_end(banner, 2)) != 0) | ||
390 | return r; | 405 | return r; |
391 | chop(buf); | 406 | if ((cp = sshbuf_dup_string(banner)) == NULL) |
392 | debug("Local version string %.100s", buf); | ||
393 | if ((*bannerp = strdup(buf)) == NULL) | ||
394 | return SSH_ERR_ALLOC_FAIL; | 407 | return SSH_ERR_ALLOC_FAIL; |
408 | debug("Local version string %.100s", cp); | ||
409 | free(cp); | ||
395 | return 0; | 410 | return 0; |
396 | } | 411 | } |
397 | 412 | ||
@@ -408,25 +423,25 @@ _ssh_exchange_banner(struct ssh *ssh) | |||
408 | 423 | ||
409 | r = 0; | 424 | r = 0; |
410 | if (kex->server) { | 425 | if (kex->server) { |
411 | if (kex->server_version_string == NULL) | 426 | if (sshbuf_len(ssh->kex->server_version) == 0) |
412 | r = _ssh_send_banner(ssh, &kex->server_version_string); | 427 | r = _ssh_send_banner(ssh, ssh->kex->server_version); |
413 | if (r == 0 && | 428 | if (r == 0 && |
414 | kex->server_version_string != NULL && | 429 | sshbuf_len(ssh->kex->server_version) != 0 && |
415 | kex->client_version_string == NULL) | 430 | sshbuf_len(ssh->kex->client_version) == 0) |
416 | r = _ssh_read_banner(ssh, &kex->client_version_string); | 431 | r = _ssh_read_banner(ssh, ssh->kex->client_version); |
417 | } else { | 432 | } else { |
418 | if (kex->server_version_string == NULL) | 433 | if (sshbuf_len(ssh->kex->server_version) == 0) |
419 | r = _ssh_read_banner(ssh, &kex->server_version_string); | 434 | r = _ssh_read_banner(ssh, ssh->kex->server_version); |
420 | if (r == 0 && | 435 | if (r == 0 && |
421 | kex->server_version_string != NULL && | 436 | sshbuf_len(ssh->kex->server_version) != 0 && |
422 | kex->client_version_string == NULL) | 437 | sshbuf_len(ssh->kex->client_version) == 0) |
423 | r = _ssh_send_banner(ssh, &kex->client_version_string); | 438 | r = _ssh_send_banner(ssh, ssh->kex->client_version); |
424 | } | 439 | } |
425 | if (r != 0) | 440 | if (r != 0) |
426 | return r; | 441 | return r; |
427 | /* start initial kex as soon as we have exchanged the banners */ | 442 | /* start initial kex as soon as we have exchanged the banners */ |
428 | if (kex->server_version_string != NULL && | 443 | if (sshbuf_len(ssh->kex->server_version) != 0 && |
429 | kex->client_version_string != NULL) { | 444 | sshbuf_len(ssh->kex->client_version) != 0) { |
430 | if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 || | 445 | if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 || |
431 | (r = kex_send_kexinit(ssh)) != 0) | 446 | (r = kex_send_kexinit(ssh)) != 0) |
432 | return r; | 447 | return r; |
diff --git a/sshconnect.c b/sshconnect.c index 4862da5ed..884e33628 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.308 2018/11/18 22:43:29 dtucker Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.309 2018/12/27 03:25:25 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,9 +68,8 @@ | |||
68 | #include "authfile.h" | 68 | #include "authfile.h" |
69 | #include "ssherr.h" | 69 | #include "ssherr.h" |
70 | #include "authfd.h" | 70 | #include "authfd.h" |
71 | #include "kex.h" | ||
71 | 72 | ||
72 | char *client_version_string = NULL; | ||
73 | char *server_version_string = NULL; | ||
74 | struct sshkey *previous_host_key = NULL; | 73 | struct sshkey *previous_host_key = NULL; |
75 | 74 | ||
76 | static int matching_host_key_dns = 0; | 75 | static int matching_host_key_dns = 0; |
@@ -445,73 +444,6 @@ fail: | |||
445 | } | 444 | } |
446 | 445 | ||
447 | /* | 446 | /* |
448 | * Wait up to *timeoutp milliseconds for fd to be readable. Updates | ||
449 | * *timeoutp with time remaining. | ||
450 | * Returns 0 if fd ready or -1 on timeout or error (see errno). | ||
451 | */ | ||
452 | static int | ||
453 | waitrfd(int fd, int *timeoutp) | ||
454 | { | ||
455 | struct pollfd pfd; | ||
456 | struct timeval t_start; | ||
457 | int oerrno, r; | ||
458 | |||
459 | monotime_tv(&t_start); | ||
460 | pfd.fd = fd; | ||
461 | pfd.events = POLLIN; | ||
462 | for (; *timeoutp >= 0;) { | ||
463 | r = poll(&pfd, 1, *timeoutp); | ||
464 | oerrno = errno; | ||
465 | ms_subtract_diff(&t_start, timeoutp); | ||
466 | errno = oerrno; | ||
467 | if (r > 0) | ||
468 | return 0; | ||
469 | else if (r == -1 && errno != EAGAIN) | ||
470 | return -1; | ||
471 | else if (r == 0) | ||
472 | break; | ||
473 | } | ||
474 | /* timeout */ | ||
475 | errno = ETIMEDOUT; | ||
476 | return -1; | ||
477 | } | ||
478 | |||
479 | static int | ||
480 | timeout_connect(int sockfd, const struct sockaddr *serv_addr, | ||
481 | socklen_t addrlen, int *timeoutp) | ||
482 | { | ||
483 | int optval = 0; | ||
484 | socklen_t optlen = sizeof(optval); | ||
485 | |||
486 | /* No timeout: just do a blocking connect() */ | ||
487 | if (*timeoutp <= 0) | ||
488 | return connect(sockfd, serv_addr, addrlen); | ||
489 | |||
490 | set_nonblock(sockfd); | ||
491 | if (connect(sockfd, serv_addr, addrlen) == 0) { | ||
492 | /* Succeeded already? */ | ||
493 | unset_nonblock(sockfd); | ||
494 | return 0; | ||
495 | } else if (errno != EINPROGRESS) | ||
496 | return -1; | ||
497 | |||
498 | if (waitrfd(sockfd, timeoutp) == -1) | ||
499 | return -1; | ||
500 | |||
501 | /* Completed or failed */ | ||
502 | if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) { | ||
503 | debug("getsockopt: %s", strerror(errno)); | ||
504 | return -1; | ||
505 | } | ||
506 | if (optval != 0) { | ||
507 | errno = optval; | ||
508 | return -1; | ||
509 | } | ||
510 | unset_nonblock(sockfd); | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * Opens a TCP/IP connection to the remote server on the given host. | 447 | * Opens a TCP/IP connection to the remote server on the given host. |
516 | * The address of the remote host will be returned in hostaddr. | 448 | * The address of the remote host will be returned in hostaddr. |
517 | * If port is 0, the default port will be used. | 449 | * If port is 0, the default port will be used. |
@@ -629,110 +561,6 @@ ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs, | |||
629 | return ssh_proxy_connect(ssh, host, port, options.proxy_command); | 561 | return ssh_proxy_connect(ssh, host, port, options.proxy_command); |
630 | } | 562 | } |
631 | 563 | ||
632 | static void | ||
633 | send_client_banner(int connection_out, int minor1) | ||
634 | { | ||
635 | /* Send our own protocol version identification. */ | ||
636 | xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", | ||
637 | PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION); | ||
638 | if (atomicio(vwrite, connection_out, client_version_string, | ||
639 | strlen(client_version_string)) != strlen(client_version_string)) | ||
640 | fatal("write: %.100s", strerror(errno)); | ||
641 | chop(client_version_string); | ||
642 | debug("Local version string %.100s", client_version_string); | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * Waits for the server identification string, and sends our own | ||
647 | * identification string. | ||
648 | */ | ||
649 | void | ||
650 | ssh_exchange_identification(int timeout_ms) | ||
651 | { | ||
652 | char buf[256], remote_version[256]; /* must be same size! */ | ||
653 | int remote_major, remote_minor, mismatch; | ||
654 | int connection_in = packet_get_connection_in(); | ||
655 | int connection_out = packet_get_connection_out(); | ||
656 | u_int i, n; | ||
657 | size_t len; | ||
658 | int rc; | ||
659 | |||
660 | send_client_banner(connection_out, 0); | ||
661 | |||
662 | /* Read other side's version identification. */ | ||
663 | for (n = 0;;) { | ||
664 | for (i = 0; i < sizeof(buf) - 1; i++) { | ||
665 | if (timeout_ms > 0) { | ||
666 | rc = waitrfd(connection_in, &timeout_ms); | ||
667 | if (rc == -1 && errno == ETIMEDOUT) { | ||
668 | fatal("Connection timed out during " | ||
669 | "banner exchange"); | ||
670 | } else if (rc == -1) { | ||
671 | fatal("%s: %s", | ||
672 | __func__, strerror(errno)); | ||
673 | } | ||
674 | } | ||
675 | |||
676 | len = atomicio(read, connection_in, &buf[i], 1); | ||
677 | if (len != 1 && errno == EPIPE) | ||
678 | fatal("ssh_exchange_identification: " | ||
679 | "Connection closed by remote host"); | ||
680 | else if (len != 1) | ||
681 | fatal("ssh_exchange_identification: " | ||
682 | "read: %.100s", strerror(errno)); | ||
683 | if (buf[i] == '\r') { | ||
684 | buf[i] = '\n'; | ||
685 | buf[i + 1] = 0; | ||
686 | continue; /**XXX wait for \n */ | ||
687 | } | ||
688 | if (buf[i] == '\n') { | ||
689 | buf[i + 1] = 0; | ||
690 | break; | ||
691 | } | ||
692 | if (++n > 65536) | ||
693 | fatal("ssh_exchange_identification: " | ||
694 | "No banner received"); | ||
695 | } | ||
696 | buf[sizeof(buf) - 1] = 0; | ||
697 | if (strncmp(buf, "SSH-", 4) == 0) | ||
698 | break; | ||
699 | debug("ssh_exchange_identification: %s", buf); | ||
700 | } | ||
701 | server_version_string = xstrdup(buf); | ||
702 | |||
703 | /* | ||
704 | * Check that the versions match. In future this might accept | ||
705 | * several versions and set appropriate flags to handle them. | ||
706 | */ | ||
707 | if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", | ||
708 | &remote_major, &remote_minor, remote_version) != 3) | ||
709 | fatal("Bad remote protocol version identification: '%.100s'", buf); | ||
710 | debug("Remote protocol version %d.%d, remote software version %.100s", | ||
711 | remote_major, remote_minor, remote_version); | ||
712 | |||
713 | active_state->compat = compat_datafellows(remote_version); | ||
714 | mismatch = 0; | ||
715 | |||
716 | switch (remote_major) { | ||
717 | case 2: | ||
718 | break; | ||
719 | case 1: | ||
720 | if (remote_minor != 99) | ||
721 | mismatch = 1; | ||
722 | break; | ||
723 | default: | ||
724 | mismatch = 1; | ||
725 | break; | ||
726 | } | ||
727 | if (mismatch) | ||
728 | fatal("Protocol major versions differ: %d vs. %d", | ||
729 | PROTOCOL_MAJOR_2, remote_major); | ||
730 | if ((datafellows & SSH_BUG_RSASIGMD5) != 0) | ||
731 | logit("Server version \"%.100s\" uses unsafe RSA signature " | ||
732 | "scheme; disabling use of RSA keys", remote_version); | ||
733 | chop(server_version_string); | ||
734 | } | ||
735 | |||
736 | /* defaults to 'no' */ | 564 | /* defaults to 'no' */ |
737 | static int | 565 | static int |
738 | confirm(const char *prompt) | 566 | confirm(const char *prompt) |
@@ -1426,7 +1254,7 @@ out: | |||
1426 | * This function does not require super-user privileges. | 1254 | * This function does not require super-user privileges. |
1427 | */ | 1255 | */ |
1428 | void | 1256 | void |
1429 | ssh_login(Sensitive *sensitive, const char *orighost, | 1257 | ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, |
1430 | struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) | 1258 | struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) |
1431 | { | 1259 | { |
1432 | char *host; | 1260 | char *host; |
@@ -1440,16 +1268,17 @@ ssh_login(Sensitive *sensitive, const char *orighost, | |||
1440 | lowercase(host); | 1268 | lowercase(host); |
1441 | 1269 | ||
1442 | /* Exchange protocol version identification strings with the server. */ | 1270 | /* Exchange protocol version identification strings with the server. */ |
1443 | ssh_exchange_identification(timeout_ms); | 1271 | if (kex_exchange_identification(ssh, timeout_ms, NULL) != 0) |
1272 | cleanup_exit(255); /* error already logged */ | ||
1444 | 1273 | ||
1445 | /* Put the connection into non-blocking mode. */ | 1274 | /* Put the connection into non-blocking mode. */ |
1446 | packet_set_nonblocking(); | 1275 | ssh_packet_set_nonblocking(ssh); |
1447 | 1276 | ||
1448 | /* key exchange */ | 1277 | /* key exchange */ |
1449 | /* authenticate user */ | 1278 | /* authenticate user */ |
1450 | debug("Authenticating to %s:%d as '%s'", host, port, server_user); | 1279 | debug("Authenticating to %s:%d as '%s'", host, port, server_user); |
1451 | ssh_kex2(host, hostaddr, port); | 1280 | ssh_kex2(ssh, host, hostaddr, port); |
1452 | ssh_userauth2(local_user, server_user, host, sensitive); | 1281 | ssh_userauth2(ssh, local_user, server_user, host, sensitive); |
1453 | free(local_user); | 1282 | free(local_user); |
1454 | } | 1283 | } |
1455 | 1284 | ||
diff --git a/sshconnect.h b/sshconnect.h index 890d85733..44a5071c7 100644 --- a/sshconnect.h +++ b/sshconnect.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.h,v 1.35 2018/07/19 10:28:47 dtucker Exp $ */ | 1 | /* $OpenBSD: sshconnect.h,v 1.36 2018/12/27 03:25:25 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -37,21 +37,18 @@ int ssh_connect(struct ssh *, const char *, struct addrinfo *, | |||
37 | struct sockaddr_storage *, u_short, int, int, int *, int); | 37 | struct sockaddr_storage *, u_short, int, int, int *, int); |
38 | void ssh_kill_proxy_command(void); | 38 | void ssh_kill_proxy_command(void); |
39 | 39 | ||
40 | void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, | 40 | void ssh_login(struct ssh *, Sensitive *, const char *, |
41 | struct passwd *, int); | 41 | struct sockaddr *, u_short, struct passwd *, int); |
42 | |||
43 | void ssh_exchange_identification(int); | ||
44 | 42 | ||
45 | int verify_host_key(char *, struct sockaddr *, struct sshkey *); | 43 | int verify_host_key(char *, struct sockaddr *, struct sshkey *); |
46 | 44 | ||
47 | void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short, | 45 | void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short, |
48 | char **, char **); | 46 | char **, char **); |
49 | 47 | ||
50 | void ssh_kex(char *, struct sockaddr *); | 48 | void ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short); |
51 | void ssh_kex2(char *, struct sockaddr *, u_short); | ||
52 | 49 | ||
53 | void ssh_userauth1(const char *, const char *, char *, Sensitive *); | 50 | void ssh_userauth2(struct ssh *ssh, const char *, const char *, |
54 | void ssh_userauth2(const char *, const char *, char *, Sensitive *); | 51 | char *, Sensitive *); |
55 | 52 | ||
56 | void ssh_put_password(char *); | 53 | void ssh_put_password(char *); |
57 | int ssh_local_cmd(const char *); | 54 | int ssh_local_cmd(const char *); |
diff --git a/sshconnect2.c b/sshconnect2.c index adb4e4cbd..19caebabc 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.290 2018/11/28 06:00:38 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.291 2018/12/27 03:25:25 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) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -155,11 +155,10 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | void | 157 | void |
158 | ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | 158 | ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) |
159 | { | 159 | { |
160 | char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; | 160 | char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; |
161 | char *s, *all_key; | 161 | char *s, *all_key; |
162 | struct kex *kex; | ||
163 | int r; | 162 | int r; |
164 | 163 | ||
165 | xxx_host = host; | 164 | xxx_host = host; |
@@ -199,36 +198,33 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | |||
199 | options.rekey_interval); | 198 | options.rekey_interval); |
200 | 199 | ||
201 | /* start key exchange */ | 200 | /* start key exchange */ |
202 | if ((r = kex_setup(active_state, myproposal)) != 0) | 201 | if ((r = kex_setup(ssh, myproposal)) != 0) |
203 | fatal("kex_setup: %s", ssh_err(r)); | 202 | fatal("kex_setup: %s", ssh_err(r)); |
204 | kex = active_state->kex; | ||
205 | #ifdef WITH_OPENSSL | 203 | #ifdef WITH_OPENSSL |
206 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; | 204 | ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; |
207 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; | 205 | ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; |
208 | kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; | 206 | ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; |
209 | kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; | 207 | ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; |
210 | kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; | 208 | ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; |
211 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | 209 | ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
212 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; | 210 | ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
213 | # ifdef OPENSSL_HAS_ECC | 211 | # ifdef OPENSSL_HAS_ECC |
214 | kex->kex[KEX_ECDH_SHA2] = kexecdh_client; | 212 | ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client; |
215 | # endif | 213 | # endif |
216 | #endif | 214 | #endif |
217 | kex->kex[KEX_C25519_SHA256] = kexc25519_client; | 215 | ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client; |
218 | kex->client_version_string=client_version_string; | 216 | ssh->kex->verify_host_key=&verify_host_key_callback; |
219 | kex->server_version_string=server_version_string; | ||
220 | kex->verify_host_key=&verify_host_key_callback; | ||
221 | 217 | ||
222 | ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); | 218 | ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); |
223 | 219 | ||
224 | /* remove ext-info from the KEX proposals for rekeying */ | 220 | /* remove ext-info from the KEX proposals for rekeying */ |
225 | myproposal[PROPOSAL_KEX_ALGS] = | 221 | myproposal[PROPOSAL_KEX_ALGS] = |
226 | compat_kex_proposal(options.kex_algorithms); | 222 | compat_kex_proposal(options.kex_algorithms); |
227 | if ((r = kex_prop2buf(kex->my, myproposal)) != 0) | 223 | if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) |
228 | fatal("kex_prop2buf: %s", ssh_err(r)); | 224 | fatal("kex_prop2buf: %s", ssh_err(r)); |
229 | 225 | ||
230 | session_id2 = kex->session_id; | 226 | session_id2 = ssh->kex->session_id; |
231 | session_id2_len = kex->session_id_len; | 227 | session_id2_len = ssh->kex->session_id_len; |
232 | 228 | ||
233 | #ifdef DEBUG_KEXDH | 229 | #ifdef DEBUG_KEXDH |
234 | /* send 1st encrypted/maced/compressed message */ | 230 | /* send 1st encrypted/maced/compressed message */ |
@@ -365,10 +361,9 @@ Authmethod authmethods[] = { | |||
365 | }; | 361 | }; |
366 | 362 | ||
367 | void | 363 | void |
368 | ssh_userauth2(const char *local_user, const char *server_user, char *host, | 364 | ssh_userauth2(struct ssh *ssh, const char *local_user, |
369 | Sensitive *sensitive) | 365 | const char *server_user, char *host, Sensitive *sensitive) |
370 | { | 366 | { |
371 | struct ssh *ssh = active_state; | ||
372 | Authctxt authctxt; | 367 | Authctxt authctxt; |
373 | int r; | 368 | int r; |
374 | 369 | ||
@@ -392,8 +387,10 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, | |||
392 | authctxt.info_req_seen = 0; | 387 | authctxt.info_req_seen = 0; |
393 | authctxt.agent_fd = -1; | 388 | authctxt.agent_fd = -1; |
394 | pubkey_prepare(&authctxt); | 389 | pubkey_prepare(&authctxt); |
395 | if (authctxt.method == NULL) | 390 | if (authctxt.method == NULL) { |
396 | fatal("ssh_userauth2: internal error: cannot send userauth none request"); | 391 | fatal("%s: internal error: cannot send userauth none request", |
392 | __func__); | ||
393 | } | ||
397 | 394 | ||
398 | if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST)) != 0 || | 395 | if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST)) != 0 || |
399 | (r = sshpkt_put_cstring(ssh, "ssh-userauth")) != 0 || | 396 | (r = sshpkt_put_cstring(ssh, "ssh-userauth")) != 0 || |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.519 2018/11/19 04:12:32 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.520 2018/12/27 03:25:25 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 |
@@ -180,13 +180,6 @@ char **rexec_argv; | |||
180 | int listen_socks[MAX_LISTEN_SOCKS]; | 180 | int listen_socks[MAX_LISTEN_SOCKS]; |
181 | int num_listen_socks = 0; | 181 | int num_listen_socks = 0; |
182 | 182 | ||
183 | /* | ||
184 | * the client's version string, passed by sshd2 in compat mode. if != NULL, | ||
185 | * sshd will skip the version-number exchange | ||
186 | */ | ||
187 | char *client_version_string = NULL; | ||
188 | char *server_version_string = NULL; | ||
189 | |||
190 | /* Daemon's agent connection */ | 183 | /* Daemon's agent connection */ |
191 | int auth_sock = -1; | 184 | int auth_sock = -1; |
192 | int have_agent = 0; | 185 | int have_agent = 0; |
@@ -363,108 +356,6 @@ grace_alarm_handler(int sig) | |||
363 | ssh_remote_ipaddr(active_state), ssh_remote_port(active_state)); | 356 | ssh_remote_ipaddr(active_state), ssh_remote_port(active_state)); |
364 | } | 357 | } |
365 | 358 | ||
366 | static void | ||
367 | sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | ||
368 | { | ||
369 | u_int i; | ||
370 | int remote_major, remote_minor; | ||
371 | char *s; | ||
372 | char buf[256]; /* Must not be larger than remote_version. */ | ||
373 | char remote_version[256]; /* Must be at least as big as buf. */ | ||
374 | |||
375 | xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", | ||
376 | PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, | ||
377 | *options.version_addendum == '\0' ? "" : " ", | ||
378 | options.version_addendum); | ||
379 | |||
380 | /* Send our protocol version identification. */ | ||
381 | if (atomicio(vwrite, sock_out, server_version_string, | ||
382 | strlen(server_version_string)) | ||
383 | != strlen(server_version_string)) { | ||
384 | logit("Could not write ident string to %s port %d", | ||
385 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | ||
386 | cleanup_exit(255); | ||
387 | } | ||
388 | |||
389 | /* Read other sides version identification. */ | ||
390 | memset(buf, 0, sizeof(buf)); | ||
391 | for (i = 0; i < sizeof(buf) - 1; i++) { | ||
392 | if (atomicio(read, sock_in, &buf[i], 1) != 1) { | ||
393 | logit("Did not receive identification string " | ||
394 | "from %s port %d", | ||
395 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | ||
396 | cleanup_exit(255); | ||
397 | } | ||
398 | if (buf[i] == '\r') { | ||
399 | buf[i] = 0; | ||
400 | /* Kludge for F-Secure Macintosh < 1.0.2 */ | ||
401 | if (i == 12 && | ||
402 | strncmp(buf, "SSH-1.5-W1.0", 12) == 0) | ||
403 | break; | ||
404 | continue; | ||
405 | } | ||
406 | if (buf[i] == '\n') { | ||
407 | buf[i] = 0; | ||
408 | break; | ||
409 | } | ||
410 | } | ||
411 | buf[sizeof(buf) - 1] = 0; | ||
412 | client_version_string = xstrdup(buf); | ||
413 | |||
414 | /* | ||
415 | * Check that the versions match. In future this might accept | ||
416 | * several versions and set appropriate flags to handle them. | ||
417 | */ | ||
418 | if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", | ||
419 | &remote_major, &remote_minor, remote_version) != 3) { | ||
420 | s = "Protocol mismatch.\n"; | ||
421 | (void) atomicio(vwrite, sock_out, s, strlen(s)); | ||
422 | logit("Bad protocol version identification '%.100s' " | ||
423 | "from %s port %d", client_version_string, | ||
424 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | ||
425 | close(sock_in); | ||
426 | close(sock_out); | ||
427 | cleanup_exit(255); | ||
428 | } | ||
429 | debug("Client protocol version %d.%d; client software version %.100s", | ||
430 | remote_major, remote_minor, remote_version); | ||
431 | |||
432 | ssh->compat = compat_datafellows(remote_version); | ||
433 | |||
434 | if ((ssh->compat & SSH_BUG_PROBE) != 0) { | ||
435 | logit("probed from %s port %d with %s. Don't panic.", | ||
436 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
437 | client_version_string); | ||
438 | cleanup_exit(255); | ||
439 | } | ||
440 | if ((ssh->compat & SSH_BUG_SCANNER) != 0) { | ||
441 | logit("scanned from %s port %d with %s. Don't panic.", | ||
442 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
443 | client_version_string); | ||
444 | cleanup_exit(255); | ||
445 | } | ||
446 | if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) { | ||
447 | logit("Client version \"%.100s\" uses unsafe RSA signature " | ||
448 | "scheme; disabling use of RSA keys", remote_version); | ||
449 | } | ||
450 | |||
451 | chop(server_version_string); | ||
452 | debug("Local version string %.200s", server_version_string); | ||
453 | |||
454 | if (remote_major != 2 && | ||
455 | !(remote_major == 1 && remote_minor == 99)) { | ||
456 | s = "Protocol major versions differ.\n"; | ||
457 | (void) atomicio(vwrite, sock_out, s, strlen(s)); | ||
458 | close(sock_in); | ||
459 | close(sock_out); | ||
460 | logit("Protocol major versions differ for %s port %d: " | ||
461 | "%.200s vs. %.200s", | ||
462 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), | ||
463 | server_version_string, client_version_string); | ||
464 | cleanup_exit(255); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | /* Destroy the host and server keys. They will no longer be needed. */ | 359 | /* Destroy the host and server keys. They will no longer be needed. */ |
469 | void | 360 | void |
470 | destroy_sensitive_data(void) | 361 | destroy_sensitive_data(void) |
@@ -2115,7 +2006,9 @@ main(int ac, char **av) | |||
2115 | if (!debug_flag) | 2006 | if (!debug_flag) |
2116 | alarm(options.login_grace_time); | 2007 | alarm(options.login_grace_time); |
2117 | 2008 | ||
2118 | sshd_exchange_identification(ssh, sock_in, sock_out); | 2009 | if (kex_exchange_identification(ssh, -1, options.version_addendum) != 0) |
2010 | cleanup_exit(255); /* error already logged */ | ||
2011 | |||
2119 | packet_set_nonblocking(); | 2012 | packet_set_nonblocking(); |
2120 | 2013 | ||
2121 | /* allocate authentication context */ | 2014 | /* allocate authentication context */ |
@@ -2303,9 +2196,6 @@ do_ssh2_kex(void) | |||
2303 | # endif | 2196 | # endif |
2304 | #endif | 2197 | #endif |
2305 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; | 2198 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; |
2306 | kex->server = 1; | ||
2307 | kex->client_version_string=client_version_string; | ||
2308 | kex->server_version_string=server_version_string; | ||
2309 | kex->load_host_public_key=&get_hostkey_public_by_type; | 2199 | kex->load_host_public_key=&get_hostkey_public_by_type; |
2310 | kex->load_host_private_key=&get_hostkey_private_by_type; | 2200 | kex->load_host_private_key=&get_hostkey_private_by_type; |
2311 | kex->host_key_index=&get_hostkey_index; | 2201 | kex->host_key_index=&get_hostkey_index; |