summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog222
-rw-r--r--Makefile.in10
-rw-r--r--README4
-rw-r--r--auth-rsa.c22
-rw-r--r--auth.h6
-rw-r--r--auth1.c6
-rw-r--r--auth2-chall.c6
-rw-r--r--auth2-gss.c9
-rw-r--r--auth2-jpake.c563
-rw-r--r--auth2-passwd.c6
-rw-r--r--auth2.c11
-rw-r--r--authfd.c4
-rw-r--r--authfile.c20
-rw-r--r--bufaux.c8
-rw-r--r--bufbn.c11
-rw-r--r--bufec.c6
-rw-r--r--buffer.c4
-rw-r--r--canohost.c2
-rw-r--r--channels.c13
-rw-r--r--cipher-3des1.c6
-rw-r--r--cipher-chachapoly.c10
-rw-r--r--cipher.c22
-rw-r--r--clientloop.c10
-rw-r--r--config.h.in6
-rwxr-xr-xconfigure6
-rw-r--r--configure.ac8
-rw-r--r--contrib/caldera/openssh.spec4
-rw-r--r--contrib/redhat/openssh.spec2
-rw-r--r--contrib/suse/openssh.spec2
-rw-r--r--debian/.git-dpm6
-rw-r--r--debian/changelog5
-rw-r--r--debian/patches/auth-log-verbosity.patch6
-rw-r--r--debian/patches/authorized-keys-man-symlink.patch4
-rw-r--r--debian/patches/consolekit.patch72
-rw-r--r--debian/patches/debian-banner.patch22
-rw-r--r--debian/patches/debian-config.patch12
-rw-r--r--debian/patches/dnssec-sshfp.patch2
-rw-r--r--debian/patches/doc-hash-tab-completion.patch6
-rw-r--r--debian/patches/doc-upstart.patch2
-rw-r--r--debian/patches/fix-case-sensitive-matching.patch41
-rw-r--r--debian/patches/getsockname-error.patch27
-rw-r--r--debian/patches/gnome-ssh-askpass2-icon.patch2
-rw-r--r--debian/patches/gssapi.patch186
-rw-r--r--debian/patches/helpful-wait-terminate.patch4
-rw-r--r--debian/patches/keepalive-extensions.patch22
-rw-r--r--debian/patches/lintian-symlink-pickiness.patch4
-rw-r--r--debian/patches/mention-ssh-keygen-on-keychange.patch8
-rw-r--r--debian/patches/no-openssl-version-check.patch2
-rw-r--r--debian/patches/openbsd-docs.patch6
-rw-r--r--debian/patches/package-versioning.patch12
-rw-r--r--debian/patches/quieter-signals.patch4
-rw-r--r--debian/patches/scp-quoting.patch2
-rw-r--r--debian/patches/selinux-role.patch58
-rw-r--r--debian/patches/series2
-rw-r--r--debian/patches/shell-path.patch6
-rw-r--r--debian/patches/sigstop.patch6
-rw-r--r--debian/patches/ssh-agent-setgid.patch2
-rw-r--r--debian/patches/ssh-argv0.patch2
-rw-r--r--debian/patches/ssh-vulnkey-compat.patch10
-rw-r--r--debian/patches/ssh1-keepalive.patch8
-rw-r--r--debian/patches/syslog-level-silent.patch6
-rw-r--r--debian/patches/user-group-modes.patch12
-rw-r--r--digest-libc.c238
-rw-r--r--digest-openssl.c (renamed from digest.c)25
-rw-r--r--digest.h12
-rw-r--r--gss-serv.c24
-rw-r--r--hmac.c197
-rw-r--r--hmac.h37
-rw-r--r--hostfile.c33
-rw-r--r--jpake.c456
-rw-r--r--jpake.h114
-rw-r--r--kex.c6
-rw-r--r--kex.h7
-rw-r--r--kexc25519.c4
-rw-r--r--kexdhc.c4
-rw-r--r--kexdhs.c4
-rw-r--r--kexecdhc.c4
-rw-r--r--kexecdhs.c4
-rw-r--r--kexgexc.c4
-rw-r--r--kexgexs.c4
-rw-r--r--key.c12
-rw-r--r--krl.c12
-rw-r--r--mac.c94
-rw-r--r--moduli.02
-rw-r--r--monitor.c235
-rw-r--r--monitor.h7
-rw-r--r--monitor_wrap.c170
-rw-r--r--monitor_wrap.h22
-rw-r--r--openbsd-compat/Makefile.in4
-rw-r--r--openbsd-compat/bsd-poll.c11
-rw-r--r--openbsd-compat/explicit_bzero.c20
-rw-r--r--openbsd-compat/openbsd-compat.h6
-rw-r--r--openbsd-compat/openssl-compat.c10
-rw-r--r--openbsd-compat/openssl-compat.h6
-rw-r--r--packet.c16
-rw-r--r--readconf.c72
-rw-r--r--readconf.h5
-rw-r--r--readpass.c8
-rw-r--r--regress/Makefile3
-rw-r--r--regress/agent-ptrace.sh2
-rw-r--r--regress/agent.sh2
-rw-r--r--regress/cert-hostkey.sh2
-rw-r--r--regress/dhgex.sh54
-rw-r--r--regress/host-expand.sh1
-rw-r--r--regress/login-timeout.sh4
-rw-r--r--regress/scp-ssh-wrapper.sh2
-rw-r--r--regress/scp.sh2
-rw-r--r--regress/setuid-allowed.c1
-rw-r--r--regress/sftp-chroot.sh5
-rw-r--r--rsa.c10
-rw-r--r--sandbox-capsicum.c6
-rw-r--r--sandbox-seccomp-filter.c3
-rw-r--r--sandbox-systrace.c5
-rw-r--r--schnorr.c668
-rw-r--r--schnorr.h60
-rw-r--r--scp.02
-rw-r--r--servconf.c21
-rw-r--r--servconf.h4
-rw-r--r--serverloop.c4
-rw-r--r--session.c13
-rw-r--r--sftp-client.c4
-rw-r--r--sftp-server.02
-rw-r--r--sftp.02
-rw-r--r--ssh-add.02
-rw-r--r--ssh-add.c8
-rw-r--r--ssh-agent.02
-rw-r--r--ssh-agent.c20
-rw-r--r--ssh-dss.c10
-rw-r--r--ssh-ecdsa.c11
-rw-r--r--ssh-ed25519.c16
-rw-r--r--ssh-gss.h4
-rw-r--r--ssh-keygen.04
-rw-r--r--ssh-keygen.16
-rw-r--r--ssh-keygen.c38
-rw-r--r--ssh-keyscan.07
-rw-r--r--ssh-keyscan.128
-rw-r--r--ssh-keysign.02
-rw-r--r--ssh-pkcs11-helper.02
-rw-r--r--ssh-rsa.c14
-rw-r--r--ssh.02
-rw-r--r--ssh.c178
-rw-r--r--ssh2.h8
-rw-r--r--ssh_config.07
-rw-r--r--ssh_config.510
-rw-r--r--sshconnect.c35
-rw-r--r--sshconnect1.c37
-rw-r--r--sshconnect2.c311
-rw-r--r--sshd.02
-rw-r--r--sshd.c53
-rw-r--r--sshd_config.012
-rw-r--r--sshd_config.519
-rw-r--r--sshlogin.c2
-rw-r--r--version.h4
153 files changed, 1756 insertions, 3447 deletions
diff --git a/ChangeLog b/ChangeLog
index c0dab651b..38de846ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,224 @@
120140313
2 - (djm) Release OpenSSH 6.6
3
420140304
5 - OpenBSD CVS Sync
6 - djm@cvs.openbsd.org 2014/03/03 22:22:30
7 [session.c]
8 ignore enviornment variables with embedded '=' or '\0' characters;
9 spotted by Jann Horn; ok deraadt@
10
1120140301
12 - (djm) [regress/Makefile] Disable dhgex regress test; it breaks when
13 no moduli file exists at the expected location.
14
1520140228
16 - OpenBSD CVS Sync
17 - djm@cvs.openbsd.org 2014/02/27 00:41:49
18 [bufbn.c]
19 fix unsigned overflow that could lead to reading a short ssh protocol
20 1 bignum value; found by Ben Hawkes; ok deraadt@
21 - djm@cvs.openbsd.org 2014/02/27 08:25:09
22 [bufbn.c]
23 off by one in range check
24 - djm@cvs.openbsd.org 2014/02/27 22:47:07
25 [sshd_config.5]
26 bz#2184 clarify behaviour of a keyword that appears in multiple
27 matching Match blocks; ok dtucker@
28 - djm@cvs.openbsd.org 2014/02/27 22:57:40
29 [version.h]
30 openssh-6.6
31 - dtucker@cvs.openbsd.org 2014/01/19 23:43:02
32 [regress/sftp-chroot.sh]
33 Don't use -q on sftp as it suppresses logging, instead redirect the
34 output to the regress logfile.
35 - dtucker@cvs.openbsd.org 2014/01/20 00:00:30
36 [sregress/ftp-chroot.sh]
37 append to rather than truncating the log file
38 - dtucker@cvs.openbsd.org 2014/01/25 04:35:32
39 [regress/Makefile regress/dhgex.sh]
40 Add a test for DH GEX sizes
41 - djm@cvs.openbsd.org 2014/01/26 10:22:10
42 [regress/cert-hostkey.sh]
43 automatically generate revoked keys from listed keys rather than
44 manually specifying each type; from portable
45 (Id sync only)
46 - djm@cvs.openbsd.org 2014/01/26 10:49:17
47 [scp-ssh-wrapper.sh scp.sh]
48 make sure $SCP is tested on the remote end rather than whichever one
49 happens to be in $PATH; from portable
50 (Id sync only)
51 - djm@cvs.openbsd.org 2014/02/27 20:04:16
52 [login-timeout.sh]
53 remove any existing LoginGraceTime from sshd_config before adding
54 a specific one for the test back in
55 - djm@cvs.openbsd.org 2014/02/27 21:21:25
56 [agent-ptrace.sh agent.sh]
57 keep return values that are printed in error messages;
58 from portable
59 (Id sync only)
60 - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
61 [contrib/suse/openssh.spec] Crank version numbers
62 - (djm) [regress/host-expand.sh] Add RCS Id
63
6420140227
65 - OpenBSD CVS Sync
66 - djm@cvs.openbsd.org 2014/02/26 20:18:37
67 [ssh.c]
68 bz#2205: avoid early hostname lookups unless canonicalisation is enabled;
69 ok dtucker@ markus@
70 - djm@cvs.openbsd.org 2014/02/26 20:28:44
71 [auth2-gss.c gss-serv.c ssh-gss.h sshd.c]
72 bz#2107 - cache OIDs of supported GSSAPI mechanisms before privsep
73 sandboxing, as running this code in the sandbox can cause violations;
74 ok markus@
75 - djm@cvs.openbsd.org 2014/02/26 20:29:29
76 [channels.c]
77 don't assume that the socks4 username is \0 terminated;
78 spotted by Ben Hawkes; ok markus@
79 - markus@cvs.openbsd.org 2014/02/26 21:53:37
80 [sshd.c]
81 ssh_gssapi_prepare_supported_oids needs GSSAPI
82
8320140224
84 - OpenBSD CVS Sync
85 - djm@cvs.openbsd.org 2014/02/07 06:55:54
86 [cipher.c mac.c]
87 remove some logging that makes ssh debugging output very verbose;
88 ok markus
89 - djm@cvs.openbsd.org 2014/02/15 23:05:36
90 [channels.c]
91 avoid spurious "getsockname failed: Bad file descriptor" errors in ssh -W;
92 bz#2200, debian#738692 via Colin Watson; ok dtucker@
93 - djm@cvs.openbsd.org 2014/02/22 01:32:19
94 [readconf.c]
95 when processing Match blocks, skip 'exec' clauses if previous predicates
96 failed to match; ok markus@
97 - djm@cvs.openbsd.org 2014/02/23 20:03:42
98 [ssh-ed25519.c]
99 check for unsigned overflow; not reachable in OpenSSH but others might
100 copy our code...
101 - djm@cvs.openbsd.org 2014/02/23 20:11:36
102 [readconf.c readconf.h ssh.c ssh_config.5]
103 reparse ssh_config and ~/.ssh/config if hostname canonicalisation changes
104 the hostname. This allows users to write configurations that always
105 refer to canonical hostnames, e.g.
106
107 CanonicalizeHostname yes
108 CanonicalDomains int.example.org example.org
109 CanonicalizeFallbackLocal no
110
111 Host *.int.example.org
112 Compression off
113 Host *.example.org
114 User djm
115
116 ok markus@
117
11820140213
119 - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add compat
120 code for older OpenSSL versions that don't have EVP_MD_CTX_copy_ex.
121
12220140207
123 - OpenBSD CVS Sync
124 - naddy@cvs.openbsd.org 2014/02/05 20:13:25
125 [ssh-keygen.1 ssh-keygen.c]
126 tweak synopsis: calling ssh-keygen without any arguments is fine; ok jmc@
127 while here, fix ordering in usage(); requested by jmc@
128 - djm@cvs.openbsd.org 2014/02/06 22:21:01
129 [sshconnect.c]
130 in ssh_create_socket(), only do the getaddrinfo for BindAddress when
131 BindAddress is actually specified. Fixes regression in 6.5 for
132 UsePrivilegedPort=yes; patch from Corinna Vinschen
133
13420140206
135 - (dtucker) [openbsd-compat/bsd-poll.c] Don't bother checking for non-NULL
136 before freeing since free(NULL) is a no-op. ok djm.
137 - (djm) [sandbox-seccomp-filter.c] Not all Linux architectures define
138 __NR_shutdown; some go via the socketcall(2) multiplexer.
139
14020140205
141 - (djm) [sandbox-capsicum.c] Don't fatal if Capsicum is offered by
142 headers/libc but not supported by the kernel. Patch from Loganaden
143 Velvindron @ AfriNIC
144
14520140204
146 - OpenBSD CVS Sync
147 - markus@cvs.openbsd.org 2014/01/27 18:58:14
148 [Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h]
149 replace openssl HMAC with an implementation based on our ssh_digest_*
150 ok and feedback djm@
151 - markus@cvs.openbsd.org 2014/01/27 19:18:54
152 [auth-rsa.c cipher.c ssh-agent.c sshconnect1.c sshd.c]
153 replace openssl MD5 with our ssh_digest_*; ok djm@
154 - markus@cvs.openbsd.org 2014/01/27 20:13:46
155 [digest.c digest-openssl.c digest-libc.c Makefile.in]
156 rename digest.c to digest-openssl.c and add libc variant; ok djm@
157 - jmc@cvs.openbsd.org 2014/01/28 14:13:39
158 [ssh-keyscan.1]
159 kill some bad Pa;
160 From: Jan Stary
161 - djm@cvs.openbsd.org 2014/01/29 00:19:26
162 [sshd.c]
163 use kill(0, ...) instead of killpg(0, ...); on most operating systems
164 they are equivalent, but SUSv2 describes the latter as having undefined
165 behaviour; from portable; ok dtucker
166 (Id sync only; change is already in portable)
167 - djm@cvs.openbsd.org 2014/01/29 06:18:35
168 [Makefile.in auth.h auth2-jpake.c auth2.c jpake.c jpake.h monitor.c]
169 [monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h]
170 [schnorr.c schnorr.h servconf.c servconf.h ssh2.h sshconnect2.c]
171 remove experimental, never-enabled JPAKE code; ok markus@
172 - jmc@cvs.openbsd.org 2014/01/29 14:04:51
173 [sshd_config.5]
174 document kbdinteractiveauthentication;
175 requested From: Ross L Richardson
176
177 dtucker/markus helped explain its workings;
178 - djm@cvs.openbsd.org 2014/01/30 22:26:14
179 [sandbox-systrace.c]
180 allow shutdown(2) syscall in sandbox - it may be called by packet_close()
181 from portable
182 (Id sync only; change is already in portable)
183 - tedu@cvs.openbsd.org 2014/01/31 16:39:19
184 [auth2-chall.c authfd.c authfile.c bufaux.c bufec.c canohost.c]
185 [channels.c cipher-chachapoly.c clientloop.c configure.ac hostfile.c]
186 [kexc25519.c krl.c monitor.c sandbox-systrace.c session.c]
187 [sftp-client.c ssh-keygen.c ssh.c sshconnect2.c sshd.c sshlogin.c]
188 [openbsd-compat/explicit_bzero.c openbsd-compat/openbsd-compat.h]
189 replace most bzero with explicit_bzero, except a few that cna be memset
190 ok djm dtucker
191 - djm@cvs.openbsd.org 2014/02/02 03:44:32
192 [auth1.c auth2-chall.c auth2-passwd.c authfile.c bufaux.c bufbn.c]
193 [buffer.c cipher-3des1.c cipher.c clientloop.c gss-serv.c kex.c]
194 [kexdhc.c kexdhs.c kexecdhc.c kexgexc.c kexecdhs.c kexgexs.c key.c]
195 [monitor.c monitor_wrap.c packet.c readpass.c rsa.c serverloop.c]
196 [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c]
197 [ssh-keygen.c ssh-rsa.c sshconnect.c sshconnect1.c sshconnect2.c]
198 [sshd.c]
199 convert memset of potentially-private data to explicit_bzero()
200 - djm@cvs.openbsd.org 2014/02/03 23:28:00
201 [ssh-ecdsa.c]
202 fix memory leak; ECDSA_SIG_new() allocates 'r' and 's' for us, unlike
203 DSA_SIG_new. Reported by Batz Spear; ok markus@
204 - djm@cvs.openbsd.org 2014/02/02 03:44:31
205 [digest-libc.c digest-openssl.c]
206 convert memset of potentially-private data to explicit_bzero()
207 - djm@cvs.openbsd.org 2014/02/04 00:24:29
208 [ssh.c]
209 delay lowercasing of hostname until right before hostname
210 canonicalisation to unbreak case-sensitive matching of ssh_config;
211 reported by Ike Devolder; ok markus@
212 - (djm) [openbsd-compat/Makefile.in] Add missing explicit_bzero.o
213 - (djm) [regress/setuid-allowed.c] Missing string.h for strerror()
214
21520140131
216 - (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2)
217 syscall from sandboxes; it may be called by packet_close.
218 - (dtucker) [readconf.c] Include <arpa/inet.h> for the hton macros. Fixes
219 build with HP-UX's compiler. Patch from Kevin Brott.
220 - (tim) [Makefile.in] build regress/setuid-allow.
221
120140130 22220140130
2 - (djm) [configure.ac] Only check for width-specified integer types 223 - (djm) [configure.ac] Only check for width-specified integer types
3 in headers that actually exist. patch from Tom G. Christensen; 224 in headers that actually exist. patch from Tom G. Christensen;
@@ -2663,3 +2884,4 @@
2663 [contrib/suse/openssh.spec] Update for release 6.0 2884 [contrib/suse/openssh.spec] Update for release 6.0
2664 - (djm) [README] Update URL to release notes. 2885 - (djm) [README] Update URL to release notes.
2665 - (djm) Release openssh-6.0 2886 - (djm) Release openssh-6.0
2887
diff --git a/Makefile.in b/Makefile.in
index b7de26f2e..7d192bb7c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.352 2014/01/27 06:35:04 dtucker Exp $ 1# $Id: Makefile.in,v 1.356 2014/02/04 00:12:56 djm Exp $
2 2
3# uncomment if you run a non bourne compatable shell. Ie. csh 3# uncomment if you run a non bourne compatable shell. Ie. csh
4#SHELL = @SH@ 4#SHELL = @SH@
@@ -74,9 +74,9 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
74 kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ 74 kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
75 kexgssc.o \ 75 kexgssc.o \
76 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ 76 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
77 jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ 77 ssh-pkcs11.o krl.o smult_curve25519_ref.o \
78 kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ 78 kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
79 ssh-ed25519.o digest.o \ 79 ssh-ed25519.o digest-openssl.o hmac.o \
80 sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o 80 sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o
81 81
82SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 82SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
@@ -89,7 +89,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
89 auth.o auth1.o auth2.o auth-options.o session.o \ 89 auth.o auth1.o auth2.o auth-options.o session.o \
90 auth-chall.o auth2-chall.o groupaccess.o \ 90 auth-chall.o auth2-chall.o groupaccess.o \
91 auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ 91 auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
92 auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ 92 auth2-none.o auth2-passwd.o auth2-pubkey.o \
93 monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ 93 monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \
94 kexc25519s.o auth-krb5.o \ 94 kexc25519s.o auth-krb5.o \
95 auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ 95 auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \
@@ -411,7 +411,7 @@ regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c
411 $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ 411 $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \
412 $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) 412 $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
413 413
414tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) 414tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) regress/setuid-allowed$(EXEEXT)
415 BUILDDIR=`pwd`; \ 415 BUILDDIR=`pwd`; \
416 TEST_SHELL="@TEST_SHELL@"; \ 416 TEST_SHELL="@TEST_SHELL@"; \
417 TEST_SSH_SCP="$${BUILDDIR}/scp"; \ 417 TEST_SSH_SCP="$${BUILDDIR}/scp"; \
diff --git a/README b/README
index 8da9759ef..368dca59c 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
1See http://www.openssh.com/txt/release-6.5 for the release notes. 1See http://www.openssh.com/txt/release-6.6 for the release notes.
2 2
3- A Japanese translation of this document and of the OpenSSH FAQ is 3- A Japanese translation of this document and of the OpenSSH FAQ is
4- available at http://www.unixuser.org/~haruyama/security/openssh/index.html 4- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
@@ -62,4 +62,4 @@ References -
62[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 62[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
63[7] http://www.openssh.com/faq.html 63[7] http://www.openssh.com/faq.html
64 64
65$Id: README,v 1.85 2014/01/16 07:51:45 djm Exp $ 65$Id: README,v 1.86 2014/02/27 23:03:53 djm Exp $
diff --git a/auth-rsa.c b/auth-rsa.c
index 4624c1597..260ce2f98 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-rsa.c,v 1.85 2013/07/12 00:19:58 djm Exp $ */ 1/* $OpenBSD: auth-rsa.c,v 1.86 2014/01/27 19:18:54 markus 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
@@ -20,7 +20,6 @@
20#include <sys/stat.h> 20#include <sys/stat.h>
21 21
22#include <openssl/rsa.h> 22#include <openssl/rsa.h>
23#include <openssl/md5.h>
24 23
25#include <pwd.h> 24#include <pwd.h>
26#include <stdio.h> 25#include <stdio.h>
@@ -48,6 +47,8 @@
48#include "ssh.h" 47#include "ssh.h"
49#include "misc.h" 48#include "misc.h"
50 49
50#include "digest.h"
51
51/* import */ 52/* import */
52extern ServerOptions options; 53extern ServerOptions options;
53 54
@@ -91,12 +92,13 @@ int
91auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) 92auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
92{ 93{
93 u_char buf[32], mdbuf[16]; 94 u_char buf[32], mdbuf[16];
94 MD5_CTX md; 95 struct ssh_digest_ctx *md;
95 int len; 96 int len;
96 97
97 /* don't allow short keys */ 98 /* don't allow short keys */
98 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 99 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
99 error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits", 100 error("%s: RSA modulus too small: %d < minimum %d bits",
101 __func__,
100 BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); 102 BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
101 return (0); 103 return (0);
102 } 104 }
@@ -104,13 +106,15 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
104 /* The response is MD5 of decrypted challenge plus session id. */ 106 /* The response is MD5 of decrypted challenge plus session id. */
105 len = BN_num_bytes(challenge); 107 len = BN_num_bytes(challenge);
106 if (len <= 0 || len > 32) 108 if (len <= 0 || len > 32)
107 fatal("auth_rsa_verify_response: bad challenge length %d", len); 109 fatal("%s: bad challenge length %d", __func__, len);
108 memset(buf, 0, 32); 110 memset(buf, 0, 32);
109 BN_bn2bin(challenge, buf + 32 - len); 111 BN_bn2bin(challenge, buf + 32 - len);
110 MD5_Init(&md); 112 if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
111 MD5_Update(&md, buf, 32); 113 ssh_digest_update(md, buf, 32) < 0 ||
112 MD5_Update(&md, session_id, 16); 114 ssh_digest_update(md, session_id, 16) < 0 ||
113 MD5_Final(mdbuf, &md); 115 ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
116 fatal("%s: md5 failed", __func__);
117 ssh_digest_free(md);
114 118
115 /* Verify that the response is the original challenge. */ 119 /* Verify that the response is the original challenge. */
116 if (timingsafe_bcmp(response, mdbuf, 16) != 0) { 120 if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
diff --git a/auth.h b/auth.h
index 5b6824f71..79e4ea53a 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.h,v 1.76 2013/07/19 07:37:48 markus Exp $ */ 1/* $OpenBSD: auth.h,v 1.77 2014/01/29 06:18:35 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -62,7 +62,6 @@ struct Authctxt {
62 char *role; 62 char *role;
63 void *kbdintctxt; 63 void *kbdintctxt;
64 char *info; /* Extra info for next auth_log */ 64 char *info; /* Extra info for next auth_log */
65 void *jpake_ctx;
66#ifdef BSD_AUTH 65#ifdef BSD_AUTH
67 auth_session_t *as; 66 auth_session_t *as;
68#endif 67#endif
@@ -176,9 +175,6 @@ int bsdauth_respond(void *, u_int, char **);
176int skey_query(void *, char **, char **, u_int *, char ***, u_int **); 175int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
177int skey_respond(void *, u_int, char **); 176int skey_respond(void *, u_int, char **);
178 177
179void auth2_jpake_get_pwdata(Authctxt *, BIGNUM **, char **, char **);
180void auth2_jpake_stop(Authctxt *);
181
182int allowed_user(struct passwd *); 178int allowed_user(struct passwd *);
183struct passwd * getpwnamallow(const char *user); 179struct passwd * getpwnamallow(const char *user);
184 180
diff --git a/auth1.c b/auth1.c
index 2803a3c97..c70739080 100644
--- a/auth1.c
+++ b/auth1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth1.c,v 1.79 2013/05/19 02:42:42 djm Exp $ */ 1/* $OpenBSD: auth1.c,v 1.80 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -129,7 +129,7 @@ auth1_process_password(Authctxt *authctxt)
129 /* Try authentication with the password. */ 129 /* Try authentication with the password. */
130 authenticated = PRIVSEP(auth_password(authctxt, password)); 130 authenticated = PRIVSEP(auth_password(authctxt, password));
131 131
132 memset(password, 0, dlen); 132 explicit_bzero(password, dlen);
133 free(password); 133 free(password);
134 134
135 return (authenticated); 135 return (authenticated);
@@ -222,7 +222,7 @@ auth1_process_tis_response(Authctxt *authctxt)
222 response = packet_get_string(&dlen); 222 response = packet_get_string(&dlen);
223 packet_check_eom(); 223 packet_check_eom();
224 authenticated = verify_response(authctxt, response); 224 authenticated = verify_response(authctxt, response);
225 memset(response, 'r', dlen); 225 explicit_bzero(response, dlen);
226 free(response); 226 free(response);
227 227
228 return (authenticated); 228 return (authenticated);
diff --git a/auth2-chall.c b/auth2-chall.c
index 031c2828c..980250a91 100644
--- a/auth2-chall.c
+++ b/auth2-chall.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-chall.c,v 1.39 2013/11/08 00:39:14 djm Exp $ */ 1/* $OpenBSD: auth2-chall.c,v 1.41 2014/02/02 03:44:31 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) 2001 Per Allansson. All rights reserved. 4 * Copyright (c) 2001 Per Allansson. All rights reserved.
@@ -148,7 +148,7 @@ kbdint_free(KbdintAuthctxt *kbdintctxt)
148 if (kbdintctxt->device) 148 if (kbdintctxt->device)
149 kbdint_reset_device(kbdintctxt); 149 kbdint_reset_device(kbdintctxt);
150 free(kbdintctxt->devices); 150 free(kbdintctxt->devices);
151 bzero(kbdintctxt, sizeof(*kbdintctxt)); 151 explicit_bzero(kbdintctxt, sizeof(*kbdintctxt));
152 free(kbdintctxt); 152 free(kbdintctxt);
153} 153}
154/* get next device */ 154/* get next device */
@@ -312,7 +312,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
312 res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response); 312 res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
313 313
314 for (i = 0; i < nresp; i++) { 314 for (i = 0; i < nresp; i++) {
315 memset(response[i], 'r', strlen(response[i])); 315 explicit_bzero(response[i], strlen(response[i]));
316 free(response[i]); 316 free(response[i]);
317 } 317 }
318 free(response); 318 free(response);
diff --git a/auth2-gss.c b/auth2-gss.c
index b8db8204f..3ff2d726b 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-gss.c,v 1.20 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: auth2-gss.c,v 1.21 2014/02/26 20:28:44 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
@@ -96,7 +96,6 @@ userauth_gssapi(Authctxt *authctxt)
96 gss_OID_desc goid = {0, NULL}; 96 gss_OID_desc goid = {0, NULL};
97 Gssctxt *ctxt = NULL; 97 Gssctxt *ctxt = NULL;
98 int mechs; 98 int mechs;
99 gss_OID_set supported;
100 int present; 99 int present;
101 OM_uint32 ms; 100 OM_uint32 ms;
102 u_int len; 101 u_int len;
@@ -111,7 +110,6 @@ userauth_gssapi(Authctxt *authctxt)
111 return (0); 110 return (0);
112 } 111 }
113 112
114 ssh_gssapi_supported_oids(&supported);
115 do { 113 do {
116 mechs--; 114 mechs--;
117 115
@@ -124,15 +122,12 @@ userauth_gssapi(Authctxt *authctxt)
124 doid[1] == len - 2) { 122 doid[1] == len - 2) {
125 goid.elements = doid + 2; 123 goid.elements = doid + 2;
126 goid.length = len - 2; 124 goid.length = len - 2;
127 gss_test_oid_set_member(&ms, &goid, supported, 125 ssh_gssapi_test_oid_supported(&ms, &goid, &present);
128 &present);
129 } else { 126 } else {
130 logit("Badly formed OID received"); 127 logit("Badly formed OID received");
131 } 128 }
132 } while (mechs > 0 && !present); 129 } while (mechs > 0 && !present);
133 130
134 gss_release_oid_set(&ms, &supported);
135
136 if (!present) { 131 if (!present) {
137 free(doid); 132 free(doid);
138 authctxt->server_caused_failure = 1; 133 authctxt->server_caused_failure = 1;
diff --git a/auth2-jpake.c b/auth2-jpake.c
deleted file mode 100644
index 78a6b8817..000000000
--- a/auth2-jpake.c
+++ /dev/null
@@ -1,563 +0,0 @@
1/* $OpenBSD: auth2-jpake.c,v 1.6 2013/05/17 00:13:13 djm Exp $ */
2/*
3 * Copyright (c) 2008 Damien Miller. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/*
19 * Server side of zero-knowledge password auth using J-PAKE protocol
20 * as described in:
21 *
22 * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling",
23 * 16th Workshop on Security Protocols, Cambridge, April 2008
24 *
25 * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
26 */
27
28#ifdef JPAKE
29
30#include <sys/types.h>
31#include <sys/param.h>
32
33#include <pwd.h>
34#include <stdio.h>
35#include <string.h>
36#include <login_cap.h>
37
38#include <openssl/bn.h>
39#include <openssl/evp.h>
40
41#include "xmalloc.h"
42#include "ssh2.h"
43#include "key.h"
44#include "hostfile.h"
45#include "auth.h"
46#include "buffer.h"
47#include "packet.h"
48#include "dispatch.h"
49#include "log.h"
50#include "servconf.h"
51#include "auth-options.h"
52#include "canohost.h"
53#ifdef GSSAPI
54#include "ssh-gss.h"
55#endif
56#include "monitor_wrap.h"
57
58#include "schnorr.h"
59#include "jpake.h"
60
61/*
62 * XXX options->permit_empty_passwd (at the moment, they will be refused
63 * anyway because they will mismatch on fake salt.
64 */
65
66/* Dispatch handlers */
67static void input_userauth_jpake_client_step1(int, u_int32_t, void *);
68static void input_userauth_jpake_client_step2(int, u_int32_t, void *);
69static void input_userauth_jpake_client_confirm(int, u_int32_t, void *);
70
71static int auth2_jpake_start(Authctxt *);
72
73/* import */
74extern ServerOptions options;
75extern u_char *session_id2;
76extern u_int session_id2_len;
77
78/*
79 * Attempt J-PAKE authentication.
80 */
81static int
82userauth_jpake(Authctxt *authctxt)
83{
84 int authenticated = 0;
85
86 packet_check_eom();
87
88 debug("jpake-01@openssh.com requested");
89
90 if (authctxt->user != NULL) {
91 if (authctxt->jpake_ctx == NULL)
92 authctxt->jpake_ctx = jpake_new();
93 if (options.zero_knowledge_password_authentication)
94 authenticated = auth2_jpake_start(authctxt);
95 }
96
97 return authenticated;
98}
99
100Authmethod method_jpake = {
101 "jpake-01@openssh.com",
102 userauth_jpake,
103 &options.zero_knowledge_password_authentication
104};
105
106/* Clear context and callbacks */
107void
108auth2_jpake_stop(Authctxt *authctxt)
109{
110 /* unregister callbacks */
111 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL);
112 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL);
113 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL);
114 if (authctxt->jpake_ctx != NULL) {
115 jpake_free(authctxt->jpake_ctx);
116 authctxt->jpake_ctx = NULL;
117 }
118}
119
120/* Returns 1 if 'c' is a valid crypt(3) salt character, 0 otherwise */
121static int
122valid_crypt_salt(int c)
123{
124 if (c >= 'A' && c <= 'Z')
125 return 1;
126 if (c >= 'a' && c <= 'z')
127 return 1;
128 if (c >= '.' && c <= '9')
129 return 1;
130 return 0;
131}
132
133/*
134 * Derive fake salt as H(username || first_private_host_key)
135 * This provides relatively stable fake salts for non-existent
136 * users and avoids the jpake method becoming an account validity
137 * oracle.
138 */
139static void
140derive_rawsalt(const char *username, u_char *rawsalt, u_int len)
141{
142 u_char *digest;
143 u_int digest_len;
144 Buffer b;
145 Key *k;
146
147 buffer_init(&b);
148 buffer_put_cstring(&b, username);
149 if ((k = get_hostkey_by_index(0)) == NULL ||
150 (k->flags & KEY_FLAG_EXT))
151 fatal("%s: no hostkeys", __func__);
152 switch (k->type) {
153 case KEY_RSA1:
154 case KEY_RSA:
155 if (k->rsa->p == NULL || k->rsa->q == NULL)
156 fatal("%s: RSA key missing p and/or q", __func__);
157 buffer_put_bignum2(&b, k->rsa->p);
158 buffer_put_bignum2(&b, k->rsa->q);
159 break;
160 case KEY_DSA:
161 if (k->dsa->priv_key == NULL)
162 fatal("%s: DSA key missing priv_key", __func__);
163 buffer_put_bignum2(&b, k->dsa->priv_key);
164 break;
165 case KEY_ECDSA:
166 if (EC_KEY_get0_private_key(k->ecdsa) == NULL)
167 fatal("%s: ECDSA key missing priv_key", __func__);
168 buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa));
169 break;
170 default:
171 fatal("%s: unknown key type %d", __func__, k->type);
172 }
173 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
174 &digest, &digest_len) != 0)
175 fatal("%s: hash_buffer", __func__);
176 buffer_free(&b);
177 if (len > digest_len)
178 fatal("%s: not enough bytes for rawsalt (want %u have %u)",
179 __func__, len, digest_len);
180 memcpy(rawsalt, digest, len);
181 bzero(digest, digest_len);
182 free(digest);
183}
184
185/* ASCII an integer [0, 64) for inclusion in a password/salt */
186static char
187pw_encode64(u_int i64)
188{
189 const u_char e64[] =
190 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
191 return e64[i64 % 64];
192}
193
194/* Generate ASCII salt bytes for user */
195static char *
196makesalt(u_int want, const char *user)
197{
198 u_char rawsalt[32];
199 static char ret[33];
200 u_int i;
201
202 if (want > sizeof(ret) - 1)
203 fatal("%s: want %u", __func__, want);
204
205 derive_rawsalt(user, rawsalt, sizeof(rawsalt));
206 bzero(ret, sizeof(ret));
207 for (i = 0; i < want; i++)
208 ret[i] = pw_encode64(rawsalt[i]);
209 bzero(rawsalt, sizeof(rawsalt));
210
211 return ret;
212}
213
214/*
215 * Select the system's default password hashing scheme and generate
216 * a stable fake salt under it for use by a non-existent account.
217 * Prevents jpake method being used to infer the validity of accounts.
218 */
219static void
220fake_salt_and_scheme(Authctxt *authctxt, char **salt, char **scheme)
221{
222 char *rounds_s, *style;
223 long long rounds;
224 login_cap_t *lc;
225
226
227 if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL &&
228 (lc = login_getclass(NULL)) == NULL)
229 fatal("%s: login_getclass failed", __func__);
230 style = login_getcapstr(lc, "localcipher", NULL, NULL);
231 if (style == NULL)
232 style = xstrdup("blowfish,6");
233 login_close(lc);
234
235 if ((rounds_s = strchr(style, ',')) != NULL)
236 *rounds_s++ = '\0';
237 rounds = strtonum(rounds_s, 1, 1<<31, NULL);
238
239 if (strcmp(style, "md5") == 0) {
240 xasprintf(salt, "$1$%s$", makesalt(8, authctxt->user));
241 *scheme = xstrdup("md5");
242 } else if (strcmp(style, "old") == 0) {
243 *salt = xstrdup(makesalt(2, authctxt->user));
244 *scheme = xstrdup("crypt");
245 } else if (strcmp(style, "newsalt") == 0) {
246 rounds = MAX(rounds, 7250);
247 rounds = MIN(rounds, (1<<24) - 1);
248 xasprintf(salt, "_%c%c%c%c%s",
249 pw_encode64(rounds), pw_encode64(rounds >> 6),
250 pw_encode64(rounds >> 12), pw_encode64(rounds >> 18),
251 makesalt(4, authctxt->user));
252 *scheme = xstrdup("crypt-extended");
253 } else {
254 /* Default to blowfish */
255 rounds = MAX(rounds, 3);
256 rounds = MIN(rounds, 31);
257 xasprintf(salt, "$2a$%02lld$%s", rounds,
258 makesalt(22, authctxt->user));
259 *scheme = xstrdup("bcrypt");
260 }
261 free(style);
262 debug3("%s: fake %s salt for user %s: %s",
263 __func__, *scheme, authctxt->user, *salt);
264}
265
266/*
267 * Fetch password hashing scheme, password salt and derive shared secret
268 * for user. If user does not exist, a fake but stable and user-unique
269 * salt will be returned.
270 */
271void
272auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
273 char **hash_scheme, char **salt)
274{
275 char *cp;
276 u_char *secret;
277 u_int secret_len, salt_len;
278
279#ifdef JPAKE_DEBUG
280 debug3("%s: valid %d pw %.5s...", __func__,
281 authctxt->valid, authctxt->pw->pw_passwd);
282#endif
283
284 *salt = NULL;
285 *hash_scheme = NULL;
286 if (authctxt->valid) {
287 if (strncmp(authctxt->pw->pw_passwd, "$2$", 3) == 0 &&
288 strlen(authctxt->pw->pw_passwd) > 28) {
289 /*
290 * old-variant bcrypt:
291 * "$2$", 2 digit rounds, "$", 22 bytes salt
292 */
293 salt_len = 3 + 2 + 1 + 22 + 1;
294 *salt = xmalloc(salt_len);
295 strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
296 *hash_scheme = xstrdup("bcrypt");
297 } else if (strncmp(authctxt->pw->pw_passwd, "$2a$", 4) == 0 &&
298 strlen(authctxt->pw->pw_passwd) > 29) {
299 /*
300 * current-variant bcrypt:
301 * "$2a$", 2 digit rounds, "$", 22 bytes salt
302 */
303 salt_len = 4 + 2 + 1 + 22 + 1;
304 *salt = xmalloc(salt_len);
305 strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
306 *hash_scheme = xstrdup("bcrypt");
307 } else if (strncmp(authctxt->pw->pw_passwd, "$1$", 3) == 0 &&
308 strlen(authctxt->pw->pw_passwd) > 5) {
309 /*
310 * md5crypt:
311 * "$1$", salt until "$"
312 */
313 cp = strchr(authctxt->pw->pw_passwd + 3, '$');
314 if (cp != NULL) {
315 salt_len = (cp - authctxt->pw->pw_passwd) + 1;
316 *salt = xmalloc(salt_len);
317 strlcpy(*salt, authctxt->pw->pw_passwd,
318 salt_len);
319 *hash_scheme = xstrdup("md5crypt");
320 }
321 } else if (strncmp(authctxt->pw->pw_passwd, "_", 1) == 0 &&
322 strlen(authctxt->pw->pw_passwd) > 9) {
323 /*
324 * BSDI extended crypt:
325 * "_", 4 digits count, 4 chars salt
326 */
327 salt_len = 1 + 4 + 4 + 1;
328 *salt = xmalloc(salt_len);
329 strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
330 *hash_scheme = xstrdup("crypt-extended");
331 } else if (strlen(authctxt->pw->pw_passwd) == 13 &&
332 valid_crypt_salt(authctxt->pw->pw_passwd[0]) &&
333 valid_crypt_salt(authctxt->pw->pw_passwd[1])) {
334 /*
335 * traditional crypt:
336 * 2 chars salt
337 */
338 salt_len = 2 + 1;
339 *salt = xmalloc(salt_len);
340 strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
341 *hash_scheme = xstrdup("crypt");
342 }
343 if (*salt == NULL) {
344 debug("%s: unrecognised crypt scheme for user %s",
345 __func__, authctxt->pw->pw_name);
346 }
347 }
348 if (*salt == NULL)
349 fake_salt_and_scheme(authctxt, salt, hash_scheme);
350
351 if (hash_buffer(authctxt->pw->pw_passwd,
352 strlen(authctxt->pw->pw_passwd), EVP_sha256(),
353 &secret, &secret_len) != 0)
354 fatal("%s: hash_buffer", __func__);
355 if ((*s = BN_bin2bn(secret, secret_len, NULL)) == NULL)
356 fatal("%s: BN_bin2bn (secret)", __func__);
357#ifdef JPAKE_DEBUG
358 debug3("%s: salt = %s (len %u)", __func__,
359 *salt, (u_int)strlen(*salt));
360 debug3("%s: scheme = %s", __func__, *hash_scheme);
361 JPAKE_DEBUG_BN((*s, "%s: s = ", __func__));
362#endif
363 bzero(secret, secret_len);
364 free(secret);
365}
366
367/*
368 * Begin authentication attempt.
369 * Note, sets authctxt->postponed while in subprotocol
370 */
371static int
372auth2_jpake_start(Authctxt *authctxt)
373{
374 struct jpake_ctx *pctx = authctxt->jpake_ctx;
375 u_char *x3_proof, *x4_proof;
376 u_int x3_proof_len, x4_proof_len;
377 char *salt, *hash_scheme;
378
379 debug("%s: start", __func__);
380
381 PRIVSEP(jpake_step1(pctx->grp,
382 &pctx->server_id, &pctx->server_id_len,
383 &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4,
384 &x3_proof, &x3_proof_len,
385 &x4_proof, &x4_proof_len));
386
387 PRIVSEP(auth2_jpake_get_pwdata(authctxt, &pctx->s,
388 &hash_scheme, &salt));
389
390 if (!use_privsep)
391 JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));
392
393 packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1);
394 packet_put_cstring(hash_scheme);
395 packet_put_cstring(salt);
396 packet_put_string(pctx->server_id, pctx->server_id_len);
397 packet_put_bignum2(pctx->g_x3);
398 packet_put_bignum2(pctx->g_x4);
399 packet_put_string(x3_proof, x3_proof_len);
400 packet_put_string(x4_proof, x4_proof_len);
401 packet_send();
402 packet_write_wait();
403
404 bzero(hash_scheme, strlen(hash_scheme));
405 bzero(salt, strlen(salt));
406 free(hash_scheme);
407 free(salt);
408 bzero(x3_proof, x3_proof_len);
409 bzero(x4_proof, x4_proof_len);
410 free(x3_proof);
411 free(x4_proof);
412
413 /* Expect step 1 packet from peer */
414 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1,
415 input_userauth_jpake_client_step1);
416
417 authctxt->postponed = 1;
418 return 0;
419}
420
421/* ARGSUSED */
422static void
423input_userauth_jpake_client_step1(int type, u_int32_t seq, void *ctxt)
424{
425 Authctxt *authctxt = ctxt;
426 struct jpake_ctx *pctx = authctxt->jpake_ctx;
427 u_char *x1_proof, *x2_proof, *x4_s_proof;
428 u_int x1_proof_len, x2_proof_len, x4_s_proof_len;
429
430 /* Disable this message */
431 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL);
432
433 /* Fetch step 1 values */
434 if ((pctx->g_x1 = BN_new()) == NULL ||
435 (pctx->g_x2 = BN_new()) == NULL)
436 fatal("%s: BN_new", __func__);
437 pctx->client_id = packet_get_string(&pctx->client_id_len);
438 packet_get_bignum2(pctx->g_x1);
439 packet_get_bignum2(pctx->g_x2);
440 x1_proof = packet_get_string(&x1_proof_len);
441 x2_proof = packet_get_string(&x2_proof_len);
442 packet_check_eom();
443
444 if (!use_privsep)
445 JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));
446
447 PRIVSEP(jpake_step2(pctx->grp, pctx->s, pctx->g_x3,
448 pctx->g_x1, pctx->g_x2, pctx->x4,
449 pctx->client_id, pctx->client_id_len,
450 pctx->server_id, pctx->server_id_len,
451 x1_proof, x1_proof_len,
452 x2_proof, x2_proof_len,
453 &pctx->b,
454 &x4_s_proof, &x4_s_proof_len));
455
456 bzero(x1_proof, x1_proof_len);
457 bzero(x2_proof, x2_proof_len);
458 free(x1_proof);
459 free(x2_proof);
460
461 if (!use_privsep)
462 JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));
463
464 /* Send values for step 2 */
465 packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2);
466 packet_put_bignum2(pctx->b);
467 packet_put_string(x4_s_proof, x4_s_proof_len);
468 packet_send();
469 packet_write_wait();
470
471 bzero(x4_s_proof, x4_s_proof_len);
472 free(x4_s_proof);
473
474 /* Expect step 2 packet from peer */
475 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2,
476 input_userauth_jpake_client_step2);
477}
478
479/* ARGSUSED */
480static void
481input_userauth_jpake_client_step2(int type, u_int32_t seq, void *ctxt)
482{
483 Authctxt *authctxt = ctxt;
484 struct jpake_ctx *pctx = authctxt->jpake_ctx;
485 u_char *x2_s_proof;
486 u_int x2_s_proof_len;
487
488 /* Disable this message */
489 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL);
490
491 if ((pctx->a = BN_new()) == NULL)
492 fatal("%s: BN_new", __func__);
493
494 /* Fetch step 2 values */
495 packet_get_bignum2(pctx->a);
496 x2_s_proof = packet_get_string(&x2_s_proof_len);
497 packet_check_eom();
498
499 if (!use_privsep)
500 JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));
501
502 /* Derive shared key and calculate confirmation hash */
503 PRIVSEP(jpake_key_confirm(pctx->grp, pctx->s, pctx->a,
504 pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2,
505 pctx->server_id, pctx->server_id_len,
506 pctx->client_id, pctx->client_id_len,
507 session_id2, session_id2_len,
508 x2_s_proof, x2_s_proof_len,
509 &pctx->k,
510 &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len));
511
512 bzero(x2_s_proof, x2_s_proof_len);
513 free(x2_s_proof);
514
515 if (!use_privsep)
516 JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));
517
518 /* Send key confirmation proof */
519 packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM);
520 packet_put_string(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
521 packet_send();
522 packet_write_wait();
523
524 /* Expect confirmation from peer */
525 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM,
526 input_userauth_jpake_client_confirm);
527}
528
529/* ARGSUSED */
530static void
531input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt)
532{
533 Authctxt *authctxt = ctxt;
534 struct jpake_ctx *pctx = authctxt->jpake_ctx;
535 int authenticated = 0;
536
537 /* Disable this message */
538 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL);
539
540 pctx->h_k_cid_sessid = packet_get_string(&pctx->h_k_cid_sessid_len);
541 packet_check_eom();
542
543 if (!use_privsep)
544 JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));
545
546 /* Verify expected confirmation hash */
547 if (PRIVSEP(jpake_check_confirm(pctx->k,
548 pctx->client_id, pctx->client_id_len,
549 session_id2, session_id2_len,
550 pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len)) == 1)
551 authenticated = authctxt->valid ? 1 : 0;
552 else
553 debug("%s: confirmation mismatch", __func__);
554
555 /* done */
556 authctxt->postponed = 0;
557 jpake_free(authctxt->jpake_ctx);
558 authctxt->jpake_ctx = NULL;
559 userauth_finish(authctxt, authenticated, method_jpake.name, NULL);
560}
561
562#endif /* JPAKE */
563
diff --git a/auth2-passwd.c b/auth2-passwd.c
index 21bc5047d..707680cd0 100644
--- a/auth2-passwd.c
+++ b/auth2-passwd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-passwd.c,v 1.10 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: auth2-passwd.c,v 1.11 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -59,7 +59,7 @@ userauth_passwd(Authctxt *authctxt)
59 if (change) { 59 if (change) {
60 /* discard new password from packet */ 60 /* discard new password from packet */
61 newpass = packet_get_string(&newlen); 61 newpass = packet_get_string(&newlen);
62 memset(newpass, 0, newlen); 62 explicit_bzero(newpass, newlen);
63 free(newpass); 63 free(newpass);
64 } 64 }
65 packet_check_eom(); 65 packet_check_eom();
@@ -68,7 +68,7 @@ userauth_passwd(Authctxt *authctxt)
68 logit("password change not supported"); 68 logit("password change not supported");
69 else if (PRIVSEP(auth_password(authctxt, password)) == 1) 69 else if (PRIVSEP(auth_password(authctxt, password)) == 1)
70 authenticated = 1; 70 authenticated = 1;
71 memset(password, 0, len); 71 explicit_bzero(password, len);
72 free(password); 72 free(password);
73 return authenticated; 73 return authenticated;
74} 74}
diff --git a/auth2.c b/auth2.c
index b55bbcd95..70f29250d 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.129 2013/05/19 02:42:42 djm Exp $ */ 1/* $OpenBSD: auth2.c,v 1.130 2014/01/29 06:18:35 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -72,9 +72,6 @@ extern Authmethod method_hostbased;
72extern Authmethod method_gsskeyex; 72extern Authmethod method_gsskeyex;
73extern Authmethod method_gssapi; 73extern Authmethod method_gssapi;
74#endif 74#endif
75#ifdef JPAKE
76extern Authmethod method_jpake;
77#endif
78 75
79Authmethod *authmethods[] = { 76Authmethod *authmethods[] = {
80 &method_none, 77 &method_none,
@@ -83,9 +80,6 @@ Authmethod *authmethods[] = {
83 &method_gsskeyex, 80 &method_gsskeyex,
84 &method_gssapi, 81 &method_gssapi,
85#endif 82#endif
86#ifdef JPAKE
87 &method_jpake,
88#endif
89 &method_passwd, 83 &method_passwd,
90 &method_kbdint, 84 &method_kbdint,
91 &method_hostbased, 85 &method_hostbased,
@@ -278,9 +272,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
278 } 272 }
279 /* reset state */ 273 /* reset state */
280 auth2_challenge_stop(authctxt); 274 auth2_challenge_stop(authctxt);
281#ifdef JPAKE
282 auth2_jpake_stop(authctxt);
283#endif
284 275
285#ifdef GSSAPI 276#ifdef GSSAPI
286 /* XXX move to auth2_gssapi_stop() */ 277 /* XXX move to auth2_gssapi_stop() */
diff --git a/authfd.c b/authfd.c
index f9636903a..cea3f97b4 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfd.c,v 1.91 2013/12/29 04:29:25 djm Exp $ */ 1/* $OpenBSD: authfd.c,v 1.92 2014/01/31 16:39:19 tedu 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
@@ -102,7 +102,7 @@ ssh_get_authentication_socket(void)
102 if (!authsocket) 102 if (!authsocket)
103 return -1; 103 return -1;
104 104
105 bzero(&sunaddr, sizeof(sunaddr)); 105 memset(&sunaddr, 0, sizeof(sunaddr));
106 sunaddr.sun_family = AF_UNIX; 106 sunaddr.sun_family = AF_UNIX;
107 strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); 107 strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
108 108
diff --git a/authfile.c b/authfile.c
index 7eccbb2c9..d7eaa9dec 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.101 2013/12/29 04:35:50 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.103 2014/02/02 03:44:31 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
@@ -131,7 +131,7 @@ key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
131 buffer_put_int(&kdf, rounds); 131 buffer_put_int(&kdf, rounds);
132 } 132 }
133 cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1); 133 cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1);
134 memset(key, 0, keylen + ivlen); 134 explicit_bzero(key, keylen + ivlen);
135 free(key); 135 free(key);
136 136
137 buffer_init(&encoded); 137 buffer_init(&encoded);
@@ -143,7 +143,7 @@ key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
143 key_to_blob(prv, &cp, &len); /* public key */ 143 key_to_blob(prv, &cp, &len); /* public key */
144 buffer_put_string(&encoded, cp, len); 144 buffer_put_string(&encoded, cp, len);
145 145
146 memset(cp, 0, len); 146 explicit_bzero(cp, len);
147 free(cp); 147 free(cp);
148 148
149 buffer_free(&kdf); 149 buffer_free(&kdf);
@@ -409,7 +409,7 @@ key_parse_private2(Buffer *blob, int type, const char *passphrase,
409 free(salt); 409 free(salt);
410 free(comment); 410 free(comment);
411 if (key) 411 if (key)
412 memset(key, 0, keylen + ivlen); 412 explicit_bzero(key, keylen + ivlen);
413 free(key); 413 free(key);
414 buffer_free(&encoded); 414 buffer_free(&encoded);
415 buffer_free(&copy); 415 buffer_free(&copy);
@@ -496,10 +496,10 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
496 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0) 496 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0)
497 fatal("%s: cipher_crypt failed", __func__); 497 fatal("%s: cipher_crypt failed", __func__);
498 cipher_cleanup(&ciphercontext); 498 cipher_cleanup(&ciphercontext);
499 memset(&ciphercontext, 0, sizeof(ciphercontext)); 499 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
500 500
501 /* Destroy temporary data. */ 501 /* Destroy temporary data. */
502 memset(buf, 0, sizeof(buf)); 502 explicit_bzero(buf, sizeof(buf));
503 buffer_free(&buffer); 503 buffer_free(&buffer);
504 504
505 buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted)); 505 buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
@@ -703,17 +703,17 @@ key_load_file(int fd, const char *filename, Buffer *blob)
703 __func__, filename == NULL ? "" : filename, 703 __func__, filename == NULL ? "" : filename,
704 filename == NULL ? "" : " ", strerror(errno)); 704 filename == NULL ? "" : " ", strerror(errno));
705 buffer_clear(blob); 705 buffer_clear(blob);
706 bzero(buf, sizeof(buf)); 706 explicit_bzero(buf, sizeof(buf));
707 return 0; 707 return 0;
708 } 708 }
709 buffer_append(blob, buf, len); 709 buffer_append(blob, buf, len);
710 if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { 710 if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
711 buffer_clear(blob); 711 buffer_clear(blob);
712 bzero(buf, sizeof(buf)); 712 explicit_bzero(buf, sizeof(buf));
713 goto toobig; 713 goto toobig;
714 } 714 }
715 } 715 }
716 bzero(buf, sizeof(buf)); 716 explicit_bzero(buf, sizeof(buf));
717 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 717 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
718 st.st_size != buffer_len(blob)) { 718 st.st_size != buffer_len(blob)) {
719 debug("%s: key file %.200s%schanged size while reading", 719 debug("%s: key file %.200s%schanged size while reading",
@@ -831,7 +831,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
831 buffer_ptr(&copy), buffer_len(&copy), 0, 0) != 0) 831 buffer_ptr(&copy), buffer_len(&copy), 0, 0) != 0)
832 fatal("%s: cipher_crypt failed", __func__); 832 fatal("%s: cipher_crypt failed", __func__);
833 cipher_cleanup(&ciphercontext); 833 cipher_cleanup(&ciphercontext);
834 memset(&ciphercontext, 0, sizeof(ciphercontext)); 834 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
835 buffer_free(&copy); 835 buffer_free(&copy);
836 836
837 check1 = buffer_get_char(&decrypted); 837 check1 = buffer_get_char(&decrypted);
diff --git a/bufaux.c b/bufaux.c
index 9401fe1d0..e24b5fc0a 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bufaux.c,v 1.54 2014/01/12 08:13:13 djm Exp $ */ 1/* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 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
@@ -216,7 +216,7 @@ buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
216 if (cp == ret + length - 1) 216 if (cp == ret + length - 1)
217 error("buffer_get_cstring_ret: string contains \\0"); 217 error("buffer_get_cstring_ret: string contains \\0");
218 else { 218 else {
219 bzero(ret, length); 219 explicit_bzero(ret, length);
220 free(ret); 220 free(ret);
221 return NULL; 221 return NULL;
222 } 222 }
@@ -346,7 +346,7 @@ buffer_get_bignum2_as_string_ret(Buffer *buffer, u_int *length_ptr)
346 } 346 }
347 ret = xmalloc(len); 347 ret = xmalloc(len);
348 memcpy(ret, p, len); 348 memcpy(ret, p, len);
349 memset(p, '\0', len); 349 explicit_bzero(p, len);
350 free(bin); 350 free(bin);
351 return ret; 351 return ret;
352} 352}
@@ -383,7 +383,7 @@ buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l)
383 } 383 }
384 memcpy(p, s, l); 384 memcpy(p, s, l);
385 buffer_put_string(buffer, buf, l + pad); 385 buffer_put_string(buffer, buf, l + pad);
386 memset(buf, '\0', l + pad); 386 explicit_bzero(buf, l + pad);
387 free(buf); 387 free(buf);
388} 388}
389 389
diff --git a/bufbn.c b/bufbn.c
index 2ebc80a27..1d2e01266 100644
--- a/bufbn.c
+++ b/bufbn.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bufbn.c,v 1.8 2013/11/08 11:15:19 dtucker Exp $*/ 1/* $OpenBSD: bufbn.c,v 1.11 2014/02/27 08:25:09 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
@@ -80,7 +80,7 @@ buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
80 /* Store the binary data. */ 80 /* Store the binary data. */
81 buffer_append(buffer, buf, oi); 81 buffer_append(buffer, buf, oi);
82 82
83 memset(buf, 0, bin_size); 83 explicit_bzero(buf, bin_size);
84 free(buf); 84 free(buf);
85 85
86 return (0); 86 return (0);
@@ -108,6 +108,11 @@ buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
108 return (-1); 108 return (-1);
109 } 109 }
110 bits = get_u16(buf); 110 bits = get_u16(buf);
111 if (bits > 65535-7) {
112 error("buffer_get_bignum_ret: cannot handle BN of size %d",
113 bits);
114 return (-1);
115 }
111 /* Compute the number of binary bytes that follow. */ 116 /* Compute the number of binary bytes that follow. */
112 bytes = (bits + 7) / 8; 117 bytes = (bits + 7) / 8;
113 if (bytes > 8 * 1024) { 118 if (bytes > 8 * 1024) {
@@ -173,7 +178,7 @@ buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
173 } 178 }
174 hasnohigh = (buf[1] & 0x80) ? 0 : 1; 179 hasnohigh = (buf[1] & 0x80) ? 0 : 1;
175 buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); 180 buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
176 memset(buf, 0, bytes); 181 explicit_bzero(buf, bytes);
177 free(buf); 182 free(buf);
178 return (0); 183 return (0);
179} 184}
diff --git a/bufec.c b/bufec.c
index 6c0048978..89482b906 100644
--- a/bufec.c
+++ b/bufec.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bufec.c,v 1.2 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: bufec.c,v 1.3 2014/01/31 16:39:19 tedu Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2010 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -77,7 +77,7 @@ buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
77 ret = 0; 77 ret = 0;
78 out: 78 out:
79 if (buf != NULL) { 79 if (buf != NULL) {
80 bzero(buf, len); 80 explicit_bzero(buf, len);
81 free(buf); 81 free(buf);
82 } 82 }
83 BN_CTX_free(bnctx); 83 BN_CTX_free(bnctx);
@@ -130,7 +130,7 @@ buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
130 ret = 0; 130 ret = 0;
131 out: 131 out:
132 BN_CTX_free(bnctx); 132 BN_CTX_free(bnctx);
133 bzero(buf, len); 133 explicit_bzero(buf, len);
134 free(buf); 134 free(buf);
135 return ret; 135 return ret;
136} 136}
diff --git a/buffer.c b/buffer.c
index 9e7c40a5a..d240f6753 100644
--- a/buffer.c
+++ b/buffer.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: buffer.c,v 1.34 2013/11/08 11:15:19 dtucker Exp $ */ 1/* $OpenBSD: buffer.c,v 1.35 2014/02/02 03:44:31 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
@@ -49,7 +49,7 @@ void
49buffer_free(Buffer *buffer) 49buffer_free(Buffer *buffer)
50{ 50{
51 if (buffer->alloc > 0) { 51 if (buffer->alloc > 0) {
52 memset(buffer->buf, 0, buffer->alloc); 52 explicit_bzero(buffer->buf, buffer->alloc);
53 buffer->alloc = 0; 53 buffer->alloc = 0;
54 free(buffer->buf); 54 free(buffer->buf);
55 } 55 }
diff --git a/canohost.c b/canohost.c
index a19a60cda..a61a8c94d 100644
--- a/canohost.c
+++ b/canohost.c
@@ -192,7 +192,7 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
192 memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); 192 memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
193 port = a6->sin6_port; 193 port = a6->sin6_port;
194 194
195 bzero(a4, sizeof(*a4)); 195 memset(a4, 0, sizeof(*a4));
196 196
197 a4->sin_family = AF_INET; 197 a4->sin_family = AF_INET;
198 *len = sizeof(*a4); 198 *len = sizeof(*a4);
diff --git a/channels.c b/channels.c
index 8e66265a3..9efe89c9c 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.328 2013/12/19 01:04:36 djm Exp $ */ 1/* $OpenBSD: channels.c,v 1.331 2014/02/26 20:29:29 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
@@ -423,7 +423,7 @@ channel_free(Channel *c)
423 if (cc->abandon_cb != NULL) 423 if (cc->abandon_cb != NULL)
424 cc->abandon_cb(c, cc->ctx); 424 cc->abandon_cb(c, cc->ctx);
425 TAILQ_REMOVE(&c->status_confirms, cc, entry); 425 TAILQ_REMOVE(&c->status_confirms, cc, entry);
426 bzero(cc, sizeof(*cc)); 426 explicit_bzero(cc, sizeof(*cc));
427 free(cc); 427 free(cc);
428 } 428 }
429 if (c->filter_cleanup != NULL && c->filter_ctx != NULL) 429 if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
@@ -1072,6 +1072,9 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1072 buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); 1072 buffer_get(&c->input, (char *)&s4_req.dest_addr, 4);
1073 have = buffer_len(&c->input); 1073 have = buffer_len(&c->input);
1074 p = buffer_ptr(&c->input); 1074 p = buffer_ptr(&c->input);
1075 if (memchr(p, '\0', have) == NULL)
1076 fatal("channel %d: decode socks4: user not nul terminated",
1077 c->self);
1075 len = strlen(p); 1078 len = strlen(p);
1076 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); 1079 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
1077 len++; /* trailing '\0' */ 1080 len++; /* trailing '\0' */
@@ -2671,7 +2674,7 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
2671 return; 2674 return;
2672 cc->cb(type, c, cc->ctx); 2675 cc->cb(type, c, cc->ctx);
2673 TAILQ_REMOVE(&c->status_confirms, cc, entry); 2676 TAILQ_REMOVE(&c->status_confirms, cc, entry);
2674 bzero(cc, sizeof(*cc)); 2677 explicit_bzero(cc, sizeof(*cc));
2675 free(cc); 2678 free(cc);
2676} 2679}
2677 2680
@@ -3304,9 +3307,7 @@ channel_connect_ctx_free(struct channel_connect *cctx)
3304 free(cctx->host); 3307 free(cctx->host);
3305 if (cctx->aitop) 3308 if (cctx->aitop)
3306 freeaddrinfo(cctx->aitop); 3309 freeaddrinfo(cctx->aitop);
3307 bzero(cctx, sizeof(*cctx)); 3310 memset(cctx, 0, sizeof(*cctx));
3308 cctx->host = NULL;
3309 cctx->ai = cctx->aitop = NULL;
3310} 3311}
3311 3312
3312/* Return CONNECTING channel to remote host, port */ 3313/* Return CONNECTING channel to remote host, port */
diff --git a/cipher-3des1.c b/cipher-3des1.c
index 56fc77786..b2823592b 100644
--- a/cipher-3des1.c
+++ b/cipher-3des1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher-3des1.c,v 1.9 2013/11/08 00:39:15 djm Exp $ */ 1/* $OpenBSD: cipher-3des1.c,v 1.10 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2003 Markus Friedl. All rights reserved. 3 * Copyright (c) 2003 Markus Friedl. All rights reserved.
4 * 4 *
@@ -93,7 +93,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
93 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || 93 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
94 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || 94 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
95 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { 95 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
96 memset(c, 0, sizeof(*c)); 96 explicit_bzero(c, sizeof(*c));
97 free(c); 97 free(c);
98 EVP_CIPHER_CTX_set_app_data(ctx, NULL); 98 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
99 return (0); 99 return (0);
@@ -134,7 +134,7 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
134 EVP_CIPHER_CTX_cleanup(&c->k1); 134 EVP_CIPHER_CTX_cleanup(&c->k1);
135 EVP_CIPHER_CTX_cleanup(&c->k2); 135 EVP_CIPHER_CTX_cleanup(&c->k2);
136 EVP_CIPHER_CTX_cleanup(&c->k3); 136 EVP_CIPHER_CTX_cleanup(&c->k3);
137 memset(c, 0, sizeof(*c)); 137 explicit_bzero(c, sizeof(*c));
138 free(c); 138 free(c);
139 EVP_CIPHER_CTX_set_app_data(ctx, NULL); 139 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
140 } 140 }
diff --git a/cipher-chachapoly.c b/cipher-chachapoly.c
index 91b0830fd..251b94ec8 100644
--- a/cipher-chachapoly.c
+++ b/cipher-chachapoly.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17/* $OpenBSD: cipher-chachapoly.c,v 1.3 2013/12/15 21:42:35 djm Exp $ */ 17/* $OpenBSD: cipher-chachapoly.c,v 1.4 2014/01/31 16:39:19 tedu Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -58,7 +58,7 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
58 * Run ChaCha20 once to generate the Poly1305 key. The IV is the 58 * Run ChaCha20 once to generate the Poly1305 key. The IV is the
59 * packet sequence number. 59 * packet sequence number.
60 */ 60 */
61 bzero(poly_key, sizeof(poly_key)); 61 memset(poly_key, 0, sizeof(poly_key));
62 put_u64(seqbuf, seqnr); 62 put_u64(seqbuf, seqnr);
63 chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); 63 chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
64 chacha_encrypt_bytes(&ctx->main_ctx, 64 chacha_encrypt_bytes(&ctx->main_ctx,
@@ -90,9 +90,9 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
90 r = 0; 90 r = 0;
91 91
92 out: 92 out:
93 bzero(expected_tag, sizeof(expected_tag)); 93 explicit_bzero(expected_tag, sizeof(expected_tag));
94 bzero(seqbuf, sizeof(seqbuf)); 94 explicit_bzero(seqbuf, sizeof(seqbuf));
95 bzero(poly_key, sizeof(poly_key)); 95 explicit_bzero(poly_key, sizeof(poly_key));
96 return r; 96 return r;
97} 97}
98 98
diff --git a/cipher.c b/cipher.c
index 2476e6539..53d9b4fb7 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.94 2014/01/25 10:12:50 dtucker Exp $ */ 1/* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 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
@@ -39,8 +39,6 @@
39 39
40#include <sys/types.h> 40#include <sys/types.h>
41 41
42#include <openssl/md5.h>
43
44#include <string.h> 42#include <string.h>
45#include <stdarg.h> 43#include <stdarg.h>
46#include <stdio.h> 44#include <stdio.h>
@@ -49,6 +47,8 @@
49#include "log.h" 47#include "log.h"
50#include "misc.h" 48#include "misc.h"
51#include "cipher.h" 49#include "cipher.h"
50#include "buffer.h"
51#include "digest.h"
52 52
53/* compatibility with old or broken OpenSSL versions */ 53/* compatibility with old or broken OpenSSL versions */
54#include "openbsd-compat/openssl-compat.h" 54#include "openbsd-compat/openssl-compat.h"
@@ -228,8 +228,6 @@ ciphers_valid(const char *names)
228 debug("bad cipher %s [%s]", p, names); 228 debug("bad cipher %s [%s]", p, names);
229 free(cipher_list); 229 free(cipher_list);
230 return 0; 230 return 0;
231 } else {
232 debug3("cipher ok: %s [%s]", p, names);
233 } 231 }
234 } 232 }
235 debug3("ciphers ok: [%s]", names); 233 debug3("ciphers ok: [%s]", names);
@@ -337,7 +335,7 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
337 if (EVP_Cipher(&cc->evp, discard, junk, 335 if (EVP_Cipher(&cc->evp, discard, junk,
338 cipher->discard_len) == 0) 336 cipher->discard_len) == 0)
339 fatal("evp_crypt: EVP_Cipher failed during discard"); 337 fatal("evp_crypt: EVP_Cipher failed during discard");
340 memset(discard, 0, cipher->discard_len); 338 explicit_bzero(discard, cipher->discard_len);
341 free(junk); 339 free(junk);
342 free(discard); 340 free(discard);
343 } 341 }
@@ -422,7 +420,7 @@ void
422cipher_cleanup(CipherContext *cc) 420cipher_cleanup(CipherContext *cc)
423{ 421{
424 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 422 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
425 memset(&cc->cp_ctx, 0, sizeof(cc->cp_ctx)); 423 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
426 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 424 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
427 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 425 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
428} 426}
@@ -436,17 +434,15 @@ void
436cipher_set_key_string(CipherContext *cc, const Cipher *cipher, 434cipher_set_key_string(CipherContext *cc, const Cipher *cipher,
437 const char *passphrase, int do_encrypt) 435 const char *passphrase, int do_encrypt)
438{ 436{
439 MD5_CTX md;
440 u_char digest[16]; 437 u_char digest[16];
441 438
442 MD5_Init(&md); 439 if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase),
443 MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); 440 digest, sizeof(digest)) < 0)
444 MD5_Final(digest, &md); 441 fatal("%s: md5 failed", __func__);
445 442
446 cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); 443 cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
447 444
448 memset(digest, 0, sizeof(digest)); 445 explicit_bzero(digest, sizeof(digest));
449 memset(&md, 0, sizeof(md));
450} 446}
451 447
452/* 448/*
diff --git a/clientloop.c b/clientloop.c
index 30097cdfe..4bc5b57d2 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.256 2013/11/20 20:54:10 deraadt Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.258 2014/02/02 03:44:31 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
@@ -553,7 +553,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
553 gc->cb(type, seq, gc->ctx); 553 gc->cb(type, seq, gc->ctx);
554 if (--gc->ref_count <= 0) { 554 if (--gc->ref_count <= 0) {
555 TAILQ_REMOVE(&global_confirms, gc, entry); 555 TAILQ_REMOVE(&global_confirms, gc, entry);
556 bzero(gc, sizeof(*gc)); 556 explicit_bzero(gc, sizeof(*gc));
557 free(gc); 557 free(gc);
558 } 558 }
559 559
@@ -885,7 +885,7 @@ process_cmdline(void)
885 int cancel_port, ok; 885 int cancel_port, ok;
886 Forward fwd; 886 Forward fwd;
887 887
888 bzero(&fwd, sizeof(fwd)); 888 memset(&fwd, 0, sizeof(fwd));
889 fwd.listen_host = fwd.connect_host = NULL; 889 fwd.listen_host = fwd.connect_host = NULL;
890 890
891 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 891 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
@@ -1781,7 +1781,7 @@ client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
1781 char *data = packet_get_string(&data_len); 1781 char *data = packet_get_string(&data_len);
1782 packet_check_eom(); 1782 packet_check_eom();
1783 buffer_append(&stdout_buffer, data, data_len); 1783 buffer_append(&stdout_buffer, data, data_len);
1784 memset(data, 0, data_len); 1784 explicit_bzero(data, data_len);
1785 free(data); 1785 free(data);
1786} 1786}
1787static void 1787static void
@@ -1791,7 +1791,7 @@ client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
1791 char *data = packet_get_string(&data_len); 1791 char *data = packet_get_string(&data_len);
1792 packet_check_eom(); 1792 packet_check_eom();
1793 buffer_append(&stderr_buffer, data, data_len); 1793 buffer_append(&stderr_buffer, data, data_len);
1794 memset(data, 0, data_len); 1794 explicit_bzero(data, data_len);
1795 free(data); 1795 free(data);
1796} 1796}
1797static void 1797static void
diff --git a/config.h.in b/config.h.in
index 906e5497f..6bc422c3e 100644
--- a/config.h.in
+++ b/config.h.in
@@ -414,6 +414,9 @@
414/* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */ 414/* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */
415#undef HAVE_EVP_MD_CTX_CLEANUP 415#undef HAVE_EVP_MD_CTX_CLEANUP
416 416
417/* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */
418#undef HAVE_EVP_MD_CTX_COPY_EX
419
417/* Define to 1 if you have the `EVP_MD_CTX_init' function. */ 420/* Define to 1 if you have the `EVP_MD_CTX_init' function. */
418#undef HAVE_EVP_MD_CTX_INIT 421#undef HAVE_EVP_MD_CTX_INIT
419 422
@@ -423,6 +426,9 @@
423/* Define if you have ut_exit in utmp.h */ 426/* Define if you have ut_exit in utmp.h */
424#undef HAVE_EXIT_IN_UTMP 427#undef HAVE_EXIT_IN_UTMP
425 428
429/* Define to 1 if you have the `explicit_bzero' function. */
430#undef HAVE_EXPLICIT_BZERO
431
426/* Define to 1 if you have the `fchmod' function. */ 432/* Define to 1 if you have the `fchmod' function. */
427#undef HAVE_FCHMOD 433#undef HAVE_FCHMOD
428 434
diff --git a/configure b/configure
index 57b68e256..e2f12cdff 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
1#! /bin/sh 1#! /bin/sh
2# From configure.ac Revision: 1.568 . 2# From configure.ac Revision: 1.571 .
3# Guess values for system-dependent variables and create Makefiles. 3# Guess values for system-dependent variables and create Makefiles.
4# Generated by GNU Autoconf 2.68 for OpenSSH Portable. 4# Generated by GNU Autoconf 2.68 for OpenSSH Portable.
5# 5#
@@ -7666,7 +7666,7 @@ $as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h
7666 # and will crash if they cannot be opened. 7666 # and will crash if they cannot be opened.
7667 7667
7668$as_echo "#define SANDBOX_SKIP_RLIMIT_NOFILE 1" >>confdefs.h 7668$as_echo "#define SANDBOX_SKIP_RLIMIT_NOFILE 1" >>confdefs.h
7669], 7669
7670 ;; 7670 ;;
7671*-*-bsdi*) 7671*-*-bsdi*)
7672 $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h 7672 $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h
@@ -10425,6 +10425,7 @@ for ac_func in \
10425 closefrom \ 10425 closefrom \
10426 dirfd \ 10426 dirfd \
10427 endgrent \ 10427 endgrent \
10428 explicit_bzero \
10428 fchmod \ 10429 fchmod \
10429 fchown \ 10430 fchown \
10430 freeaddrinfo \ 10431 freeaddrinfo \
@@ -12172,6 +12173,7 @@ for ac_func in \
12172 EVP_DigestFinal_ex \ 12173 EVP_DigestFinal_ex \
12173 EVP_MD_CTX_init \ 12174 EVP_MD_CTX_init \
12174 EVP_MD_CTX_cleanup \ 12175 EVP_MD_CTX_cleanup \
12176 EVP_MD_CTX_copy_ex \
12175 HMAC_CTX_init \ 12177 HMAC_CTX_init \
12176 RSA_generate_key_ex \ 12178 RSA_generate_key_ex \
12177 RSA_get_default_method \ 12179 RSA_get_default_method \
diff --git a/configure.ac b/configure.ac
index e2289cd37..86692714b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
1# $Id: configure.ac,v 1.568 2014/01/30 00:26:46 djm Exp $ 1# $Id: configure.ac,v 1.571 2014/02/21 17:09:34 tim Exp $
2# 2#
3# Copyright (c) 1999-2004 Damien Miller 3# Copyright (c) 1999-2004 Damien Miller
4# 4#
@@ -15,7 +15,7 @@
15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 16
17AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) 17AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org])
18AC_REVISION($Revision: 1.568 $) 18AC_REVISION($Revision: 1.571 $)
19AC_CONFIG_SRCDIR([ssh.c]) 19AC_CONFIG_SRCDIR([ssh.c])
20AC_LANG([C]) 20AC_LANG([C])
21 21
@@ -809,7 +809,7 @@ mips-sony-bsd|mips-sony-newsos4)
809 # Preauth crypto occasionally uses file descriptors for crypto offload 809 # Preauth crypto occasionally uses file descriptors for crypto offload
810 # and will crash if they cannot be opened. 810 # and will crash if they cannot be opened.
811 AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1], 811 AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1],
812 [define if setrlimit RLIMIT_NOFILE breaks things])], 812 [define if setrlimit RLIMIT_NOFILE breaks things])
813 ;; 813 ;;
814*-*-bsdi*) 814*-*-bsdi*)
815 AC_DEFINE([SETEUID_BREAKS_SETUID]) 815 AC_DEFINE([SETEUID_BREAKS_SETUID])
@@ -1673,6 +1673,7 @@ AC_CHECK_FUNCS([ \
1673 closefrom \ 1673 closefrom \
1674 dirfd \ 1674 dirfd \
1675 endgrent \ 1675 endgrent \
1676 explicit_bzero \
1676 fchmod \ 1677 fchmod \
1677 fchown \ 1678 fchown \
1678 freeaddrinfo \ 1679 freeaddrinfo \
@@ -2453,6 +2454,7 @@ AC_CHECK_FUNCS([ \
2453 EVP_DigestFinal_ex \ 2454 EVP_DigestFinal_ex \
2454 EVP_MD_CTX_init \ 2455 EVP_MD_CTX_init \
2455 EVP_MD_CTX_cleanup \ 2456 EVP_MD_CTX_cleanup \
2457 EVP_MD_CTX_copy_ex \
2456 HMAC_CTX_init \ 2458 HMAC_CTX_init \
2457 RSA_generate_key_ex \ 2459 RSA_generate_key_ex \
2458 RSA_get_default_method \ 2460 RSA_get_default_method \
diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec
index 3c417bb8f..0061fe933 100644
--- a/contrib/caldera/openssh.spec
+++ b/contrib/caldera/openssh.spec
@@ -16,7 +16,7 @@
16 16
17#old cvs stuff. please update before use. may be deprecated. 17#old cvs stuff. please update before use. may be deprecated.
18%define use_stable 1 18%define use_stable 1
19%define version 6.5p1 19%define version 6.6p1
20%if %{use_stable} 20%if %{use_stable}
21 %define cvs %{nil} 21 %define cvs %{nil}
22 %define release 1 22 %define release 1
@@ -363,4 +363,4 @@ fi
363* Mon Jan 01 1998 ... 363* Mon Jan 01 1998 ...
364Template Version: 1.31 364Template Version: 1.31
365 365
366$Id: openssh.spec,v 1.82 2014/01/16 07:51:10 djm Exp $ 366$Id: openssh.spec,v 1.83 2014/02/27 23:03:55 djm Exp $
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec
index d47cf3862..96401c6ee 100644
--- a/contrib/redhat/openssh.spec
+++ b/contrib/redhat/openssh.spec
@@ -1,4 +1,4 @@
1%define ver 6.5p1 1%define ver 6.6p1
2%define rel 1 2%define rel 1
3 3
4# OpenSSH privilege separation requires a user & group ID 4# OpenSSH privilege separation requires a user & group ID
diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec
index 6693fe2bc..0515d6d7c 100644
--- a/contrib/suse/openssh.spec
+++ b/contrib/suse/openssh.spec
@@ -13,7 +13,7 @@
13 13
14Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation 14Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
15Name: openssh 15Name: openssh
16Version: 6.5p1 16Version: 6.6p1
17URL: http://www.openssh.com/ 17URL: http://www.openssh.com/
18Release: 1 18Release: 1
19Source0: openssh-%{version}.tar.gz 19Source0: openssh-%{version}.tar.gz
diff --git a/debian/.git-dpm b/debian/.git-dpm
index 3deb8d58e..cd9486a07 100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@ -1,7 +1,7 @@
1# see git-dpm(1) from git-dpm package 1# see git-dpm(1) from git-dpm package
26dbd954a28d3fc2631f1c0b42c23452e1e493e6f 29cbb60f5e4932634db04c330c88abc49cc5567bd
36dbd954a28d3fc2631f1c0b42c23452e1e493e6f 39cbb60f5e4932634db04c330c88abc49cc5567bd
49a975a9faed7c4f334e8c8490db3e77e102f2b21 4796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7
5796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 5796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7
6openssh_6.6p1.orig.tar.gz 6openssh_6.6p1.orig.tar.gz
7b850fd1af704942d9b3c2eff7ef6b3a59b6a6b6e 7b850fd1af704942d9b3c2eff7ef6b3a59b6a6b6e
diff --git a/debian/changelog b/debian/changelog
index 7bc3c6046..eccc51410 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,10 @@
1openssh (1:6.5p1-7) UNRELEASED; urgency=medium 1openssh (1:6.6p1-1) UNRELEASED; urgency=medium
2 2
3 * Apply various warning-suppression and regression-test fixes to 3 * Apply various warning-suppression and regression-test fixes to
4 gssapi.patch from Damien Miller. 4 gssapi.patch from Damien Miller.
5 * New upstream release (http://www.openssh.com/txt/release-6.6).
5 6
6 -- Colin Watson <cjwatson@debian.org> Wed, 19 Mar 2014 16:40:52 +0000 7 -- Colin Watson <cjwatson@debian.org> Thu, 20 Mar 2014 00:32:46 +0000
7 8
8openssh (1:6.5p1-6) unstable; urgency=medium 9openssh (1:6.5p1-6) unstable; urgency=medium
9 10
diff --git a/debian/patches/auth-log-verbosity.patch b/debian/patches/auth-log-verbosity.patch
index 3de03e861..8d26d7b6f 100644
--- a/debian/patches/auth-log-verbosity.patch
+++ b/debian/patches/auth-log-verbosity.patch
@@ -1,4 +1,4 @@
1From 72aaec921b802c4f1dd73cac0fb21f149e443fc5 Mon Sep 17 00:00:00 2001 1From 283322f493ee7dc75511f6cf9e9b88e536de0874 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:02 +0000 3Date: Sun, 9 Feb 2014 16:10:02 +0000
4Subject: Quieten logs when multiple from= restrictions are used 4Subject: Quieten logs when multiple from= restrictions are used
@@ -91,10 +91,10 @@ index 7455c94..a3f0a02 100644
91 void auth_clear_options(void); 91 void auth_clear_options(void);
92 int auth_cert_options(Key *, struct passwd *); 92 int auth_cert_options(Key *, struct passwd *);
93diff --git a/auth-rsa.c b/auth-rsa.c 93diff --git a/auth-rsa.c b/auth-rsa.c
94index 545aa49..4624c15 100644 94index 5dad6c3..260ce2f 100644
95--- a/auth-rsa.c 95--- a/auth-rsa.c
96+++ b/auth-rsa.c 96+++ b/auth-rsa.c
97@@ -174,6 +174,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, 97@@ -178,6 +178,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file,
98 if ((f = auth_openkeyfile(file, pw, options.strict_modes)) == NULL) 98 if ((f = auth_openkeyfile(file, pw, options.strict_modes)) == NULL)
99 return 0; 99 return 0;
100 100
diff --git a/debian/patches/authorized-keys-man-symlink.patch b/debian/patches/authorized-keys-man-symlink.patch
index 39e63e33b..74bfb46e6 100644
--- a/debian/patches/authorized-keys-man-symlink.patch
+++ b/debian/patches/authorized-keys-man-symlink.patch
@@ -1,4 +1,4 @@
1From 6384f890f732a0967590e37ad402ace6505799ea Mon Sep 17 00:00:00 2001 1From 71448da5ce75ba50bcb10dbbd3b8c7633f633e8f Mon Sep 17 00:00:00 2001
2From: Tomas Pospisek <tpo_deb@sourcepole.ch> 2From: Tomas Pospisek <tpo_deb@sourcepole.ch>
3Date: Sun, 9 Feb 2014 16:10:07 +0000 3Date: Sun, 9 Feb 2014 16:10:07 +0000
4Subject: Install authorized_keys(5) as a symlink to sshd(8) 4Subject: Install authorized_keys(5) as a symlink to sshd(8)
@@ -13,7 +13,7 @@ Patch-Name: authorized-keys-man-symlink.patch
13 1 file changed, 1 insertion(+) 13 1 file changed, 1 insertion(+)
14 14
15diff --git a/Makefile.in b/Makefile.in 15diff --git a/Makefile.in b/Makefile.in
16index 598d55a..5cf8100 100644 16index 3d96c05..feee0b2 100644
17--- a/Makefile.in 17--- a/Makefile.in
18+++ b/Makefile.in 18+++ b/Makefile.in
19@@ -287,6 +287,7 @@ install-files: 19@@ -287,6 +287,7 @@ install-files:
diff --git a/debian/patches/consolekit.patch b/debian/patches/consolekit.patch
index 7492daca8..e3ff4d7e4 100644
--- a/debian/patches/consolekit.patch
+++ b/debian/patches/consolekit.patch
@@ -1,10 +1,10 @@
1From f4858fd1a10d1621e5e3ad5f2400dd17d156ced7 Mon Sep 17 00:00:00 2001 1From 7a26d16efb4ee303c8d66ee82caf9d0686f4a074 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@ubuntu.com> 2From: Colin Watson <cjwatson@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:09:57 +0000 3Date: Sun, 9 Feb 2014 16:09:57 +0000
4Subject: Add support for registering ConsoleKit sessions on login 4Subject: Add support for registering ConsoleKit sessions on login
5 5
6Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1450 6Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1450
7Last-Updated: 2013-09-14 7Last-Updated: 2014-03-20
8 8
9Patch-Name: consolekit.patch 9Patch-Name: consolekit.patch
10--- 10---
@@ -13,18 +13,18 @@ Patch-Name: consolekit.patch
13 configure.ac | 25 ++++++ 13 configure.ac | 25 ++++++
14 consolekit.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 14 consolekit.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 consolekit.h | 24 ++++++ 15 consolekit.h | 24 ++++++
16 monitor.c | 43 +++++++++++ 16 monitor.c | 42 ++++++++++
17 monitor.h | 2 + 17 monitor.h | 2 +
18 monitor_wrap.c | 31 ++++++++ 18 monitor_wrap.c | 30 ++++++++
19 monitor_wrap.h | 4 + 19 monitor_wrap.h | 4 +
20 session.c | 13 ++++ 20 session.c | 13 ++++
21 session.h | 6 ++ 21 session.h | 6 ++
22 11 files changed, 522 insertions(+), 1 deletion(-) 22 11 files changed, 520 insertions(+), 1 deletion(-)
23 create mode 100644 consolekit.c 23 create mode 100644 consolekit.c
24 create mode 100644 consolekit.h 24 create mode 100644 consolekit.h
25 25
26diff --git a/Makefile.in b/Makefile.in 26diff --git a/Makefile.in b/Makefile.in
27index 35c6fd6..598d55a 100644 27index ee1d2c3..3d96c05 100644
28--- a/Makefile.in 28--- a/Makefile.in
29+++ b/Makefile.in 29+++ b/Makefile.in
30@@ -97,7 +97,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ 30@@ -97,7 +97,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
@@ -38,7 +38,7 @@ index 35c6fd6..598d55a 100644
38 MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out 38 MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
39 MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 39 MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
40diff --git a/configure b/configure 40diff --git a/configure b/configure
41index 5a9db2d..57b68e2 100755 41index b6b5b6d..e2f12cd 100755
42--- a/configure 42--- a/configure
43+++ b/configure 43+++ b/configure
44@@ -740,6 +740,7 @@ with_privsep_user 44@@ -740,6 +740,7 @@ with_privsep_user
@@ -57,7 +57,7 @@ index 5a9db2d..57b68e2 100755
57 --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) 57 --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)
58 --with-xauth=PATH Specify path to xauth program 58 --with-xauth=PATH Specify path to xauth program
59 --with-maildir=/path/to/mail Specify your system mail directory 59 --with-maildir=/path/to/mail Specify your system mail directory
60@@ -17215,6 +17217,135 @@ fi 60@@ -17217,6 +17219,135 @@ fi
61 61
62 62
63 63
@@ -193,7 +193,7 @@ index 5a9db2d..57b68e2 100755
193 # Looking for programs, paths and files 193 # Looking for programs, paths and files
194 194
195 PRIVSEP_PATH=/var/empty 195 PRIVSEP_PATH=/var/empty
196@@ -19744,6 +19875,7 @@ echo " MD5 password support: $MD5_MSG" 196@@ -19746,6 +19877,7 @@ echo " MD5 password support: $MD5_MSG"
197 echo " libedit support: $LIBEDIT_MSG" 197 echo " libedit support: $LIBEDIT_MSG"
198 echo " Solaris process contract support: $SPC_MSG" 198 echo " Solaris process contract support: $SPC_MSG"
199 echo " Solaris project support: $SP_MSG" 199 echo " Solaris project support: $SP_MSG"
@@ -202,10 +202,10 @@ index 5a9db2d..57b68e2 100755
202 echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" 202 echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
203 echo " BSD Auth support: $BSD_AUTH_MSG" 203 echo " BSD Auth support: $BSD_AUTH_MSG"
204diff --git a/configure.ac b/configure.ac 204diff --git a/configure.ac b/configure.ac
205index 90eebf5..e2289cd 100644 205index d235fb0..8669271 100644
206--- a/configure.ac 206--- a/configure.ac
207+++ b/configure.ac 207+++ b/configure.ac
208@@ -4070,6 +4070,30 @@ AC_ARG_WITH([kerberos5], 208@@ -4072,6 +4072,30 @@ AC_ARG_WITH([kerberos5],
209 AC_SUBST([GSSLIBS]) 209 AC_SUBST([GSSLIBS])
210 AC_SUBST([K5LIBS]) 210 AC_SUBST([K5LIBS])
211 211
@@ -236,7 +236,7 @@ index 90eebf5..e2289cd 100644
236 # Looking for programs, paths and files 236 # Looking for programs, paths and files
237 237
238 PRIVSEP_PATH=/var/empty 238 PRIVSEP_PATH=/var/empty
239@@ -4871,6 +4895,7 @@ echo " MD5 password support: $MD5_MSG" 239@@ -4873,6 +4897,7 @@ echo " MD5 password support: $MD5_MSG"
240 echo " libedit support: $LIBEDIT_MSG" 240 echo " libedit support: $LIBEDIT_MSG"
241 echo " Solaris process contract support: $SPC_MSG" 241 echo " Solaris process contract support: $SPC_MSG"
242 echo " Solaris project support: $SP_MSG" 242 echo " Solaris project support: $SP_MSG"
@@ -521,11 +521,11 @@ index 0000000..8ce3716
521+ 521+
522+#endif /* USE_CONSOLEKIT */ 522+#endif /* USE_CONSOLEKIT */
523diff --git a/monitor.c b/monitor.c 523diff --git a/monitor.c b/monitor.c
524index 88f472e..8ffea4f 100644 524index 11eac63..7c105e6 100644
525--- a/monitor.c 525--- a/monitor.c
526+++ b/monitor.c 526+++ b/monitor.c
527@@ -98,6 +98,9 @@ 527@@ -97,6 +97,9 @@
528 #include "jpake.h" 528 #include "ssh2.h"
529 #include "roaming.h" 529 #include "roaming.h"
530 #include "authfd.h" 530 #include "authfd.h"
531+#ifdef USE_CONSOLEKIT 531+#ifdef USE_CONSOLEKIT
@@ -534,7 +534,7 @@ index 88f472e..8ffea4f 100644
534 534
535 #ifdef GSSAPI 535 #ifdef GSSAPI
536 static Gssctxt *gsscontext = NULL; 536 static Gssctxt *gsscontext = NULL;
537@@ -193,6 +196,10 @@ int mm_answer_audit_command(int, Buffer *); 537@@ -187,6 +190,10 @@ int mm_answer_audit_command(int, Buffer *);
538 538
539 static int monitor_read_log(struct monitor *); 539 static int monitor_read_log(struct monitor *);
540 540
@@ -545,7 +545,7 @@ index 88f472e..8ffea4f 100644
545 static Authctxt *authctxt; 545 static Authctxt *authctxt;
546 static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ 546 static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
547 547
548@@ -285,6 +292,9 @@ struct mon_table mon_dispatch_postauth20[] = { 548@@ -272,6 +279,9 @@ struct mon_table mon_dispatch_postauth20[] = {
549 {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, 549 {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
550 {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, 550 {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
551 #endif 551 #endif
@@ -555,7 +555,7 @@ index 88f472e..8ffea4f 100644
555 {0, 0, NULL} 555 {0, 0, NULL}
556 }; 556 };
557 557
558@@ -327,6 +337,9 @@ struct mon_table mon_dispatch_postauth15[] = { 558@@ -314,6 +324,9 @@ struct mon_table mon_dispatch_postauth15[] = {
559 {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, 559 {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
560 {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, 560 {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
561 #endif 561 #endif
@@ -565,7 +565,7 @@ index 88f472e..8ffea4f 100644
565 {0, 0, NULL} 565 {0, 0, NULL}
566 }; 566 };
567 567
568@@ -514,6 +527,9 @@ monitor_child_postauth(struct monitor *pmonitor) 568@@ -492,6 +505,9 @@ monitor_child_postauth(struct monitor *pmonitor)
569 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); 569 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
570 monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); 570 monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
571 } 571 }
@@ -575,11 +575,10 @@ index 88f472e..8ffea4f 100644
575 575
576 for (;;) 576 for (;;)
577 monitor_read(pmonitor, mon_dispatch, NULL); 577 monitor_read(pmonitor, mon_dispatch, NULL);
578@@ -2493,3 +2509,30 @@ mm_answer_jpake_check_confirm(int sock, Buffer *m) 578@@ -2269,3 +2285,29 @@ mm_answer_gss_updatecreds(int socket, Buffer *m) {
579 } 579
580 #endif /* GSSAPI */
580 581
581 #endif /* JPAKE */
582+
583+#ifdef USE_CONSOLEKIT 582+#ifdef USE_CONSOLEKIT
584+int 583+int
585+mm_answer_consolekit_register(int sock, Buffer *m) 584+mm_answer_consolekit_register(int sock, Buffer *m)
@@ -607,10 +606,10 @@ index 88f472e..8ffea4f 100644
607+} 606+}
608+#endif /* USE_CONSOLEKIT */ 607+#endif /* USE_CONSOLEKIT */
609diff --git a/monitor.h b/monitor.h 608diff --git a/monitor.h b/monitor.h
610index 3c13706..cd83428 100644 609index 4d5e8fa..10ba59e 100644
611--- a/monitor.h 610--- a/monitor.h
612+++ b/monitor.h 611+++ b/monitor.h
613@@ -75,6 +75,8 @@ enum monitor_reqtype { 612@@ -70,6 +70,8 @@ enum monitor_reqtype {
614 613
615 MONITOR_REQ_AUTHROLE = 154, 614 MONITOR_REQ_AUTHROLE = 154,
616 615
@@ -620,14 +619,13 @@ index 3c13706..cd83428 100644
620 619
621 struct mm_master; 620 struct mm_master;
622diff --git a/monitor_wrap.c b/monitor_wrap.c 621diff --git a/monitor_wrap.c b/monitor_wrap.c
623index 69bc324..670b62d 100644 622index f75dc9d..a8fb07b 100644
624--- a/monitor_wrap.c 623--- a/monitor_wrap.c
625+++ b/monitor_wrap.c 624+++ b/monitor_wrap.c
626@@ -1516,3 +1516,34 @@ mm_jpake_check_confirm(const BIGNUM *k, 625@@ -1353,3 +1353,33 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
627 return success; 626
628 } 627 #endif /* GSSAPI */
629 #endif /* JPAKE */ 628
630+
631+#ifdef USE_CONSOLEKIT 629+#ifdef USE_CONSOLEKIT
632+char * 630+char *
633+mm_consolekit_register(Session *s, const char *display) 631+mm_consolekit_register(Session *s, const char *display)
@@ -659,10 +657,10 @@ index 69bc324..670b62d 100644
659+} 657+}
660+#endif /* USE_CONSOLEKIT */ 658+#endif /* USE_CONSOLEKIT */
661diff --git a/monitor_wrap.h b/monitor_wrap.h 659diff --git a/monitor_wrap.h b/monitor_wrap.h
662index 4d12e29..360fb9f 100644 660index 9c2ee49..00e93fe 100644
663--- a/monitor_wrap.h 661--- a/monitor_wrap.h
664+++ b/monitor_wrap.h 662+++ b/monitor_wrap.h
665@@ -131,4 +131,8 @@ void *mm_zalloc(struct mm_master *, u_int, u_int); 663@@ -111,4 +111,8 @@ void *mm_zalloc(struct mm_master *, u_int, u_int);
666 void mm_zfree(struct mm_master *, void *); 664 void mm_zfree(struct mm_master *, void *);
667 void mm_init_compression(struct mm_master *); 665 void mm_init_compression(struct mm_master *);
668 666
@@ -672,7 +670,7 @@ index 4d12e29..360fb9f 100644
672+ 670+
673 #endif /* _MM_WRAP_H_ */ 671 #endif /* _MM_WRAP_H_ */
674diff --git a/session.c b/session.c 672diff --git a/session.c b/session.c
675index 5ddd82a..14df226 100644 673index 6848df4..9d43fc3 100644
676--- a/session.c 674--- a/session.c
677+++ b/session.c 675+++ b/session.c
678@@ -92,6 +92,7 @@ 676@@ -92,6 +92,7 @@
@@ -683,7 +681,7 @@ index 5ddd82a..14df226 100644
683 681
684 #if defined(KRB5) && defined(USE_AFS) 682 #if defined(KRB5) && defined(USE_AFS)
685 #include <kafs.h> 683 #include <kafs.h>
686@@ -1155,6 +1156,9 @@ do_setup_env(Session *s, const char *shell) 684@@ -1160,6 +1161,9 @@ do_setup_env(Session *s, const char *shell)
687 #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) 685 #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
688 char *path = NULL; 686 char *path = NULL;
689 #endif 687 #endif
@@ -693,7 +691,7 @@ index 5ddd82a..14df226 100644
693 691
694 /* Initialize the environment. */ 692 /* Initialize the environment. */
695 envsize = 100; 693 envsize = 100;
696@@ -1299,6 +1303,11 @@ do_setup_env(Session *s, const char *shell) 694@@ -1304,6 +1308,11 @@ do_setup_env(Session *s, const char *shell)
697 child_set_env(&env, &envsize, "KRB5CCNAME", 695 child_set_env(&env, &envsize, "KRB5CCNAME",
698 s->authctxt->krb5_ccname); 696 s->authctxt->krb5_ccname);
699 #endif 697 #endif
@@ -705,7 +703,7 @@ index 5ddd82a..14df226 100644
705 #ifdef USE_PAM 703 #ifdef USE_PAM
706 /* 704 /*
707 * Pull in any environment variables that may have 705 * Pull in any environment variables that may have
708@@ -2348,6 +2357,10 @@ session_pty_cleanup2(Session *s) 706@@ -2353,6 +2362,10 @@ session_pty_cleanup2(Session *s)
709 707
710 debug("session_pty_cleanup: session %d release %s", s->self, s->tty); 708 debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
711 709
diff --git a/debian/patches/debian-banner.patch b/debian/patches/debian-banner.patch
index 39cab81e7..49219cf93 100644
--- a/debian/patches/debian-banner.patch
+++ b/debian/patches/debian-banner.patch
@@ -1,4 +1,4 @@
1From 75e44c43679e8b888b7ef55ce7abe432eb57ef1c Mon Sep 17 00:00:00 2001 1From 9fcad888f4dbf0ecc0c7e87b6ef0f8d88d7ac3ec Mon Sep 17 00:00:00 2001
2From: Kees Cook <kees@debian.org> 2From: Kees Cook <kees@debian.org>
3Date: Sun, 9 Feb 2014 16:10:06 +0000 3Date: Sun, 9 Feb 2014 16:10:06 +0000
4Subject: Add DebianBanner server configuration option 4Subject: Add DebianBanner server configuration option
@@ -19,10 +19,10 @@ Patch-Name: debian-banner.patch
19 4 files changed, 18 insertions(+), 1 deletion(-) 19 4 files changed, 18 insertions(+), 1 deletion(-)
20 20
21diff --git a/servconf.c b/servconf.c 21diff --git a/servconf.c b/servconf.c
22index 65f71ad..63ff4ff 100644 22index 90de888..37fd2de 100644
23--- a/servconf.c 23--- a/servconf.c
24+++ b/servconf.c 24+++ b/servconf.c
25@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions *options) 25@@ -156,6 +156,7 @@ initialize_server_options(ServerOptions *options)
26 options->ip_qos_interactive = -1; 26 options->ip_qos_interactive = -1;
27 options->ip_qos_bulk = -1; 27 options->ip_qos_bulk = -1;
28 options->version_addendum = NULL; 28 options->version_addendum = NULL;
@@ -30,7 +30,7 @@ index 65f71ad..63ff4ff 100644
30 } 30 }
31 31
32 void 32 void
33@@ -312,6 +313,8 @@ fill_default_server_options(ServerOptions *options) 33@@ -309,6 +310,8 @@ fill_default_server_options(ServerOptions *options)
34 options->ip_qos_bulk = IPTOS_THROUGHPUT; 34 options->ip_qos_bulk = IPTOS_THROUGHPUT;
35 if (options->version_addendum == NULL) 35 if (options->version_addendum == NULL)
36 options->version_addendum = xstrdup(""); 36 options->version_addendum = xstrdup("");
@@ -39,7 +39,7 @@ index 65f71ad..63ff4ff 100644
39 /* Turn privilege separation on by default */ 39 /* Turn privilege separation on by default */
40 if (use_privsep == -1) 40 if (use_privsep == -1)
41 use_privsep = PRIVSEP_NOSANDBOX; 41 use_privsep = PRIVSEP_NOSANDBOX;
42@@ -362,6 +365,7 @@ typedef enum { 42@@ -359,6 +362,7 @@ typedef enum {
43 sKexAlgorithms, sIPQoS, sVersionAddendum, 43 sKexAlgorithms, sIPQoS, sVersionAddendum,
44 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, 44 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
45 sAuthenticationMethods, sHostKeyAgent, 45 sAuthenticationMethods, sHostKeyAgent,
@@ -47,7 +47,7 @@ index 65f71ad..63ff4ff 100644
47 sDeprecated, sUnsupported 47 sDeprecated, sUnsupported
48 } ServerOpCodes; 48 } ServerOpCodes;
49 49
50@@ -504,6 +508,7 @@ static struct { 50@@ -496,6 +500,7 @@ static struct {
51 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, 51 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
52 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, 52 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
53 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, 53 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
@@ -55,7 +55,7 @@ index 65f71ad..63ff4ff 100644
55 { NULL, sBadOption, 0 } 55 { NULL, sBadOption, 0 }
56 }; 56 };
57 57
58@@ -1666,6 +1671,10 @@ process_server_config_line(ServerOptions *options, char *line, 58@@ -1654,6 +1659,10 @@ process_server_config_line(ServerOptions *options, char *line,
59 } 59 }
60 return 0; 60 return 0;
61 61
@@ -67,10 +67,10 @@ index 65f71ad..63ff4ff 100644
67 logit("%s line %d: Deprecated option %s", 67 logit("%s line %d: Deprecated option %s",
68 filename, linenum, arg); 68 filename, linenum, arg);
69diff --git a/servconf.h b/servconf.h 69diff --git a/servconf.h b/servconf.h
70index eba76ee..98d68ce 100644 70index c922eb5..dcd1c2a 100644
71--- a/servconf.h 71--- a/servconf.h
72+++ b/servconf.h 72+++ b/servconf.h
73@@ -188,6 +188,8 @@ typedef struct { 73@@ -186,6 +186,8 @@ typedef struct {
74 74
75 u_int num_auth_methods; 75 u_int num_auth_methods;
76 char *auth_methods[MAX_AUTH_METHODS]; 76 char *auth_methods[MAX_AUTH_METHODS];
@@ -80,7 +80,7 @@ index eba76ee..98d68ce 100644
80 80
81 /* Information about the incoming connection as used by Match */ 81 /* Information about the incoming connection as used by Match */
82diff --git a/sshd.c b/sshd.c 82diff --git a/sshd.c b/sshd.c
83index 82168a1..c49a877 100644 83index af9b8f1..665c0b9 100644
84--- a/sshd.c 84--- a/sshd.c
85+++ b/sshd.c 85+++ b/sshd.c
86@@ -440,7 +440,8 @@ sshd_exchange_identification(int sock_in, int sock_out) 86@@ -440,7 +440,8 @@ sshd_exchange_identification(int sock_in, int sock_out)
@@ -94,7 +94,7 @@ index 82168a1..c49a877 100644
94 options.version_addendum, newline); 94 options.version_addendum, newline);
95 95
96diff --git a/sshd_config.5 b/sshd_config.5 96diff --git a/sshd_config.5 b/sshd_config.5
97index 39643de..bdca797 100644 97index 2164d58..8f078f6 100644
98--- a/sshd_config.5 98--- a/sshd_config.5
99+++ b/sshd_config.5 99+++ b/sshd_config.5
100@@ -413,6 +413,11 @@ or 100@@ -413,6 +413,11 @@ or
diff --git a/debian/patches/debian-config.patch b/debian/patches/debian-config.patch
index 77be015fa..9bb0c6520 100644
--- a/debian/patches/debian-config.patch
+++ b/debian/patches/debian-config.patch
@@ -1,4 +1,4 @@
1From 54a7935863c3e6b3f08f620b3bd75571bb90470c Mon Sep 17 00:00:00 2001 1From 9cbb60f5e4932634db04c330c88abc49cc5567bd Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:18 +0000 3Date: Sun, 9 Feb 2014 16:10:18 +0000
4Subject: Various Debian-specific configuration changes 4Subject: Various Debian-specific configuration changes
@@ -34,10 +34,10 @@ Patch-Name: debian-config.patch
34 5 files changed, 51 insertions(+), 3 deletions(-) 34 5 files changed, 51 insertions(+), 3 deletions(-)
35 35
36diff --git a/readconf.c b/readconf.c 36diff --git a/readconf.c b/readconf.c
37index 273552d..6ac8bea 100644 37index 32c4b42..5429fc2 100644
38--- a/readconf.c 38--- a/readconf.c
39+++ b/readconf.c 39+++ b/readconf.c
40@@ -1618,7 +1618,7 @@ fill_default_options(Options * options) 40@@ -1640,7 +1640,7 @@ fill_default_options(Options * options)
41 if (options->forward_x11 == -1) 41 if (options->forward_x11 == -1)
42 options->forward_x11 = 0; 42 options->forward_x11 = 0;
43 if (options->forward_x11_trusted == -1) 43 if (options->forward_x11_trusted == -1)
@@ -71,7 +71,7 @@ index 228e5ab..c9386aa 100644
71+ GSSAPIAuthentication yes 71+ GSSAPIAuthentication yes
72+ GSSAPIDelegateCredentials no 72+ GSSAPIDelegateCredentials no
73diff --git a/ssh_config.5 b/ssh_config.5 73diff --git a/ssh_config.5 b/ssh_config.5
74index 85f306c..cc91a5c 100644 74index 1d500e9..22e6372 100644
75--- a/ssh_config.5 75--- a/ssh_config.5
76+++ b/ssh_config.5 76+++ b/ssh_config.5
77@@ -71,6 +71,22 @@ Since the first obtained value for each parameter is used, more 77@@ -71,6 +71,22 @@ Since the first obtained value for each parameter is used, more
@@ -97,7 +97,7 @@ index 85f306c..cc91a5c 100644
97 The configuration file has the following format: 97 The configuration file has the following format:
98 .Pp 98 .Pp
99 Empty lines and lines starting with 99 Empty lines and lines starting with
100@@ -648,7 +664,8 @@ token used for the session will be set to expire after 20 minutes. 100@@ -654,7 +670,8 @@ token used for the session will be set to expire after 20 minutes.
101 Remote clients will be refused access after this time. 101 Remote clients will be refused access after this time.
102 .Pp 102 .Pp
103 The default is 103 The default is
@@ -120,7 +120,7 @@ index d9b8594..4db32f5 100644
120 #StrictModes yes 120 #StrictModes yes
121 #MaxAuthTries 6 121 #MaxAuthTries 6
122diff --git a/sshd_config.5 b/sshd_config.5 122diff --git a/sshd_config.5 b/sshd_config.5
123index 9fa6086..496530b 100644 123index 908e0bb..90fd3f4 100644
124--- a/sshd_config.5 124--- a/sshd_config.5
125+++ b/sshd_config.5 125+++ b/sshd_config.5
126@@ -57,6 +57,31 @@ Arguments may optionally be enclosed in double quotes 126@@ -57,6 +57,31 @@ Arguments may optionally be enclosed in double quotes
diff --git a/debian/patches/dnssec-sshfp.patch b/debian/patches/dnssec-sshfp.patch
index 3d33a91f9..bc89c50fc 100644
--- a/debian/patches/dnssec-sshfp.patch
+++ b/debian/patches/dnssec-sshfp.patch
@@ -1,4 +1,4 @@
1From 231608bce9f439366bc2d2c7537f48920f3dd852 Mon Sep 17 00:00:00 2001 1From 912129ba92bea401d8cdeadc7aa7084fbf7625a1 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:01 +0000 3Date: Sun, 9 Feb 2014 16:10:01 +0000
4Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf 4Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf
diff --git a/debian/patches/doc-hash-tab-completion.patch b/debian/patches/doc-hash-tab-completion.patch
index df957fca2..16c40b05f 100644
--- a/debian/patches/doc-hash-tab-completion.patch
+++ b/debian/patches/doc-hash-tab-completion.patch
@@ -1,4 +1,4 @@
1From 465d1a333520edbd2f0fac77c76e06bdd1d94cb9 Mon Sep 17 00:00:00 2001 1From 1d108ef62050b4368e24e1efada16ec88c177fb8 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:11 +0000 3Date: Sun, 9 Feb 2014 16:10:11 +0000
4Subject: Document that HashKnownHosts may break tab-completion 4Subject: Document that HashKnownHosts may break tab-completion
@@ -13,10 +13,10 @@ Patch-Name: doc-hash-tab-completion.patch
13 1 file changed, 3 insertions(+) 13 1 file changed, 3 insertions(+)
14 14
15diff --git a/ssh_config.5 b/ssh_config.5 15diff --git a/ssh_config.5 b/ssh_config.5
16index 3c6b9d4..85f306c 100644 16index 4bf7cbb..1d500e9 100644
17--- a/ssh_config.5 17--- a/ssh_config.5
18+++ b/ssh_config.5 18+++ b/ssh_config.5
19@@ -734,6 +734,9 @@ Note that existing names and addresses in known hosts files 19@@ -740,6 +740,9 @@ Note that existing names and addresses in known hosts files
20 will not be converted automatically, 20 will not be converted automatically,
21 but may be manually hashed using 21 but may be manually hashed using
22 .Xr ssh-keygen 1 . 22 .Xr ssh-keygen 1 .
diff --git a/debian/patches/doc-upstart.patch b/debian/patches/doc-upstart.patch
index a09ac77e4..da8fc7ed4 100644
--- a/debian/patches/doc-upstart.patch
+++ b/debian/patches/doc-upstart.patch
@@ -1,4 +1,4 @@
1From faf2466c7933f1c4225c8a8ceb503e24e4228ab9 Mon Sep 17 00:00:00 2001 1From 111de26347496af3f6ed04849fd29bc4bf1c2cea Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@ubuntu.com> 2From: Colin Watson <cjwatson@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:10:12 +0000 3Date: Sun, 9 Feb 2014 16:10:12 +0000
4Subject: Refer to ssh's Upstart job as well as its init script 4Subject: Refer to ssh's Upstart job as well as its init script
diff --git a/debian/patches/fix-case-sensitive-matching.patch b/debian/patches/fix-case-sensitive-matching.patch
deleted file mode 100644
index c721b5a0a..000000000
--- a/debian/patches/fix-case-sensitive-matching.patch
+++ /dev/null
@@ -1,41 +0,0 @@
1From efb58a7258484c31c702f9093b7a726da9eab682 Mon Sep 17 00:00:00 2001
2From: Damien Miller <djm@mindrot.org>
3Date: Tue, 4 Feb 2014 11:26:04 +1100
4Subject: Unbreak case-sensitive matching of ssh_config
5
6 - djm@cvs.openbsd.org 2014/02/04 00:24:29
7 [ssh.c]
8 delay lowercasing of hostname until right before hostname
9 canonicalisation to unbreak case-sensitive matching of ssh_config;
10 reported by Ike Devolder; ok markus@
11
12Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=d56b44d2dfa093883a5c4e91be3f72d99946b170
13Bug-Debian: http://bugs.debian.org/738619
14Forwarded: not-needed
15Last-Update: 2014-02-11
16
17Patch-Name: fix-case-sensitive-matching.patch
18---
19 ssh.c | 2 +-
20 1 file changed, 1 insertion(+), 1 deletion(-)
21
22diff --git a/ssh.c b/ssh.c
23index 0cea713..5d5d4de 100644
24--- a/ssh.c
25+++ b/ssh.c
26@@ -780,7 +780,6 @@ main(int ac, char **av)
27 if (!host)
28 usage();
29
30- lowercase(host);
31 host_arg = xstrdup(host);
32
33 OpenSSL_add_all_algorithms();
34@@ -914,6 +913,7 @@ main(int ac, char **av)
35 }
36
37 /* If canonicalization requested then try to apply it */
38+ lowercase(host);
39 if (options.canonicalize_hostname != SSH_CANONICALISE_NO)
40 addrs = resolve_canonicalize(&host, options.port);
41 /*
diff --git a/debian/patches/getsockname-error.patch b/debian/patches/getsockname-error.patch
deleted file mode 100644
index 300151cab..000000000
--- a/debian/patches/getsockname-error.patch
+++ /dev/null
@@ -1,27 +0,0 @@
1From 6dbd954a28d3fc2631f1c0b42c23452e1e493e6f Mon Sep 17 00:00:00 2001
2From: Damien Miller <djm@mindrot.org>
3Date: Sat, 15 Feb 2014 02:08:20 +0000
4Subject: Skip get_sock_port call for c->sock==-1
5
6Origin: upstream, https://bugzilla.mindrot.org/show_bug.cgi?id=2200
7Bug-Debian: http://bugs.debian.org/738693
8Last-Update: 2014-02-15
9
10Patch-Name: getsockname-error.patch
11---
12 channels.c | 2 +-
13 1 file changed, 1 insertion(+), 1 deletion(-)
14
15diff --git a/channels.c b/channels.c
16index e741f29..8e66265 100644
17--- a/channels.c
18+++ b/channels.c
19@@ -1386,7 +1386,7 @@ port_open_helper(Channel *c, char *rtype)
20 int direct;
21 char buf[1024];
22 char *local_ipaddr = get_local_ipaddr(c->sock);
23- int local_port = get_sock_port(c->sock, 1);
24+ int local_port = c->sock == -1 ? 65536 : get_sock_port(c->sock, 1);
25 char *remote_ipaddr = get_peer_ipaddr(c->sock);
26 int remote_port = get_peer_port(c->sock);
27
diff --git a/debian/patches/gnome-ssh-askpass2-icon.patch b/debian/patches/gnome-ssh-askpass2-icon.patch
index 951284cf5..dab518f65 100644
--- a/debian/patches/gnome-ssh-askpass2-icon.patch
+++ b/debian/patches/gnome-ssh-askpass2-icon.patch
@@ -1,4 +1,4 @@
1From fd8d46990dfe572955a6eda524fcbf9e9efefa75 Mon Sep 17 00:00:00 2001 1From b7df8fdb32f3d33b70ff8733cb0c39417e367534 Mon Sep 17 00:00:00 2001
2From: Vincent Untz <vuntz@ubuntu.com> 2From: Vincent Untz <vuntz@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:10:16 +0000 3Date: Sun, 9 Feb 2014 16:10:16 +0000
4Subject: Give the ssh-askpass-gnome window a default icon 4Subject: Give the ssh-askpass-gnome window a default icon
diff --git a/debian/patches/gssapi.patch b/debian/patches/gssapi.patch
index 90a21db99..d8439bf03 100644
--- a/debian/patches/gssapi.patch
+++ b/debian/patches/gssapi.patch
@@ -1,4 +1,4 @@
1From 429c595dbaff7f7c2b3a53fe4235211f6d788025 Mon Sep 17 00:00:00 2001 1From 9dfcd1a0e691c1cad34b168e27b3ed31ab6986cd Mon Sep 17 00:00:00 2001
2From: Simon Wilkinson <simon@sxw.org.uk> 2From: Simon Wilkinson <simon@sxw.org.uk>
3Date: Sun, 9 Feb 2014 16:09:48 +0000 3Date: Sun, 9 Feb 2014 16:09:48 +0000
4Subject: GSSAPI key exchange support 4Subject: GSSAPI key exchange support
@@ -179,7 +179,7 @@ index 0000000..f117a33
179+ (from jbasney AT ncsa.uiuc.edu) 179+ (from jbasney AT ncsa.uiuc.edu)
180+ <gssapi-with-mic support is Bugzilla #1008> 180+ <gssapi-with-mic support is Bugzilla #1008>
181diff --git a/Makefile.in b/Makefile.in 181diff --git a/Makefile.in b/Makefile.in
182index a8aa127..35c6fd6 100644 182index 28a8ec4..ee1d2c3 100644
183--- a/Makefile.in 183--- a/Makefile.in
184+++ b/Makefile.in 184+++ b/Makefile.in
185@@ -72,6 +72,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ 185@@ -72,6 +72,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
@@ -188,10 +188,10 @@ index a8aa127..35c6fd6 100644
188 kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ 188 kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
189+ kexgssc.o \ 189+ kexgssc.o \
190 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ 190 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
191 jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ 191 ssh-pkcs11.o krl.o smult_curve25519_ref.o \
192 kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ 192 kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
193@@ -91,7 +92,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ 193@@ -91,7 +92,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
194 auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ 194 auth2-none.o auth2-passwd.o auth2-pubkey.o \
195 monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ 195 monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \
196 kexc25519s.o auth-krb5.o \ 196 kexc25519s.o auth-krb5.o \
197- auth2-gss.o gss-serv.o gss-serv-krb5.o \ 197- auth2-gss.o gss-serv.o gss-serv-krb5.o \
@@ -251,11 +251,11 @@ index 6c62bdf..69a1a53 100644
251 return (krb5_cc_resolve(ctx, ccname, ccache)); 251 return (krb5_cc_resolve(ctx, ccname, ccache));
252 } 252 }
253diff --git a/auth2-gss.c b/auth2-gss.c 253diff --git a/auth2-gss.c b/auth2-gss.c
254index 638d8f8..b8db820 100644 254index c28a705..3ff2d72 100644
255--- a/auth2-gss.c 255--- a/auth2-gss.c
256+++ b/auth2-gss.c 256+++ b/auth2-gss.c
257@@ -1,7 +1,7 @@ 257@@ -1,7 +1,7 @@
258 /* $OpenBSD: auth2-gss.c,v 1.20 2013/05/17 00:13:13 djm Exp $ */ 258 /* $OpenBSD: auth2-gss.c,v 1.21 2014/02/26 20:28:44 djm Exp $ */
259 259
260 /* 260 /*
261- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 261- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -304,7 +304,7 @@ index 638d8f8..b8db820 100644
304 /* 304 /*
305 * We only support those mechanisms that we know about (ie ones that we know 305 * We only support those mechanisms that we know about (ie ones that we know
306 * how to check local user kuserok and the like) 306 * how to check local user kuserok and the like)
307@@ -240,7 +274,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) 307@@ -235,7 +269,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
308 308
309 packet_check_eom(); 309 packet_check_eom();
310 310
@@ -314,7 +314,7 @@ index 638d8f8..b8db820 100644
314 314
315 authctxt->postponed = 0; 315 authctxt->postponed = 0;
316 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 316 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
317@@ -275,7 +310,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) 317@@ -270,7 +305,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
318 gssbuf.length = buffer_len(&b); 318 gssbuf.length = buffer_len(&b);
319 319
320 if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) 320 if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
@@ -324,7 +324,7 @@ index 638d8f8..b8db820 100644
324 else 324 else
325 logit("GSSAPI MIC check failed"); 325 logit("GSSAPI MIC check failed");
326 326
327@@ -290,6 +326,12 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) 327@@ -285,6 +321,12 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
328 userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); 328 userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
329 } 329 }
330 330
@@ -338,7 +338,7 @@ index 638d8f8..b8db820 100644
338 "gssapi-with-mic", 338 "gssapi-with-mic",
339 userauth_gssapi, 339 userauth_gssapi,
340diff --git a/auth2.c b/auth2.c 340diff --git a/auth2.c b/auth2.c
341index f0cab8c..6ed8f04 100644 341index a5490c0..fbe3e1b 100644
342--- a/auth2.c 342--- a/auth2.c
343+++ b/auth2.c 343+++ b/auth2.c
344@@ -69,6 +69,7 @@ extern Authmethod method_passwd; 344@@ -69,6 +69,7 @@ extern Authmethod method_passwd;
@@ -348,17 +348,17 @@ index f0cab8c..6ed8f04 100644
348+extern Authmethod method_gsskeyex; 348+extern Authmethod method_gsskeyex;
349 extern Authmethod method_gssapi; 349 extern Authmethod method_gssapi;
350 #endif 350 #endif
351 #ifdef JPAKE 351
352@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { 352@@ -76,6 +77,7 @@ Authmethod *authmethods[] = {
353 &method_none, 353 &method_none,
354 &method_pubkey, 354 &method_pubkey,
355 #ifdef GSSAPI 355 #ifdef GSSAPI
356+ &method_gsskeyex, 356+ &method_gsskeyex,
357 &method_gssapi, 357 &method_gssapi,
358 #endif 358 #endif
359 #ifdef JPAKE 359 &method_passwd,
360diff --git a/clientloop.c b/clientloop.c 360diff --git a/clientloop.c b/clientloop.c
361index f30c8b6..cc23e35 100644 361index 59ad3a2..6d8cd7d 100644
362--- a/clientloop.c 362--- a/clientloop.c
363+++ b/clientloop.c 363+++ b/clientloop.c
364@@ -111,6 +111,10 @@ 364@@ -111,6 +111,10 @@
@@ -389,10 +389,10 @@ index f30c8b6..cc23e35 100644
389 debug("need rekeying"); 389 debug("need rekeying");
390 xxx_kex->done = 0; 390 xxx_kex->done = 0;
391diff --git a/config.h.in b/config.h.in 391diff --git a/config.h.in b/config.h.in
392index 075c619..906e549 100644 392index 0401ad1..6bc422c 100644
393--- a/config.h.in 393--- a/config.h.in
394+++ b/config.h.in 394+++ b/config.h.in
395@@ -1616,6 +1616,9 @@ 395@@ -1622,6 +1622,9 @@
396 /* Use btmp to log bad logins */ 396 /* Use btmp to log bad logins */
397 #undef USE_BTMP 397 #undef USE_BTMP
398 398
@@ -402,7 +402,7 @@ index 075c619..906e549 100644
402 /* Use libedit for sftp */ 402 /* Use libedit for sftp */
403 #undef USE_LIBEDIT 403 #undef USE_LIBEDIT
404 404
405@@ -1631,6 +1634,9 @@ 405@@ -1637,6 +1640,9 @@
406 /* Use PIPES instead of a socketpair() */ 406 /* Use PIPES instead of a socketpair() */
407 #undef USE_PIPES 407 #undef USE_PIPES
408 408
@@ -413,7 +413,7 @@ index 075c619..906e549 100644
413 #undef USE_SOLARIS_PROCESS_CONTRACTS 413 #undef USE_SOLARIS_PROCESS_CONTRACTS
414 414
415diff --git a/configure b/configure 415diff --git a/configure b/configure
416index 2d714ac..5a9db2d 100755 416index d690393..b6b5b6d 100755
417--- a/configure 417--- a/configure
418+++ b/configure 418+++ b/configure
419@@ -7170,6 +7170,63 @@ $as_echo "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h 419@@ -7170,6 +7170,63 @@ $as_echo "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h
@@ -481,7 +481,7 @@ index 2d714ac..5a9db2d 100755
481 ac_fn_c_check_decl "$LINENO" "AU_IPv4" "ac_cv_have_decl_AU_IPv4" "$ac_includes_default" 481 ac_fn_c_check_decl "$LINENO" "AU_IPv4" "ac_cv_have_decl_AU_IPv4" "$ac_includes_default"
482 if test "x$ac_cv_have_decl_AU_IPv4" = xyes; then : 482 if test "x$ac_cv_have_decl_AU_IPv4" = xyes; then :
483diff --git a/configure.ac b/configure.ac 483diff --git a/configure.ac b/configure.ac
484index dfd32cd..90eebf5 100644 484index 7c6ce08..d235fb0 100644
485--- a/configure.ac 485--- a/configure.ac
486+++ b/configure.ac 486+++ b/configure.ac
487@@ -584,6 +584,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) 487@@ -584,6 +584,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
@@ -992,11 +992,11 @@ index 759fa10..e678a27 100644
992 992
993 #endif /* KRB5 */ 993 #endif /* KRB5 */
994diff --git a/gss-serv.c b/gss-serv.c 994diff --git a/gss-serv.c b/gss-serv.c
995index 95348e2..feb1ed7 100644 995index e61b37b..c33463b 100644
996--- a/gss-serv.c 996--- a/gss-serv.c
997+++ b/gss-serv.c 997+++ b/gss-serv.c
998@@ -1,7 +1,7 @@ 998@@ -1,7 +1,7 @@
999 /* $OpenBSD: gss-serv.c,v 1.24 2013/07/20 01:55:13 djm Exp $ */ 999 /* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */
1000 1000
1001 /* 1001 /*
1002- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 1002- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -1028,7 +1028,7 @@ index 95348e2..feb1ed7 100644
1028 1028
1029 #ifdef KRB5 1029 #ifdef KRB5
1030 extern ssh_gssapi_mech gssapi_kerberos_mech; 1030 extern ssh_gssapi_mech gssapi_kerberos_mech;
1031@@ -81,25 +87,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) 1031@@ -100,25 +106,32 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
1032 char lname[MAXHOSTNAMELEN]; 1032 char lname[MAXHOSTNAMELEN];
1033 gss_OID_set oidset; 1033 gss_OID_set oidset;
1034 1034
@@ -1075,7 +1075,7 @@ index 95348e2..feb1ed7 100644
1075 } 1075 }
1076 1076
1077 /* Privileged */ 1077 /* Privileged */
1078@@ -114,6 +127,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) 1078@@ -133,6 +146,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
1079 } 1079 }
1080 1080
1081 /* Unprivileged */ 1081 /* Unprivileged */
@@ -1105,7 +1105,7 @@ index 95348e2..feb1ed7 100644
1105 void 1105 void
1106 ssh_gssapi_supported_oids(gss_OID_set *oidset) 1106 ssh_gssapi_supported_oids(gss_OID_set *oidset)
1107 { 1107 {
1108@@ -123,7 +159,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) 1108@@ -142,7 +178,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset)
1109 gss_OID_set supported; 1109 gss_OID_set supported;
1110 1110
1111 gss_create_empty_oid_set(&min_status, oidset); 1111 gss_create_empty_oid_set(&min_status, oidset);
@@ -1116,7 +1116,7 @@ index 95348e2..feb1ed7 100644
1116 1116
1117 while (supported_mechs[i]->name != NULL) { 1117 while (supported_mechs[i]->name != NULL) {
1118 if (GSS_ERROR(gss_test_oid_set_member(&min_status, 1118 if (GSS_ERROR(gss_test_oid_set_member(&min_status,
1119@@ -249,8 +287,48 @@ OM_uint32 1119@@ -268,8 +306,48 @@ OM_uint32
1120 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) 1120 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
1121 { 1121 {
1122 int i = 0; 1122 int i = 0;
@@ -1166,7 +1166,7 @@ index 95348e2..feb1ed7 100644
1166 1166
1167 client->mech = NULL; 1167 client->mech = NULL;
1168 1168
1169@@ -265,6 +343,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) 1169@@ -284,6 +362,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
1170 if (client->mech == NULL) 1170 if (client->mech == NULL)
1171 return GSS_S_FAILURE; 1171 return GSS_S_FAILURE;
1172 1172
@@ -1180,7 +1180,7 @@ index 95348e2..feb1ed7 100644
1180 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, 1180 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
1181 &client->displayname, NULL))) { 1181 &client->displayname, NULL))) {
1182 ssh_gssapi_error(ctx); 1182 ssh_gssapi_error(ctx);
1183@@ -282,6 +367,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) 1183@@ -301,6 +386,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
1184 return (ctx->major); 1184 return (ctx->major);
1185 } 1185 }
1186 1186
@@ -1189,7 +1189,7 @@ index 95348e2..feb1ed7 100644
1189 /* We can't copy this structure, so we just move the pointer to it */ 1189 /* We can't copy this structure, so we just move the pointer to it */
1190 client->creds = ctx->client_creds; 1190 client->creds = ctx->client_creds;
1191 ctx->client_creds = GSS_C_NO_CREDENTIAL; 1191 ctx->client_creds = GSS_C_NO_CREDENTIAL;
1192@@ -329,7 +416,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) 1192@@ -348,7 +435,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep)
1193 1193
1194 /* Privileged */ 1194 /* Privileged */
1195 int 1195 int
@@ -1198,7 +1198,7 @@ index 95348e2..feb1ed7 100644
1198 { 1198 {
1199 OM_uint32 lmin; 1199 OM_uint32 lmin;
1200 1200
1201@@ -339,9 +426,11 @@ ssh_gssapi_userok(char *user) 1201@@ -358,9 +445,11 @@ ssh_gssapi_userok(char *user)
1202 return 0; 1202 return 0;
1203 } 1203 }
1204 if (gssapi_client.mech && gssapi_client.mech->userok) 1204 if (gssapi_client.mech && gssapi_client.mech->userok)
@@ -1212,7 +1212,7 @@ index 95348e2..feb1ed7 100644
1212 /* Destroy delegated credentials if userok fails */ 1212 /* Destroy delegated credentials if userok fails */
1213 gss_release_buffer(&lmin, &gssapi_client.displayname); 1213 gss_release_buffer(&lmin, &gssapi_client.displayname);
1214 gss_release_buffer(&lmin, &gssapi_client.exportedname); 1214 gss_release_buffer(&lmin, &gssapi_client.exportedname);
1215@@ -354,14 +443,90 @@ ssh_gssapi_userok(char *user) 1215@@ -374,14 +463,90 @@ ssh_gssapi_userok(char *user)
1216 return (0); 1216 return (0);
1217 } 1217 }
1218 1218
@@ -1310,7 +1310,7 @@ index 95348e2..feb1ed7 100644
1310 1310
1311 #endif 1311 #endif
1312diff --git a/kex.c b/kex.c 1312diff --git a/kex.c b/kex.c
1313index 616484b..49d0fc8 100644 1313index 74e2b86..d114ee3 100644
1314--- a/kex.c 1314--- a/kex.c
1315+++ b/kex.c 1315+++ b/kex.c
1316@@ -51,6 +51,10 @@ 1316@@ -51,6 +51,10 @@
@@ -1351,7 +1351,7 @@ index 616484b..49d0fc8 100644
1351 } 1351 }
1352 1352
1353diff --git a/kex.h b/kex.h 1353diff --git a/kex.h b/kex.h
1354index 1aa3ec2..8fbcb2b 100644 1354index c85680e..ea698c4 100644
1355--- a/kex.h 1355--- a/kex.h
1356+++ b/kex.h 1356+++ b/kex.h
1357@@ -76,6 +76,9 @@ enum kex_exchange { 1357@@ -76,6 +76,9 @@ enum kex_exchange {
@@ -1364,7 +1364,7 @@ index 1aa3ec2..8fbcb2b 100644
1364 KEX_MAX 1364 KEX_MAX
1365 }; 1365 };
1366 1366
1367@@ -136,6 +139,12 @@ struct Kex { 1367@@ -135,6 +138,12 @@ struct Kex {
1368 int flags; 1368 int flags;
1369 int hash_alg; 1369 int hash_alg;
1370 int ec_nid; 1370 int ec_nid;
@@ -1377,7 +1377,7 @@ index 1aa3ec2..8fbcb2b 100644
1377 char *client_version_string; 1377 char *client_version_string;
1378 char *server_version_string; 1378 char *server_version_string;
1379 int (*verify_host_key)(Key *); 1379 int (*verify_host_key)(Key *);
1380@@ -168,6 +177,11 @@ void kexecdh_server(Kex *); 1380@@ -167,6 +176,11 @@ void kexecdh_server(Kex *);
1381 void kexc25519_client(Kex *); 1381 void kexc25519_client(Kex *);
1382 void kexc25519_server(Kex *); 1382 void kexc25519_server(Kex *);
1383 1383
@@ -2023,7 +2023,7 @@ index 0000000..8095259
2023+} 2023+}
2024+#endif /* GSSAPI */ 2024+#endif /* GSSAPI */
2025diff --git a/key.c b/key.c 2025diff --git a/key.c b/key.c
2026index 9142338..7ac844c 100644 2026index 168e1b7..3d640e7 100644
2027--- a/key.c 2027--- a/key.c
2028+++ b/key.c 2028+++ b/key.c
2029@@ -985,6 +985,7 @@ static const struct keytype keytypes[] = { 2029@@ -985,6 +985,7 @@ static const struct keytype keytypes[] = {
@@ -2056,10 +2056,10 @@ index d8ad13d..c8aeba2 100644
2056 }; 2056 };
2057 enum fp_type { 2057 enum fp_type {
2058diff --git a/monitor.c b/monitor.c 2058diff --git a/monitor.c b/monitor.c
2059index 03baf1e..a777c4c 100644 2059index 531c4f9..2918814 100644
2060--- a/monitor.c 2060--- a/monitor.c
2061+++ b/monitor.c 2061+++ b/monitor.c
2062@@ -181,6 +181,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *); 2062@@ -175,6 +175,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
2063 int mm_answer_gss_accept_ctx(int, Buffer *); 2063 int mm_answer_gss_accept_ctx(int, Buffer *);
2064 int mm_answer_gss_userok(int, Buffer *); 2064 int mm_answer_gss_userok(int, Buffer *);
2065 int mm_answer_gss_checkmic(int, Buffer *); 2065 int mm_answer_gss_checkmic(int, Buffer *);
@@ -2068,15 +2068,13 @@ index 03baf1e..a777c4c 100644
2068 #endif 2068 #endif
2069 2069
2070 #ifdef SSH_AUDIT_EVENTS 2070 #ifdef SSH_AUDIT_EVENTS
2071@@ -253,6 +255,7 @@ struct mon_table mon_dispatch_proto20[] = { 2071@@ -247,11 +249,18 @@ struct mon_table mon_dispatch_proto20[] = {
2072 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 2072 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
2073 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 2073 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
2074 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 2074 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
2075+ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, 2075+ {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
2076 #endif 2076 #endif
2077 #ifdef JPAKE 2077 {0, 0, NULL}
2078 {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
2079@@ -265,6 +268,12 @@ struct mon_table mon_dispatch_proto20[] = {
2080 }; 2078 };
2081 2079
2082 struct mon_table mon_dispatch_postauth20[] = { 2080 struct mon_table mon_dispatch_postauth20[] = {
@@ -2089,7 +2087,7 @@ index 03baf1e..a777c4c 100644
2089 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 2087 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
2090 {MONITOR_REQ_SIGN, 0, mm_answer_sign}, 2088 {MONITOR_REQ_SIGN, 0, mm_answer_sign},
2091 {MONITOR_REQ_PTY, 0, mm_answer_pty}, 2089 {MONITOR_REQ_PTY, 0, mm_answer_pty},
2092@@ -373,6 +382,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) 2090@@ -360,6 +369,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
2093 /* Permit requests for moduli and signatures */ 2091 /* Permit requests for moduli and signatures */
2094 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 2092 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
2095 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 2093 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
@@ -2100,7 +2098,7 @@ index 03baf1e..a777c4c 100644
2100 } else { 2098 } else {
2101 mon_dispatch = mon_dispatch_proto15; 2099 mon_dispatch = mon_dispatch_proto15;
2102 2100
2103@@ -487,6 +500,10 @@ monitor_child_postauth(struct monitor *pmonitor) 2101@@ -465,6 +478,10 @@ monitor_child_postauth(struct monitor *pmonitor)
2104 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 2102 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
2105 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 2103 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
2106 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 2104 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -2111,7 +2109,7 @@ index 03baf1e..a777c4c 100644
2111 } else { 2109 } else {
2112 mon_dispatch = mon_dispatch_postauth15; 2110 mon_dispatch = mon_dispatch_postauth15;
2113 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 2111 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
2114@@ -1856,6 +1873,13 @@ mm_get_kex(Buffer *m) 2112@@ -1834,6 +1851,13 @@ mm_get_kex(Buffer *m)
2115 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 2113 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
2116 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 2114 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
2117 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2115 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
@@ -2125,7 +2123,7 @@ index 03baf1e..a777c4c 100644
2125 kex->server = 1; 2123 kex->server = 1;
2126 kex->hostkey_type = buffer_get_int(m); 2124 kex->hostkey_type = buffer_get_int(m);
2127 kex->kex_type = buffer_get_int(m); 2125 kex->kex_type = buffer_get_int(m);
2128@@ -2063,6 +2087,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) 2126@@ -2041,6 +2065,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
2129 OM_uint32 major; 2127 OM_uint32 major;
2130 u_int len; 2128 u_int len;
2131 2129
@@ -2135,7 +2133,7 @@ index 03baf1e..a777c4c 100644
2135 goid.elements = buffer_get_string(m, &len); 2133 goid.elements = buffer_get_string(m, &len);
2136 goid.length = len; 2134 goid.length = len;
2137 2135
2138@@ -2090,6 +2117,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) 2136@@ -2068,6 +2095,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2139 OM_uint32 flags = 0; /* GSI needs this */ 2137 OM_uint32 flags = 0; /* GSI needs this */
2140 u_int len; 2138 u_int len;
2141 2139
@@ -2145,7 +2143,7 @@ index 03baf1e..a777c4c 100644
2145 in.value = buffer_get_string(m, &len); 2143 in.value = buffer_get_string(m, &len);
2146 in.length = len; 2144 in.length = len;
2147 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2145 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
2148@@ -2107,6 +2137,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) 2146@@ -2085,6 +2115,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2149 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2147 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2150 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2148 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2151 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2149 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
@@ -2153,7 +2151,7 @@ index 03baf1e..a777c4c 100644
2153 } 2151 }
2154 return (0); 2152 return (0);
2155 } 2153 }
2156@@ -2118,6 +2149,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) 2154@@ -2096,6 +2127,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2157 OM_uint32 ret; 2155 OM_uint32 ret;
2158 u_int len; 2156 u_int len;
2159 2157
@@ -2163,7 +2161,7 @@ index 03baf1e..a777c4c 100644
2163 gssbuf.value = buffer_get_string(m, &len); 2161 gssbuf.value = buffer_get_string(m, &len);
2164 gssbuf.length = len; 2162 gssbuf.length = len;
2165 mic.value = buffer_get_string(m, &len); 2163 mic.value = buffer_get_string(m, &len);
2166@@ -2144,7 +2178,11 @@ mm_answer_gss_userok(int sock, Buffer *m) 2164@@ -2122,7 +2156,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2167 { 2165 {
2168 int authenticated; 2166 int authenticated;
2169 2167
@@ -2176,7 +2174,7 @@ index 03baf1e..a777c4c 100644
2176 2174
2177 buffer_clear(m); 2175 buffer_clear(m);
2178 buffer_put_int(m, authenticated); 2176 buffer_put_int(m, authenticated);
2179@@ -2157,6 +2195,74 @@ mm_answer_gss_userok(int sock, Buffer *m) 2177@@ -2135,5 +2173,73 @@ mm_answer_gss_userok(int sock, Buffer *m)
2180 /* Monitor loop will terminate if authenticated */ 2178 /* Monitor loop will terminate if authenticated */
2181 return (authenticated); 2179 return (authenticated);
2182 } 2180 }
@@ -2250,12 +2248,11 @@ index 03baf1e..a777c4c 100644
2250+ 2248+
2251 #endif /* GSSAPI */ 2249 #endif /* GSSAPI */
2252 2250
2253 #ifdef JPAKE
2254diff --git a/monitor.h b/monitor.h 2251diff --git a/monitor.h b/monitor.h
2255index 2caa469..315ef99 100644 2252index 5bc41b5..7f32b0c 100644
2256--- a/monitor.h 2253--- a/monitor.h
2257+++ b/monitor.h 2254+++ b/monitor.h
2258@@ -70,6 +70,9 @@ enum monitor_reqtype { 2255@@ -65,6 +65,9 @@ enum monitor_reqtype {
2259 MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, 2256 MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
2260 MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, 2257 MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
2261 2258
@@ -2266,10 +2263,10 @@ index 2caa469..315ef99 100644
2266 2263
2267 struct mm_master; 2264 struct mm_master;
2268diff --git a/monitor_wrap.c b/monitor_wrap.c 2265diff --git a/monitor_wrap.c b/monitor_wrap.c
2269index 4ce4696..44019f3 100644 2266index 1a47e41..60b987d 100644
2270--- a/monitor_wrap.c 2267--- a/monitor_wrap.c
2271+++ b/monitor_wrap.c 2268+++ b/monitor_wrap.c
2272@@ -1273,7 +1273,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 2269@@ -1271,7 +1271,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
2273 } 2270 }
2274 2271
2275 int 2272 int
@@ -2278,7 +2275,7 @@ index 4ce4696..44019f3 100644
2278 { 2275 {
2279 Buffer m; 2276 Buffer m;
2280 int authenticated = 0; 2277 int authenticated = 0;
2281@@ -1290,6 +1290,51 @@ mm_ssh_gssapi_userok(char *user) 2278@@ -1288,5 +1288,50 @@ mm_ssh_gssapi_userok(char *user)
2282 debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 2279 debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
2283 return (authenticated); 2280 return (authenticated);
2284 } 2281 }
@@ -2329,9 +2326,8 @@ index 4ce4696..44019f3 100644
2329+ 2326+
2330 #endif /* GSSAPI */ 2327 #endif /* GSSAPI */
2331 2328
2332 #ifdef JPAKE
2333diff --git a/monitor_wrap.h b/monitor_wrap.h 2329diff --git a/monitor_wrap.h b/monitor_wrap.h
2334index 0c7f2e3..ec9b9b1 100644 2330index 18c2501..a4e9d24 100644
2335--- a/monitor_wrap.h 2331--- a/monitor_wrap.h
2336+++ b/monitor_wrap.h 2332+++ b/monitor_wrap.h
2337@@ -58,8 +58,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *); 2333@@ -58,8 +58,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(Key *);
@@ -2347,10 +2343,10 @@ index 0c7f2e3..ec9b9b1 100644
2347 2343
2348 #ifdef USE_PAM 2344 #ifdef USE_PAM
2349diff --git a/readconf.c b/readconf.c 2345diff --git a/readconf.c b/readconf.c
2350index 9c7e73d..cb8bcb2 100644 2346index dc884c9..7613ff2 100644
2351--- a/readconf.c 2347--- a/readconf.c
2352+++ b/readconf.c 2348+++ b/readconf.c
2353@@ -140,6 +140,8 @@ typedef enum { 2349@@ -141,6 +141,8 @@ typedef enum {
2354 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 2350 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
2355 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 2351 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
2356 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 2352 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
@@ -2359,7 +2355,7 @@ index 9c7e73d..cb8bcb2 100644
2359 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 2355 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
2360 oSendEnv, oControlPath, oControlMaster, oControlPersist, 2356 oSendEnv, oControlPath, oControlMaster, oControlPersist,
2361 oHashKnownHosts, 2357 oHashKnownHosts,
2362@@ -182,10 +184,19 @@ static struct { 2358@@ -183,10 +185,19 @@ static struct {
2363 { "afstokenpassing", oUnsupported }, 2359 { "afstokenpassing", oUnsupported },
2364 #if defined(GSSAPI) 2360 #if defined(GSSAPI)
2365 { "gssapiauthentication", oGssAuthentication }, 2361 { "gssapiauthentication", oGssAuthentication },
@@ -2379,7 +2375,7 @@ index 9c7e73d..cb8bcb2 100644
2379 #endif 2375 #endif
2380 { "fallbacktorsh", oDeprecated }, 2376 { "fallbacktorsh", oDeprecated },
2381 { "usersh", oDeprecated }, 2377 { "usersh", oDeprecated },
2382@@ -839,10 +850,30 @@ parse_time: 2378@@ -841,10 +852,30 @@ parse_time:
2383 intptr = &options->gss_authentication; 2379 intptr = &options->gss_authentication;
2384 goto parse_flag; 2380 goto parse_flag;
2385 2381
@@ -2410,7 +2406,7 @@ index 9c7e73d..cb8bcb2 100644
2410 case oBatchMode: 2406 case oBatchMode:
2411 intptr = &options->batch_mode; 2407 intptr = &options->batch_mode;
2412 goto parse_flag; 2408 goto parse_flag;
2413@@ -1488,7 +1519,12 @@ initialize_options(Options * options) 2409@@ -1497,7 +1528,12 @@ initialize_options(Options * options)
2414 options->pubkey_authentication = -1; 2410 options->pubkey_authentication = -1;
2415 options->challenge_response_authentication = -1; 2411 options->challenge_response_authentication = -1;
2416 options->gss_authentication = -1; 2412 options->gss_authentication = -1;
@@ -2423,7 +2419,7 @@ index 9c7e73d..cb8bcb2 100644
2423 options->password_authentication = -1; 2419 options->password_authentication = -1;
2424 options->kbd_interactive_authentication = -1; 2420 options->kbd_interactive_authentication = -1;
2425 options->kbd_interactive_devices = NULL; 2421 options->kbd_interactive_devices = NULL;
2426@@ -1594,8 +1630,14 @@ fill_default_options(Options * options) 2422@@ -1616,8 +1652,14 @@ fill_default_options(Options * options)
2427 options->challenge_response_authentication = 1; 2423 options->challenge_response_authentication = 1;
2428 if (options->gss_authentication == -1) 2424 if (options->gss_authentication == -1)
2429 options->gss_authentication = 0; 2425 options->gss_authentication = 0;
@@ -2439,7 +2435,7 @@ index 9c7e73d..cb8bcb2 100644
2439 options->password_authentication = 1; 2435 options->password_authentication = 1;
2440 if (options->kbd_interactive_authentication == -1) 2436 if (options->kbd_interactive_authentication == -1)
2441diff --git a/readconf.h b/readconf.h 2437diff --git a/readconf.h b/readconf.h
2442index 2d7ea9f..826c676 100644 2438index 75e3f8f..5cc97f0 100644
2443--- a/readconf.h 2439--- a/readconf.h
2444+++ b/readconf.h 2440+++ b/readconf.h
2445@@ -54,7 +54,12 @@ typedef struct { 2441@@ -54,7 +54,12 @@ typedef struct {
@@ -2456,7 +2452,7 @@ index 2d7ea9f..826c676 100644
2456 * authentication. */ 2452 * authentication. */
2457 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ 2453 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
2458diff --git a/servconf.c b/servconf.c 2454diff --git a/servconf.c b/servconf.c
2459index 9bcd05b..29209e4 100644 2455index 7ba65d5..0083cf8 100644
2460--- a/servconf.c 2456--- a/servconf.c
2461+++ b/servconf.c 2457+++ b/servconf.c
2462@@ -108,7 +108,10 @@ initialize_server_options(ServerOptions *options) 2458@@ -108,7 +108,10 @@ initialize_server_options(ServerOptions *options)
@@ -2470,7 +2466,7 @@ index 9bcd05b..29209e4 100644
2470 options->password_authentication = -1; 2466 options->password_authentication = -1;
2471 options->kbd_interactive_authentication = -1; 2467 options->kbd_interactive_authentication = -1;
2472 options->challenge_response_authentication = -1; 2468 options->challenge_response_authentication = -1;
2473@@ -245,8 +248,14 @@ fill_default_server_options(ServerOptions *options) 2469@@ -244,8 +247,14 @@ fill_default_server_options(ServerOptions *options)
2474 options->kerberos_get_afs_token = 0; 2470 options->kerberos_get_afs_token = 0;
2475 if (options->gss_authentication == -1) 2471 if (options->gss_authentication == -1)
2476 options->gss_authentication = 0; 2472 options->gss_authentication = 0;
@@ -2485,7 +2481,7 @@ index 9bcd05b..29209e4 100644
2485 if (options->password_authentication == -1) 2481 if (options->password_authentication == -1)
2486 options->password_authentication = 1; 2482 options->password_authentication = 1;
2487 if (options->kbd_interactive_authentication == -1) 2483 if (options->kbd_interactive_authentication == -1)
2488@@ -343,7 +352,9 @@ typedef enum { 2484@@ -340,7 +349,9 @@ typedef enum {
2489 sBanner, sUseDNS, sHostbasedAuthentication, 2485 sBanner, sUseDNS, sHostbasedAuthentication,
2490 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 2486 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
2491 sClientAliveCountMax, sAuthorizedKeysFile, 2487 sClientAliveCountMax, sAuthorizedKeysFile,
@@ -2495,8 +2491,8 @@ index 9bcd05b..29209e4 100644
2495+ sAcceptEnv, sPermitTunnel, 2491+ sAcceptEnv, sPermitTunnel,
2496 sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 2492 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
2497 sUsePrivilegeSeparation, sAllowAgentForwarding, 2493 sUsePrivilegeSeparation, sAllowAgentForwarding,
2498 sZeroKnowledgePasswordAuthentication, sHostCertificate, 2494 sHostCertificate,
2499@@ -410,10 +421,20 @@ static struct { 2495@@ -407,10 +418,20 @@ static struct {
2500 #ifdef GSSAPI 2496 #ifdef GSSAPI
2501 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 2497 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
2502 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 2498 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
@@ -2517,7 +2513,7 @@ index 9bcd05b..29209e4 100644
2517 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 2513 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
2518 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 2514 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
2519 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 2515 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
2520@@ -1094,10 +1115,22 @@ process_server_config_line(ServerOptions *options, char *line, 2516@@ -1086,10 +1107,22 @@ process_server_config_line(ServerOptions *options, char *line,
2521 intptr = &options->gss_authentication; 2517 intptr = &options->gss_authentication;
2522 goto parse_flag; 2518 goto parse_flag;
2523 2519
@@ -2540,7 +2536,7 @@ index 9bcd05b..29209e4 100644
2540 case sPasswordAuthentication: 2536 case sPasswordAuthentication:
2541 intptr = &options->password_authentication; 2537 intptr = &options->password_authentication;
2542 goto parse_flag; 2538 goto parse_flag;
2543@@ -2008,7 +2041,10 @@ dump_config(ServerOptions *o) 2539@@ -1995,7 +2028,10 @@ dump_config(ServerOptions *o)
2544 #endif 2540 #endif
2545 #ifdef GSSAPI 2541 #ifdef GSSAPI
2546 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 2542 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
@@ -2549,10 +2545,10 @@ index 9bcd05b..29209e4 100644
2549+ dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); 2545+ dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
2550+ dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); 2546+ dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
2551 #endif 2547 #endif
2552 #ifdef JPAKE 2548 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2553 dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication, 2549 dump_cfg_fmtint(sKbdInteractiveAuthentication,
2554diff --git a/servconf.h b/servconf.h 2550diff --git a/servconf.h b/servconf.h
2555index 8812c5a..eba76ee 100644 2551index 752d1c5..c922eb5 100644
2556--- a/servconf.h 2552--- a/servconf.h
2557+++ b/servconf.h 2553+++ b/servconf.h
2558@@ -112,7 +112,10 @@ typedef struct { 2554@@ -112,7 +112,10 @@ typedef struct {
@@ -2567,11 +2563,11 @@ index 8812c5a..eba76ee 100644
2567 * authentication. */ 2563 * authentication. */
2568 int kbd_interactive_authentication; /* If true, permit */ 2564 int kbd_interactive_authentication; /* If true, permit */
2569diff --git a/ssh-gss.h b/ssh-gss.h 2565diff --git a/ssh-gss.h b/ssh-gss.h
2570index 077e13c..885e481 100644 2566index a99d7f0..914701b 100644
2571--- a/ssh-gss.h 2567--- a/ssh-gss.h
2572+++ b/ssh-gss.h 2568+++ b/ssh-gss.h
2573@@ -1,6 +1,6 @@ 2569@@ -1,6 +1,6 @@
2574 /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */ 2570 /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */
2575 /* 2571 /*
2576- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 2572- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
2577+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. 2573+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
@@ -2634,7 +2630,7 @@ index 077e13c..885e481 100644
2634 2630
2635 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); 2631 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
2636 void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); 2632 void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
2637@@ -117,16 +134,32 @@ void ssh_gssapi_build_ctx(Gssctxt **); 2633@@ -119,16 +136,32 @@ void ssh_gssapi_build_ctx(Gssctxt **);
2638 void ssh_gssapi_delete_ctx(Gssctxt **); 2634 void ssh_gssapi_delete_ctx(Gssctxt **);
2639 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); 2635 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
2640 void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); 2636 void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
@@ -2683,10 +2679,10 @@ index 03a228f..228e5ab 100644
2683 # CheckHostIP yes 2679 # CheckHostIP yes
2684 # AddressFamily any 2680 # AddressFamily any
2685diff --git a/ssh_config.5 b/ssh_config.5 2681diff --git a/ssh_config.5 b/ssh_config.5
2686index 3cadcd7..49505ae 100644 2682index b580392..e7accd6 100644
2687--- a/ssh_config.5 2683--- a/ssh_config.5
2688+++ b/ssh_config.5 2684+++ b/ssh_config.5
2689@@ -676,11 +676,43 @@ Specifies whether user authentication based on GSSAPI is allowed. 2685@@ -682,11 +682,43 @@ Specifies whether user authentication based on GSSAPI is allowed.
2690 The default is 2686 The default is
2691 .Dq no . 2687 .Dq no .
2692 Note that this option applies to protocol version 2 only. 2688 Note that this option applies to protocol version 2 only.
@@ -2732,10 +2728,10 @@ index 3cadcd7..49505ae 100644
2732 Indicates that 2728 Indicates that
2733 .Xr ssh 1 2729 .Xr ssh 1
2734diff --git a/sshconnect2.c b/sshconnect2.c 2730diff --git a/sshconnect2.c b/sshconnect2.c
2735index 8acffc5..21a269d 100644 2731index 7f4ff41..66cb035 100644
2736--- a/sshconnect2.c 2732--- a/sshconnect2.c
2737+++ b/sshconnect2.c 2733+++ b/sshconnect2.c
2738@@ -160,9 +160,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 2734@@ -158,9 +158,34 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
2739 { 2735 {
2740 Kex *kex; 2736 Kex *kex;
2741 2737
@@ -2770,7 +2766,7 @@ index 8acffc5..21a269d 100644
2770 if (options.ciphers == (char *)-1) { 2766 if (options.ciphers == (char *)-1) {
2771 logit("No valid ciphers for protocol version 2 given, using defaults."); 2767 logit("No valid ciphers for protocol version 2 given, using defaults.");
2772 options.ciphers = NULL; 2768 options.ciphers = NULL;
2773@@ -198,6 +223,17 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 2769@@ -196,6 +221,17 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
2774 if (options.kex_algorithms != NULL) 2770 if (options.kex_algorithms != NULL)
2775 myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; 2771 myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
2776 2772
@@ -2788,7 +2784,7 @@ index 8acffc5..21a269d 100644
2788 if (options.rekey_limit || options.rekey_interval) 2784 if (options.rekey_limit || options.rekey_interval)
2789 packet_set_rekey_limits((u_int32_t)options.rekey_limit, 2785 packet_set_rekey_limits((u_int32_t)options.rekey_limit,
2790 (time_t)options.rekey_interval); 2786 (time_t)options.rekey_interval);
2791@@ -210,10 +246,30 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 2787@@ -208,10 +244,30 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
2792 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 2788 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
2793 kex->kex[KEX_ECDH_SHA2] = kexecdh_client; 2789 kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
2794 kex->kex[KEX_C25519_SHA256] = kexc25519_client; 2790 kex->kex[KEX_C25519_SHA256] = kexc25519_client;
@@ -2819,7 +2815,7 @@ index 8acffc5..21a269d 100644
2819 xxx_kex = kex; 2815 xxx_kex = kex;
2820 2816
2821 dispatch_run(DISPATCH_BLOCK, &kex->done, kex); 2817 dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
2822@@ -309,6 +365,7 @@ void input_gssapi_token(int type, u_int32_t, void *); 2818@@ -301,6 +357,7 @@ void input_gssapi_token(int type, u_int32_t, void *);
2823 void input_gssapi_hash(int type, u_int32_t, void *); 2819 void input_gssapi_hash(int type, u_int32_t, void *);
2824 void input_gssapi_error(int, u_int32_t, void *); 2820 void input_gssapi_error(int, u_int32_t, void *);
2825 void input_gssapi_errtok(int, u_int32_t, void *); 2821 void input_gssapi_errtok(int, u_int32_t, void *);
@@ -2827,7 +2823,7 @@ index 8acffc5..21a269d 100644
2827 #endif 2823 #endif
2828 2824
2829 void userauth(Authctxt *, char *); 2825 void userauth(Authctxt *, char *);
2830@@ -324,6 +381,11 @@ static char *authmethods_get(void); 2826@@ -316,6 +373,11 @@ static char *authmethods_get(void);
2831 2827
2832 Authmethod authmethods[] = { 2828 Authmethod authmethods[] = {
2833 #ifdef GSSAPI 2829 #ifdef GSSAPI
@@ -2839,7 +2835,7 @@ index 8acffc5..21a269d 100644
2839 {"gssapi-with-mic", 2835 {"gssapi-with-mic",
2840 userauth_gssapi, 2836 userauth_gssapi,
2841 NULL, 2837 NULL,
2842@@ -627,19 +689,31 @@ userauth_gssapi(Authctxt *authctxt) 2838@@ -612,19 +674,31 @@ userauth_gssapi(Authctxt *authctxt)
2843 static u_int mech = 0; 2839 static u_int mech = 0;
2844 OM_uint32 min; 2840 OM_uint32 min;
2845 int ok = 0; 2841 int ok = 0;
@@ -2873,7 +2869,7 @@ index 8acffc5..21a269d 100644
2873 ok = 1; /* Mechanism works */ 2869 ok = 1; /* Mechanism works */
2874 } else { 2870 } else {
2875 mech++; 2871 mech++;
2876@@ -736,8 +810,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) 2872@@ -721,8 +795,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
2877 { 2873 {
2878 Authctxt *authctxt = ctxt; 2874 Authctxt *authctxt = ctxt;
2879 Gssctxt *gssctxt; 2875 Gssctxt *gssctxt;
@@ -2884,7 +2880,7 @@ index 8acffc5..21a269d 100644
2884 2880
2885 if (authctxt == NULL) 2881 if (authctxt == NULL)
2886 fatal("input_gssapi_response: no authentication context"); 2882 fatal("input_gssapi_response: no authentication context");
2887@@ -846,6 +920,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) 2883@@ -831,6 +905,48 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt)
2888 free(msg); 2884 free(msg);
2889 free(lang); 2885 free(lang);
2890 } 2886 }
@@ -2934,7 +2930,7 @@ index 8acffc5..21a269d 100644
2934 2930
2935 int 2931 int
2936diff --git a/sshd.c b/sshd.c 2932diff --git a/sshd.c b/sshd.c
2937index 25380c9..fe65132 100644 2933index 7523de9..d787fea 100644
2938--- a/sshd.c 2934--- a/sshd.c
2939+++ b/sshd.c 2935+++ b/sshd.c
2940@@ -122,6 +122,10 @@ 2936@@ -122,6 +122,10 @@
@@ -2948,7 +2944,7 @@ index 25380c9..fe65132 100644
2948 #ifdef LIBWRAP 2944 #ifdef LIBWRAP
2949 #include <tcpd.h> 2945 #include <tcpd.h>
2950 #include <syslog.h> 2946 #include <syslog.h>
2951@@ -1721,10 +1725,13 @@ main(int ac, char **av) 2947@@ -1728,10 +1732,13 @@ main(int ac, char **av)
2952 logit("Disabling protocol version 1. Could not load host key"); 2948 logit("Disabling protocol version 1. Could not load host key");
2953 options.protocol &= ~SSH_PROTO_1; 2949 options.protocol &= ~SSH_PROTO_1;
2954 } 2950 }
@@ -2962,7 +2958,7 @@ index 25380c9..fe65132 100644
2962 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 2958 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
2963 logit("sshd: no hostkeys available -- exiting."); 2959 logit("sshd: no hostkeys available -- exiting.");
2964 exit(1); 2960 exit(1);
2965@@ -2051,6 +2058,60 @@ main(int ac, char **av) 2961@@ -2058,6 +2065,60 @@ main(int ac, char **av)
2966 remote_ip, remote_port, 2962 remote_ip, remote_port,
2967 get_local_ipaddr(sock_in), get_local_port()); 2963 get_local_ipaddr(sock_in), get_local_port());
2968 2964
@@ -3023,7 +3019,7 @@ index 25380c9..fe65132 100644
3023 /* 3019 /*
3024 * We don't want to listen forever unless the other side 3020 * We don't want to listen forever unless the other side
3025 * successfully authenticates itself. So we set up an alarm which is 3021 * successfully authenticates itself. So we set up an alarm which is
3026@@ -2456,6 +2517,48 @@ do_ssh2_kex(void) 3022@@ -2469,6 +2530,48 @@ do_ssh2_kex(void)
3027 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 3023 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
3028 list_hostkey_types()); 3024 list_hostkey_types());
3029 3025
@@ -3072,7 +3068,7 @@ index 25380c9..fe65132 100644
3072 /* start key exchange */ 3068 /* start key exchange */
3073 kex = kex_setup(myproposal); 3069 kex = kex_setup(myproposal);
3074 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 3070 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
3075@@ -2464,6 +2567,13 @@ do_ssh2_kex(void) 3071@@ -2477,6 +2580,13 @@ do_ssh2_kex(void)
3076 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 3072 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
3077 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 3073 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
3078 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 3074 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
@@ -3100,7 +3096,7 @@ index e9045bc..d9b8594 100644
3100 # Set this to 'yes' to enable PAM authentication, account processing, 3096 # Set this to 'yes' to enable PAM authentication, account processing,
3101 # and session processing. If this is enabled, PAM authentication will 3097 # and session processing. If this is enabled, PAM authentication will
3102diff --git a/sshd_config.5 b/sshd_config.5 3098diff --git a/sshd_config.5 b/sshd_config.5
3103index 3b21ea6..9aa9eba 100644 3099index ce71efe..ceed88a 100644
3104--- a/sshd_config.5 3100--- a/sshd_config.5
3105+++ b/sshd_config.5 3101+++ b/sshd_config.5
3106@@ -493,12 +493,40 @@ Specifies whether user authentication based on GSSAPI is allowed. 3102@@ -493,12 +493,40 @@ Specifies whether user authentication based on GSSAPI is allowed.
diff --git a/debian/patches/helpful-wait-terminate.patch b/debian/patches/helpful-wait-terminate.patch
index 6f28f7db5..e79f4990f 100644
--- a/debian/patches/helpful-wait-terminate.patch
+++ b/debian/patches/helpful-wait-terminate.patch
@@ -1,4 +1,4 @@
1From 29a3d408fe0b8e91aed47ec4ad26d0c0a16e8f65 Mon Sep 17 00:00:00 2001 1From ef912859a4300360164292abe47b5516c8ee4a13 Mon Sep 17 00:00:00 2001
2From: Matthew Vernon <matthew@debian.org> 2From: Matthew Vernon <matthew@debian.org>
3Date: Sun, 9 Feb 2014 16:09:56 +0000 3Date: Sun, 9 Feb 2014 16:09:56 +0000
4Subject: Mention ~& when waiting for forwarded connections to terminate 4Subject: Mention ~& when waiting for forwarded connections to terminate
@@ -12,7 +12,7 @@ Patch-Name: helpful-wait-terminate.patch
12 1 file changed, 1 insertion(+), 1 deletion(-) 12 1 file changed, 1 insertion(+), 1 deletion(-)
13 13
14diff --git a/serverloop.c b/serverloop.c 14diff --git a/serverloop.c b/serverloop.c
15index 5b2f802..d3079d2 100644 15index 2f8e3a0..441d73b 100644
16--- a/serverloop.c 16--- a/serverloop.c
17+++ b/serverloop.c 17+++ b/serverloop.c
18@@ -687,7 +687,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) 18@@ -687,7 +687,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
diff --git a/debian/patches/keepalive-extensions.patch b/debian/patches/keepalive-extensions.patch
index 149821283..680701f3d 100644
--- a/debian/patches/keepalive-extensions.patch
+++ b/debian/patches/keepalive-extensions.patch
@@ -1,4 +1,4 @@
1From 89a797b303eb5ed9edeb122a15b9dedf152cdd02 Mon Sep 17 00:00:00 2001 1From 81540b7886fdc73c7be304706ea33d6d87b5fc81 Mon Sep 17 00:00:00 2001
2From: Richard Kettlewell <rjk@greenend.org.uk> 2From: Richard Kettlewell <rjk@greenend.org.uk>
3Date: Sun, 9 Feb 2014 16:09:52 +0000 3Date: Sun, 9 Feb 2014 16:09:52 +0000
4Subject: Various keepalive extensions 4Subject: Various keepalive extensions
@@ -26,10 +26,10 @@ Patch-Name: keepalive-extensions.patch
26 3 files changed, 34 insertions(+), 4 deletions(-) 26 3 files changed, 34 insertions(+), 4 deletions(-)
27 27
28diff --git a/readconf.c b/readconf.c 28diff --git a/readconf.c b/readconf.c
29index 2a1fe8e..e79e355 100644 29index bcd8cad..6409937 100644
30--- a/readconf.c 30--- a/readconf.c
31+++ b/readconf.c 31+++ b/readconf.c
32@@ -150,6 +150,7 @@ typedef enum { 32@@ -151,6 +151,7 @@ typedef enum {
33 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 33 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
34 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 34 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
35 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 35 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
@@ -37,7 +37,7 @@ index 2a1fe8e..e79e355 100644
37 oIgnoredUnknownOption, oDeprecated, oUnsupported 37 oIgnoredUnknownOption, oDeprecated, oUnsupported
38 } OpCodes; 38 } OpCodes;
39 39
40@@ -279,6 +280,8 @@ static struct { 40@@ -274,6 +275,8 @@ static struct {
41 { "canonicalizemaxdots", oCanonicalizeMaxDots }, 41 { "canonicalizemaxdots", oCanonicalizeMaxDots },
42 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, 42 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
43 { "ignoreunknown", oIgnoreUnknown }, 43 { "ignoreunknown", oIgnoreUnknown },
@@ -46,7 +46,7 @@ index 2a1fe8e..e79e355 100644
46 46
47 { NULL, oBadOption } 47 { NULL, oBadOption }
48 }; 48 };
49@@ -1245,6 +1248,8 @@ parse_int: 49@@ -1247,6 +1250,8 @@ parse_int:
50 goto parse_flag; 50 goto parse_flag;
51 51
52 case oServerAliveInterval: 52 case oServerAliveInterval:
@@ -55,7 +55,7 @@ index 2a1fe8e..e79e355 100644
55 intptr = &options->server_alive_interval; 55 intptr = &options->server_alive_interval;
56 goto parse_time; 56 goto parse_time;
57 57
58@@ -1724,8 +1729,13 @@ fill_default_options(Options * options) 58@@ -1746,8 +1751,13 @@ fill_default_options(Options * options)
59 options->rekey_interval = 0; 59 options->rekey_interval = 0;
60 if (options->verify_host_key_dns == -1) 60 if (options->verify_host_key_dns == -1)
61 options->verify_host_key_dns = 0; 61 options->verify_host_key_dns = 0;
@@ -72,7 +72,7 @@ index 2a1fe8e..e79e355 100644
72 options->server_alive_count_max = 3; 72 options->server_alive_count_max = 3;
73 if (options->control_master == -1) 73 if (options->control_master == -1)
74diff --git a/ssh_config.5 b/ssh_config.5 74diff --git a/ssh_config.5 b/ssh_config.5
75index 617a312..b3c5dc6 100644 75index 473971e..3172fd4 100644
76--- a/ssh_config.5 76--- a/ssh_config.5
77+++ b/ssh_config.5 77+++ b/ssh_config.5
78@@ -205,8 +205,12 @@ Valid arguments are 78@@ -205,8 +205,12 @@ Valid arguments are
@@ -89,7 +89,7 @@ index 617a312..b3c5dc6 100644
89 The argument must be 89 The argument must be
90 .Dq yes 90 .Dq yes
91 or 91 or
92@@ -1299,8 +1303,15 @@ from the server, 92@@ -1305,8 +1309,15 @@ from the server,
93 will send a message through the encrypted 93 will send a message through the encrypted
94 channel to request a response from the server. 94 channel to request a response from the server.
95 The default 95 The default
@@ -106,7 +106,7 @@ index 617a312..b3c5dc6 100644
106 .It Cm StrictHostKeyChecking 106 .It Cm StrictHostKeyChecking
107 If this flag is set to 107 If this flag is set to
108 .Dq yes , 108 .Dq yes ,
109@@ -1339,6 +1350,12 @@ Specifies whether the system should send TCP keepalive messages to the 109@@ -1345,6 +1356,12 @@ Specifies whether the system should send TCP keepalive messages to the
110 other side. 110 other side.
111 If they are sent, death of the connection or crash of one 111 If they are sent, death of the connection or crash of one
112 of the machines will be properly noticed. 112 of the machines will be properly noticed.
@@ -120,10 +120,10 @@ index 617a312..b3c5dc6 100644
120 connections will die if the route is down temporarily, and some people 120 connections will die if the route is down temporarily, and some people
121 find it annoying. 121 find it annoying.
122diff --git a/sshd_config.5 b/sshd_config.5 122diff --git a/sshd_config.5 b/sshd_config.5
123index 9aa9eba..39643de 100644 123index ceed88a..2164d58 100644
124--- a/sshd_config.5 124--- a/sshd_config.5
125+++ b/sshd_config.5 125+++ b/sshd_config.5
126@@ -1168,6 +1168,9 @@ This avoids infinitely hanging sessions. 126@@ -1183,6 +1183,9 @@ This avoids infinitely hanging sessions.
127 .Pp 127 .Pp
128 To disable TCP keepalive messages, the value should be set to 128 To disable TCP keepalive messages, the value should be set to
129 .Dq no . 129 .Dq no .
diff --git a/debian/patches/lintian-symlink-pickiness.patch b/debian/patches/lintian-symlink-pickiness.patch
index 97f9b0759..09e09ecf8 100644
--- a/debian/patches/lintian-symlink-pickiness.patch
+++ b/debian/patches/lintian-symlink-pickiness.patch
@@ -1,4 +1,4 @@
1From b25d3b37e89fb73b5fa86d19bc22f67f64dd0ad9 Mon Sep 17 00:00:00 2001 1From eb567100ef178f4395c95cc1f37b921e02c3dd5b Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:08 +0000 3Date: Sun, 9 Feb 2014 16:10:08 +0000
4Subject: Fix picky lintian errors about slogin symlinks 4Subject: Fix picky lintian errors about slogin symlinks
@@ -15,7 +15,7 @@ Patch-Name: lintian-symlink-pickiness.patch
15 1 file changed, 2 insertions(+), 2 deletions(-) 15 1 file changed, 2 insertions(+), 2 deletions(-)
16 16
17diff --git a/Makefile.in b/Makefile.in 17diff --git a/Makefile.in b/Makefile.in
18index 5cf8100..b7de26f 100644 18index feee0b2..7d192bb 100644
19--- a/Makefile.in 19--- a/Makefile.in
20+++ b/Makefile.in 20+++ b/Makefile.in
21@@ -293,9 +293,9 @@ install-files: 21@@ -293,9 +293,9 @@ install-files:
diff --git a/debian/patches/mention-ssh-keygen-on-keychange.patch b/debian/patches/mention-ssh-keygen-on-keychange.patch
index ab0505834..e00b6c345 100644
--- a/debian/patches/mention-ssh-keygen-on-keychange.patch
+++ b/debian/patches/mention-ssh-keygen-on-keychange.patch
@@ -1,4 +1,4 @@
1From 1ad5769e5d1d878125c48c6bb4a8bea7225940fc Mon Sep 17 00:00:00 2001 1From 8ab8f1465980856291f215c7b7184a4456398fb4 Mon Sep 17 00:00:00 2001
2From: Scott Moser <smoser@ubuntu.com> 2From: Scott Moser <smoser@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:10:03 +0000 3Date: Sun, 9 Feb 2014 16:10:03 +0000
4Subject: Mention ssh-keygen in ssh fingerprint changed warning 4Subject: Mention ssh-keygen in ssh fingerprint changed warning
@@ -13,10 +13,10 @@ Patch-Name: mention-ssh-keygen-on-keychange.patch
13 1 file changed, 6 insertions(+), 1 deletion(-) 13 1 file changed, 6 insertions(+), 1 deletion(-)
14 14
15diff --git a/sshconnect.c b/sshconnect.c 15diff --git a/sshconnect.c b/sshconnect.c
16index ef4d9e0..4ff5c73 100644 16index 9e02837..e0a5db9 100644
17--- a/sshconnect.c 17--- a/sshconnect.c
18+++ b/sshconnect.c 18+++ b/sshconnect.c
19@@ -1062,9 +1062,12 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, 19@@ -1065,9 +1065,12 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
20 error("%s. This could either mean that", key_msg); 20 error("%s. This could either mean that", key_msg);
21 error("DNS SPOOFING is happening or the IP address for the host"); 21 error("DNS SPOOFING is happening or the IP address for the host");
22 error("and its host key have changed at the same time."); 22 error("and its host key have changed at the same time.");
@@ -30,7 +30,7 @@ index ef4d9e0..4ff5c73 100644
30 } 30 }
31 /* The host key has changed. */ 31 /* The host key has changed. */
32 warn_changed_key(host_key); 32 warn_changed_key(host_key);
33@@ -1072,6 +1075,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, 33@@ -1075,6 +1078,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
34 user_hostfiles[0]); 34 user_hostfiles[0]);
35 error("Offending %s key in %s:%lu", key_type(host_found->key), 35 error("Offending %s key in %s:%lu", key_type(host_found->key),
36 host_found->file, host_found->line); 36 host_found->file, host_found->line);
diff --git a/debian/patches/no-openssl-version-check.patch b/debian/patches/no-openssl-version-check.patch
index 590259750..56fa46aac 100644
--- a/debian/patches/no-openssl-version-check.patch
+++ b/debian/patches/no-openssl-version-check.patch
@@ -1,4 +1,4 @@
1From 4edb6872515344a0b137fe835ea7f76dcb0325ad Mon Sep 17 00:00:00 2001 1From 20690ea4b33e8ff81fea287492270df3a7029777 Mon Sep 17 00:00:00 2001
2From: Philip Hands <phil@hands.com> 2From: Philip Hands <phil@hands.com>
3Date: Sun, 9 Feb 2014 16:10:14 +0000 3Date: Sun, 9 Feb 2014 16:10:14 +0000
4Subject: Disable OpenSSL version check 4Subject: Disable OpenSSL version check
diff --git a/debian/patches/openbsd-docs.patch b/debian/patches/openbsd-docs.patch
index ea9f290ad..9a34a4182 100644
--- a/debian/patches/openbsd-docs.patch
+++ b/debian/patches/openbsd-docs.patch
@@ -1,4 +1,4 @@
1From ddca9737b50bd2ec15dc166434e312ae2fbd1196 Mon Sep 17 00:00:00 2001 1From ec9bfd62211fdf5a3004ef2045c2eb3baccfd375 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:09 +0000 3Date: Sun, 9 Feb 2014 16:10:09 +0000
4Subject: Adjust various OpenBSD-specific references in manual pages 4Subject: Adjust various OpenBSD-specific references in manual pages
@@ -44,7 +44,7 @@ index ef0de08..149846c 100644
44 .Sh SEE ALSO 44 .Sh SEE ALSO
45 .Xr ssh-keygen 1 , 45 .Xr ssh-keygen 1 ,
46diff --git a/ssh-keygen.1 b/ssh-keygen.1 46diff --git a/ssh-keygen.1 b/ssh-keygen.1
47index 0e0ed98..299ccf8 100644 47index 12e00d4..a71de74 100644
48--- a/ssh-keygen.1 48--- a/ssh-keygen.1
49+++ b/ssh-keygen.1 49+++ b/ssh-keygen.1
50@@ -172,9 +172,7 @@ key in 50@@ -172,9 +172,7 @@ key in
@@ -133,7 +133,7 @@ index e6a900b..b016e90 100644
133 .Xr sshd_config 5 , 133 .Xr sshd_config 5 ,
134 .Xr inetd 8 , 134 .Xr inetd 8 ,
135diff --git a/sshd_config.5 b/sshd_config.5 135diff --git a/sshd_config.5 b/sshd_config.5
136index bdca797..9fa6086 100644 136index 8f078f6..908e0bb 100644
137--- a/sshd_config.5 137--- a/sshd_config.5
138+++ b/sshd_config.5 138+++ b/sshd_config.5
139@@ -283,8 +283,7 @@ This option is only available for protocol version 2. 139@@ -283,8 +283,7 @@ This option is only available for protocol version 2.
diff --git a/debian/patches/package-versioning.patch b/debian/patches/package-versioning.patch
index 67e54ccf3..c9c20d1c0 100644
--- a/debian/patches/package-versioning.patch
+++ b/debian/patches/package-versioning.patch
@@ -1,4 +1,4 @@
1From 07b738d2bf93a5e3c57ab242b666a5f58484c7a3 Mon Sep 17 00:00:00 2001 1From 6de70b95f5005447ae23532d4f3ee41a9338479f Mon Sep 17 00:00:00 2001
2From: Matthew Vernon <matthew@debian.org> 2From: Matthew Vernon <matthew@debian.org>
3Date: Sun, 9 Feb 2014 16:10:05 +0000 3Date: Sun, 9 Feb 2014 16:10:05 +0000
4Subject: Include the Debian version in our identification 4Subject: Include the Debian version in our identification
@@ -19,10 +19,10 @@ Patch-Name: package-versioning.patch
19 3 files changed, 9 insertions(+), 4 deletions(-) 19 3 files changed, 9 insertions(+), 4 deletions(-)
20 20
21diff --git a/sshconnect.c b/sshconnect.c 21diff --git a/sshconnect.c b/sshconnect.c
22index 4ff5c73..a2fbf9e 100644 22index e0a5db9..87c3770 100644
23--- a/sshconnect.c 23--- a/sshconnect.c
24+++ b/sshconnect.c 24+++ b/sshconnect.c
25@@ -517,10 +517,10 @@ send_client_banner(int connection_out, int minor1) 25@@ -520,10 +520,10 @@ send_client_banner(int connection_out, int minor1)
26 /* Send our own protocol version identification. */ 26 /* Send our own protocol version identification. */
27 if (compat20) { 27 if (compat20) {
28 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", 28 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
@@ -36,7 +36,7 @@ index 4ff5c73..a2fbf9e 100644
36 if (roaming_atomicio(vwrite, connection_out, client_version_string, 36 if (roaming_atomicio(vwrite, connection_out, client_version_string,
37 strlen(client_version_string)) != strlen(client_version_string)) 37 strlen(client_version_string)) != strlen(client_version_string))
38diff --git a/sshd.c b/sshd.c 38diff --git a/sshd.c b/sshd.c
39index 0a30101..82168a1 100644 39index e343d90..af9b8f1 100644
40--- a/sshd.c 40--- a/sshd.c
41+++ b/sshd.c 41+++ b/sshd.c
42@@ -440,7 +440,7 @@ sshd_exchange_identification(int sock_in, int sock_out) 42@@ -440,7 +440,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
@@ -49,11 +49,11 @@ index 0a30101..82168a1 100644
49 options.version_addendum, newline); 49 options.version_addendum, newline);
50 50
51diff --git a/version.h b/version.h 51diff --git a/version.h b/version.h
52index 83d70c6..0c6ea0f 100644 52index a1579ac..a97c337 100644
53--- a/version.h 53--- a/version.h
54+++ b/version.h 54+++ b/version.h
55@@ -3,4 +3,9 @@ 55@@ -3,4 +3,9 @@
56 #define SSH_VERSION "OpenSSH_6.5" 56 #define SSH_VERSION "OpenSSH_6.6"
57 57
58 #define SSH_PORTABLE "p1" 58 #define SSH_PORTABLE "p1"
59-#define SSH_RELEASE SSH_VERSION SSH_PORTABLE 59-#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
diff --git a/debian/patches/quieter-signals.patch b/debian/patches/quieter-signals.patch
index 168b05a34..075b59823 100644
--- a/debian/patches/quieter-signals.patch
+++ b/debian/patches/quieter-signals.patch
@@ -1,4 +1,4 @@
1From 4ba49a8d770618307867a73769ebba62bf553961 Mon Sep 17 00:00:00 2001 1From 9875e47079abff55f8d2c1e958e9d50de6eae7ec Mon Sep 17 00:00:00 2001
2From: Peter Samuelson <peter@p12n.org> 2From: Peter Samuelson <peter@p12n.org>
3Date: Sun, 9 Feb 2014 16:09:55 +0000 3Date: Sun, 9 Feb 2014 16:09:55 +0000
4Subject: Reduce severity of "Killed by signal %d" 4Subject: Reduce severity of "Killed by signal %d"
@@ -22,7 +22,7 @@ Patch-Name: quieter-signals.patch
22 1 file changed, 4 insertions(+), 2 deletions(-) 22 1 file changed, 4 insertions(+), 2 deletions(-)
23 23
24diff --git a/clientloop.c b/clientloop.c 24diff --git a/clientloop.c b/clientloop.c
25index cd1739f..30097cd 100644 25index 73a800c..4bc5b57 100644
26--- a/clientloop.c 26--- a/clientloop.c
27+++ b/clientloop.c 27+++ b/clientloop.c
28@@ -1717,8 +1717,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) 28@@ -1717,8 +1717,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
diff --git a/debian/patches/scp-quoting.patch b/debian/patches/scp-quoting.patch
index d4755c6b3..ff037a43a 100644
--- a/debian/patches/scp-quoting.patch
+++ b/debian/patches/scp-quoting.patch
@@ -1,4 +1,4 @@
1From 882d0c4c4403674eebd4ec525fe368ecc2100bfc Mon Sep 17 00:00:00 2001 1From 8ab204ee192e655d5a8f4d599adb3d99eeabedc6 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Nicolas=20Valc=C3=A1rcel?= <nvalcarcel@ubuntu.com> 2From: =?UTF-8?q?Nicolas=20Valc=C3=A1rcel?= <nvalcarcel@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:09:59 +0000 3Date: Sun, 9 Feb 2014 16:09:59 +0000
4Subject: Adjust scp quoting in verbose mode 4Subject: Adjust scp quoting in verbose mode
diff --git a/debian/patches/selinux-role.patch b/debian/patches/selinux-role.patch
index 1f924dfad..e0ca12fb0 100644
--- a/debian/patches/selinux-role.patch
+++ b/debian/patches/selinux-role.patch
@@ -1,4 +1,4 @@
1From 7afb9ad9307191397a3ccf3d7cc90dfe474b09e8 Mon Sep 17 00:00:00 2001 1From ae32d626ed3d15cfd7f432358b63c005961921df Mon Sep 17 00:00:00 2001
2From: Manoj Srivastava <srivasta@debian.org> 2From: Manoj Srivastava <srivasta@debian.org>
3Date: Sun, 9 Feb 2014 16:09:49 +0000 3Date: Sun, 9 Feb 2014 16:09:49 +0000
4Subject: Handle SELinux authorisation roles 4Subject: Handle SELinux authorisation roles
@@ -32,7 +32,7 @@ Patch-Name: selinux-role.patch
32 16 files changed, 104 insertions(+), 31 deletions(-) 32 16 files changed, 104 insertions(+), 31 deletions(-)
33 33
34diff --git a/auth.h b/auth.h 34diff --git a/auth.h b/auth.h
35index 80f0898..5b6824f 100644 35index 124e597..79e4ea5 100644
36--- a/auth.h 36--- a/auth.h
37+++ b/auth.h 37+++ b/auth.h
38@@ -59,6 +59,7 @@ struct Authctxt { 38@@ -59,6 +59,7 @@ struct Authctxt {
@@ -42,9 +42,9 @@ index 80f0898..5b6824f 100644
42+ char *role; 42+ char *role;
43 void *kbdintctxt; 43 void *kbdintctxt;
44 char *info; /* Extra info for next auth_log */ 44 char *info; /* Extra info for next auth_log */
45 void *jpake_ctx; 45 #ifdef BSD_AUTH
46diff --git a/auth1.c b/auth1.c 46diff --git a/auth1.c b/auth1.c
47index f1ac598..2803a3c 100644 47index 0f870b3..c707390 100644
48--- a/auth1.c 48--- a/auth1.c
49+++ b/auth1.c 49+++ b/auth1.c
50@@ -380,7 +380,7 @@ void 50@@ -380,7 +380,7 @@ void
@@ -75,10 +75,10 @@ index f1ac598..2803a3c 100644
75 /* Verify that the user is a valid user. */ 75 /* Verify that the user is a valid user. */
76 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) 76 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
77diff --git a/auth2.c b/auth2.c 77diff --git a/auth2.c b/auth2.c
78index 6ed8f04..b55bbcd 100644 78index fbe3e1b..70f2925 100644
79--- a/auth2.c 79--- a/auth2.c
80+++ b/auth2.c 80+++ b/auth2.c
81@@ -222,7 +222,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) 81@@ -216,7 +216,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
82 { 82 {
83 Authctxt *authctxt = ctxt; 83 Authctxt *authctxt = ctxt;
84 Authmethod *m = NULL; 84 Authmethod *m = NULL;
@@ -87,7 +87,7 @@ index 6ed8f04..b55bbcd 100644
87 int authenticated = 0; 87 int authenticated = 0;
88 88
89 if (authctxt == NULL) 89 if (authctxt == NULL)
90@@ -234,8 +234,13 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) 90@@ -228,8 +228,13 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
91 debug("userauth-request for user %s service %s method %s", user, service, method); 91 debug("userauth-request for user %s service %s method %s", user, service, method);
92 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 92 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
93 93
@@ -101,7 +101,7 @@ index 6ed8f04..b55bbcd 100644
101 101
102 if (authctxt->attempt++ == 0) { 102 if (authctxt->attempt++ == 0) {
103 /* setup auth context */ 103 /* setup auth context */
104@@ -259,8 +264,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) 104@@ -253,8 +258,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
105 use_privsep ? " [net]" : ""); 105 use_privsep ? " [net]" : "");
106 authctxt->service = xstrdup(service); 106 authctxt->service = xstrdup(service);
107 authctxt->style = style ? xstrdup(style) : NULL; 107 authctxt->style = style ? xstrdup(style) : NULL;
@@ -113,10 +113,10 @@ index 6ed8f04..b55bbcd 100644
113 if (auth2_setup_methods_lists(authctxt) != 0) 113 if (auth2_setup_methods_lists(authctxt) != 0)
114 packet_disconnect("no authentication methods enabled"); 114 packet_disconnect("no authentication methods enabled");
115diff --git a/monitor.c b/monitor.c 115diff --git a/monitor.c b/monitor.c
116index a777c4c..88f472e 100644 116index 2918814..11eac63 100644
117--- a/monitor.c 117--- a/monitor.c
118+++ b/monitor.c 118+++ b/monitor.c
119@@ -146,6 +146,7 @@ int mm_answer_sign(int, Buffer *); 119@@ -145,6 +145,7 @@ int mm_answer_sign(int, Buffer *);
120 int mm_answer_pwnamallow(int, Buffer *); 120 int mm_answer_pwnamallow(int, Buffer *);
121 int mm_answer_auth2_read_banner(int, Buffer *); 121 int mm_answer_auth2_read_banner(int, Buffer *);
122 int mm_answer_authserv(int, Buffer *); 122 int mm_answer_authserv(int, Buffer *);
@@ -124,7 +124,7 @@ index a777c4c..88f472e 100644
124 int mm_answer_authpassword(int, Buffer *); 124 int mm_answer_authpassword(int, Buffer *);
125 int mm_answer_bsdauthquery(int, Buffer *); 125 int mm_answer_bsdauthquery(int, Buffer *);
126 int mm_answer_bsdauthrespond(int, Buffer *); 126 int mm_answer_bsdauthrespond(int, Buffer *);
127@@ -227,6 +228,7 @@ struct mon_table mon_dispatch_proto20[] = { 127@@ -221,6 +222,7 @@ struct mon_table mon_dispatch_proto20[] = {
128 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 128 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
129 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 129 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
130 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 130 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
@@ -132,7 +132,7 @@ index a777c4c..88f472e 100644
132 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 132 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
133 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 133 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
134 #ifdef USE_PAM 134 #ifdef USE_PAM
135@@ -844,6 +846,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) 135@@ -822,6 +824,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
136 else { 136 else {
137 /* Allow service/style information on the auth context */ 137 /* Allow service/style information on the auth context */
138 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 138 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
@@ -140,7 +140,7 @@ index a777c4c..88f472e 100644
140 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 140 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
141 } 141 }
142 #ifdef USE_PAM 142 #ifdef USE_PAM
143@@ -874,14 +877,37 @@ mm_answer_authserv(int sock, Buffer *m) 143@@ -852,14 +855,37 @@ mm_answer_authserv(int sock, Buffer *m)
144 144
145 authctxt->service = buffer_get_string(m, NULL); 145 authctxt->service = buffer_get_string(m, NULL);
146 authctxt->style = buffer_get_string(m, NULL); 146 authctxt->style = buffer_get_string(m, NULL);
@@ -180,7 +180,7 @@ index a777c4c..88f472e 100644
180 return (0); 180 return (0);
181 } 181 }
182 182
183@@ -1486,7 +1512,7 @@ mm_answer_pty(int sock, Buffer *m) 183@@ -1464,7 +1490,7 @@ mm_answer_pty(int sock, Buffer *m)
184 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 184 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
185 if (res == 0) 185 if (res == 0)
186 goto error; 186 goto error;
@@ -190,10 +190,10 @@ index a777c4c..88f472e 100644
190 buffer_put_int(m, 1); 190 buffer_put_int(m, 1);
191 buffer_put_cstring(m, s->tty); 191 buffer_put_cstring(m, s->tty);
192diff --git a/monitor.h b/monitor.h 192diff --git a/monitor.h b/monitor.h
193index 315ef99..3c13706 100644 193index 7f32b0c..4d5e8fa 100644
194--- a/monitor.h 194--- a/monitor.h
195+++ b/monitor.h 195+++ b/monitor.h
196@@ -73,6 +73,8 @@ enum monitor_reqtype { 196@@ -68,6 +68,8 @@ enum monitor_reqtype {
197 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, 197 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151,
198 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, 198 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153,
199 199
@@ -203,10 +203,10 @@ index 315ef99..3c13706 100644
203 203
204 struct mm_master; 204 struct mm_master;
205diff --git a/monitor_wrap.c b/monitor_wrap.c 205diff --git a/monitor_wrap.c b/monitor_wrap.c
206index 44019f3..69bc324 100644 206index 60b987d..f75dc9d 100644
207--- a/monitor_wrap.c 207--- a/monitor_wrap.c
208+++ b/monitor_wrap.c 208+++ b/monitor_wrap.c
209@@ -320,10 +320,10 @@ mm_auth2_read_banner(void) 209@@ -318,10 +318,10 @@ mm_auth2_read_banner(void)
210 return (banner); 210 return (banner);
211 } 211 }
212 212
@@ -219,7 +219,7 @@ index 44019f3..69bc324 100644
219 { 219 {
220 Buffer m; 220 Buffer m;
221 221
222@@ -332,12 +332,30 @@ mm_inform_authserv(char *service, char *style) 222@@ -330,12 +330,30 @@ mm_inform_authserv(char *service, char *style)
223 buffer_init(&m); 223 buffer_init(&m);
224 buffer_put_cstring(&m, service); 224 buffer_put_cstring(&m, service);
225 buffer_put_cstring(&m, style ? style : ""); 225 buffer_put_cstring(&m, style ? style : "");
@@ -251,7 +251,7 @@ index 44019f3..69bc324 100644
251 int 251 int
252 mm_auth_password(Authctxt *authctxt, char *password) 252 mm_auth_password(Authctxt *authctxt, char *password)
253diff --git a/monitor_wrap.h b/monitor_wrap.h 253diff --git a/monitor_wrap.h b/monitor_wrap.h
254index ec9b9b1..4d12e29 100644 254index a4e9d24..9c2ee49 100644
255--- a/monitor_wrap.h 255--- a/monitor_wrap.h
256+++ b/monitor_wrap.h 256+++ b/monitor_wrap.h
257@@ -41,7 +41,8 @@ void mm_log_handler(LogLevel, const char *, void *); 257@@ -41,7 +41,8 @@ void mm_log_handler(LogLevel, const char *, void *);
@@ -396,10 +396,10 @@ index 1c7a45d..436ae7c 100644
396 char *platform_krb5_get_principal_name(const char *); 396 char *platform_krb5_get_principal_name(const char *);
397 int platform_sys_dir_uid(uid_t); 397 int platform_sys_dir_uid(uid_t);
398diff --git a/session.c b/session.c 398diff --git a/session.c b/session.c
399index 12dd9ab..5ddd82a 100644 399index 2bcf818..6848df4 100644
400--- a/session.c 400--- a/session.c
401+++ b/session.c 401+++ b/session.c
402@@ -1497,7 +1497,7 @@ safely_chroot(const char *path, uid_t uid) 402@@ -1502,7 +1502,7 @@ safely_chroot(const char *path, uid_t uid)
403 403
404 /* Set login name, uid, gid, and groups. */ 404 /* Set login name, uid, gid, and groups. */
405 void 405 void
@@ -408,7 +408,7 @@ index 12dd9ab..5ddd82a 100644
408 { 408 {
409 char *chroot_path, *tmp; 409 char *chroot_path, *tmp;
410 410
411@@ -1525,7 +1525,7 @@ do_setusercontext(struct passwd *pw) 411@@ -1530,7 +1530,7 @@ do_setusercontext(struct passwd *pw)
412 endgrent(); 412 endgrent();
413 #endif 413 #endif
414 414
@@ -417,7 +417,7 @@ index 12dd9ab..5ddd82a 100644
417 417
418 if (options.chroot_directory != NULL && 418 if (options.chroot_directory != NULL &&
419 strcasecmp(options.chroot_directory, "none") != 0) { 419 strcasecmp(options.chroot_directory, "none") != 0) {
420@@ -1674,7 +1674,7 @@ do_child(Session *s, const char *command) 420@@ -1679,7 +1679,7 @@ do_child(Session *s, const char *command)
421 421
422 /* Force a password change */ 422 /* Force a password change */
423 if (s->authctxt->force_pwchange) { 423 if (s->authctxt->force_pwchange) {
@@ -426,7 +426,7 @@ index 12dd9ab..5ddd82a 100644
426 child_close_fds(); 426 child_close_fds();
427 do_pwchange(s); 427 do_pwchange(s);
428 exit(1); 428 exit(1);
429@@ -1701,7 +1701,7 @@ do_child(Session *s, const char *command) 429@@ -1706,7 +1706,7 @@ do_child(Session *s, const char *command)
430 /* When PAM is enabled we rely on it to do the nologin check */ 430 /* When PAM is enabled we rely on it to do the nologin check */
431 if (!options.use_pam) 431 if (!options.use_pam)
432 do_nologin(pw); 432 do_nologin(pw);
@@ -435,7 +435,7 @@ index 12dd9ab..5ddd82a 100644
435 /* 435 /*
436 * PAM session modules in do_setusercontext may have 436 * PAM session modules in do_setusercontext may have
437 * generated messages, so if this in an interactive 437 * generated messages, so if this in an interactive
438@@ -2112,7 +2112,7 @@ session_pty_req(Session *s) 438@@ -2117,7 +2117,7 @@ session_pty_req(Session *s)
439 tty_parse_modes(s->ttyfd, &n_bytes); 439 tty_parse_modes(s->ttyfd, &n_bytes);
440 440
441 if (!use_privsep) 441 if (!use_privsep)
@@ -458,11 +458,11 @@ index 6a2f35e..ef6593c 100644
458 const char *value); 458 const char *value);
459 459
460diff --git a/sshd.c b/sshd.c 460diff --git a/sshd.c b/sshd.c
461index fe65132..0a30101 100644 461index d787fea..e343d90 100644
462--- a/sshd.c 462--- a/sshd.c
463+++ b/sshd.c 463+++ b/sshd.c
464@@ -763,7 +763,7 @@ privsep_postauth(Authctxt *authctxt) 464@@ -769,7 +769,7 @@ privsep_postauth(Authctxt *authctxt)
465 bzero(rnd, sizeof(rnd)); 465 explicit_bzero(rnd, sizeof(rnd));
466 466
467 /* Drop privileges */ 467 /* Drop privileges */
468- do_setusercontext(authctxt->pw); 468- do_setusercontext(authctxt->pw);
diff --git a/debian/patches/series b/debian/patches/series
index 5048e254d..5d21e57d1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -26,5 +26,3 @@ no-openssl-version-check.patch
26gnome-ssh-askpass2-icon.patch 26gnome-ssh-askpass2-icon.patch
27sigstop.patch 27sigstop.patch
28debian-config.patch 28debian-config.patch
29fix-case-sensitive-matching.patch
30getsockname-error.patch
diff --git a/debian/patches/shell-path.patch b/debian/patches/shell-path.patch
index 71d52e0bc..48c16d2a2 100644
--- a/debian/patches/shell-path.patch
+++ b/debian/patches/shell-path.patch
@@ -1,4 +1,4 @@
1From 43dbfc0c515e0adeddb097a9996dea382cc9e582 Mon Sep 17 00:00:00 2001 1From 6103c29d855e82c098e88ee12f05a6eb41f659ce Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:00 +0000 3Date: Sun, 9 Feb 2014 16:10:00 +0000
4Subject: Look for $SHELL on the path for ProxyCommand/LocalCommand 4Subject: Look for $SHELL on the path for ProxyCommand/LocalCommand
@@ -16,7 +16,7 @@ Patch-Name: shell-path.patch
16 1 file changed, 2 insertions(+), 2 deletions(-) 16 1 file changed, 2 insertions(+), 2 deletions(-)
17 17
18diff --git a/sshconnect.c b/sshconnect.c 18diff --git a/sshconnect.c b/sshconnect.c
19index d21781e..ef4d9e0 100644 19index 573d7a8..9e02837 100644
20--- a/sshconnect.c 20--- a/sshconnect.c
21+++ b/sshconnect.c 21+++ b/sshconnect.c
22@@ -227,7 +227,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) 22@@ -227,7 +227,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
@@ -28,7 +28,7 @@ index d21781e..ef4d9e0 100644
28 perror(argv[0]); 28 perror(argv[0]);
29 exit(1); 29 exit(1);
30 } 30 }
31@@ -1384,7 +1384,7 @@ ssh_local_cmd(const char *args) 31@@ -1387,7 +1387,7 @@ ssh_local_cmd(const char *args)
32 if (pid == 0) { 32 if (pid == 0) {
33 signal(SIGPIPE, SIG_DFL); 33 signal(SIGPIPE, SIG_DFL);
34 debug3("Executing %s -c \"%s\"", shell, args); 34 debug3("Executing %s -c \"%s\"", shell, args);
diff --git a/debian/patches/sigstop.patch b/debian/patches/sigstop.patch
index b34dbcda0..ac9eb4794 100644
--- a/debian/patches/sigstop.patch
+++ b/debian/patches/sigstop.patch
@@ -1,4 +1,4 @@
1From b0d3fe663d6a54b1348934946bbf8678b7470d14 Mon Sep 17 00:00:00 2001 1From d9ac4d127f53d92cf3426fba28ff351e5e165ae2 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:17 +0000 3Date: Sun, 9 Feb 2014 16:10:17 +0000
4Subject: Support synchronisation with service supervisor using SIGSTOP 4Subject: Support synchronisation with service supervisor using SIGSTOP
@@ -12,10 +12,10 @@ Patch-Name: sigstop.patch
12 1 file changed, 4 insertions(+) 12 1 file changed, 4 insertions(+)
13 13
14diff --git a/sshd.c b/sshd.c 14diff --git a/sshd.c b/sshd.c
15index c49a877..23e8c2d 100644 15index 665c0b9..ffe360c 100644
16--- a/sshd.c 16--- a/sshd.c
17+++ b/sshd.c 17+++ b/sshd.c
18@@ -1924,6 +1924,10 @@ main(int ac, char **av) 18@@ -1931,6 +1931,10 @@ main(int ac, char **av)
19 } 19 }
20 } 20 }
21 21
diff --git a/debian/patches/ssh-agent-setgid.patch b/debian/patches/ssh-agent-setgid.patch
index 1eedfe297..af23075b3 100644
--- a/debian/patches/ssh-agent-setgid.patch
+++ b/debian/patches/ssh-agent-setgid.patch
@@ -1,4 +1,4 @@
1From 5708dae528688dd06c784773f0e05f5e3739d0e5 Mon Sep 17 00:00:00 2001 1From d53483ab71ac2a9195c8f171da5a5dcf54ec16ec Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:13 +0000 3Date: Sun, 9 Feb 2014 16:10:13 +0000
4Subject: Document consequences of ssh-agent being setgid in ssh-agent(1) 4Subject: Document consequences of ssh-agent being setgid in ssh-agent(1)
diff --git a/debian/patches/ssh-argv0.patch b/debian/patches/ssh-argv0.patch
index 9afa12a88..d456facea 100644
--- a/debian/patches/ssh-argv0.patch
+++ b/debian/patches/ssh-argv0.patch
@@ -1,4 +1,4 @@
1From ce4c3e861126520177b929d3d04e57c0dc9cb70d Mon Sep 17 00:00:00 2001 1From d4ac61d918775f629eff9a389d0f7bb0f8426b48 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:10 +0000 3Date: Sun, 9 Feb 2014 16:10:10 +0000
4Subject: ssh(1): Refer to ssh-argv0(1) 4Subject: ssh(1): Refer to ssh-argv0(1)
diff --git a/debian/patches/ssh-vulnkey-compat.patch b/debian/patches/ssh-vulnkey-compat.patch
index 9939dda8c..fa738b084 100644
--- a/debian/patches/ssh-vulnkey-compat.patch
+++ b/debian/patches/ssh-vulnkey-compat.patch
@@ -1,4 +1,4 @@
1From 9ae199bbd2484aed4fd61535221a96f1ae478712 Mon Sep 17 00:00:00 2001 1From d422205e757aaf23e8e0e787f842ef37f6a170a2 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@ubuntu.com> 2From: Colin Watson <cjwatson@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:09:50 +0000 3Date: Sun, 9 Feb 2014 16:09:50 +0000
4Subject: Accept obsolete ssh-vulnkey configuration options 4Subject: Accept obsolete ssh-vulnkey configuration options
@@ -17,10 +17,10 @@ Patch-Name: ssh-vulnkey-compat.patch
17 2 files changed, 2 insertions(+) 17 2 files changed, 2 insertions(+)
18 18
19diff --git a/readconf.c b/readconf.c 19diff --git a/readconf.c b/readconf.c
20index cb8bcb2..2a1fe8e 100644 20index 7613ff2..bcd8cad 100644
21--- a/readconf.c 21--- a/readconf.c
22+++ b/readconf.c 22+++ b/readconf.c
23@@ -171,6 +171,7 @@ static struct { 23@@ -172,6 +172,7 @@ static struct {
24 { "passwordauthentication", oPasswordAuthentication }, 24 { "passwordauthentication", oPasswordAuthentication },
25 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 25 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
26 { "kbdinteractivedevices", oKbdInteractiveDevices }, 26 { "kbdinteractivedevices", oKbdInteractiveDevices },
@@ -29,10 +29,10 @@ index cb8bcb2..2a1fe8e 100644
29 { "pubkeyauthentication", oPubkeyAuthentication }, 29 { "pubkeyauthentication", oPubkeyAuthentication },
30 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 30 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
31diff --git a/servconf.c b/servconf.c 31diff --git a/servconf.c b/servconf.c
32index 29209e4..65f71ad 100644 32index 0083cf8..90de888 100644
33--- a/servconf.c 33--- a/servconf.c
34+++ b/servconf.c 34+++ b/servconf.c
35@@ -456,6 +456,7 @@ static struct { 35@@ -448,6 +448,7 @@ static struct {
36 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, 36 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
37 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, 37 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
38 { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, 38 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
diff --git a/debian/patches/ssh1-keepalive.patch b/debian/patches/ssh1-keepalive.patch
index 4456498bf..ded7c122a 100644
--- a/debian/patches/ssh1-keepalive.patch
+++ b/debian/patches/ssh1-keepalive.patch
@@ -1,4 +1,4 @@
1From 40a23637b9cb6364c8baeb2c25b1d8115bc740c0 Mon Sep 17 00:00:00 2001 1From 789d58ed3df120c7b80d07fb2d259c216194a29c Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:09:51 +0000 3Date: Sun, 9 Feb 2014 16:09:51 +0000
4Subject: Partial server keep-alive implementation for SSH1 4Subject: Partial server keep-alive implementation for SSH1
@@ -13,7 +13,7 @@ Patch-Name: ssh1-keepalive.patch
13 2 files changed, 19 insertions(+), 11 deletions(-) 13 2 files changed, 19 insertions(+), 11 deletions(-)
14 14
15diff --git a/clientloop.c b/clientloop.c 15diff --git a/clientloop.c b/clientloop.c
16index cc23e35..cd1739f 100644 16index 6d8cd7d..73a800c 100644
17--- a/clientloop.c 17--- a/clientloop.c
18+++ b/clientloop.c 18+++ b/clientloop.c
19@@ -563,16 +563,21 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt) 19@@ -563,16 +563,21 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
@@ -57,10 +57,10 @@ index cc23e35..cd1739f 100644
57 server_alive_time = now + options.server_alive_interval; 57 server_alive_time = now + options.server_alive_interval;
58 } 58 }
59diff --git a/ssh_config.5 b/ssh_config.5 59diff --git a/ssh_config.5 b/ssh_config.5
60index 49505ae..617a312 100644 60index e7accd6..473971e 100644
61--- a/ssh_config.5 61--- a/ssh_config.5
62+++ b/ssh_config.5 62+++ b/ssh_config.5
63@@ -1288,7 +1288,10 @@ If, for example, 63@@ -1294,7 +1294,10 @@ If, for example,
64 .Cm ServerAliveCountMax 64 .Cm ServerAliveCountMax
65 is left at the default, if the server becomes unresponsive, 65 is left at the default, if the server becomes unresponsive,
66 ssh will disconnect after approximately 45 seconds. 66 ssh will disconnect after approximately 45 seconds.
diff --git a/debian/patches/syslog-level-silent.patch b/debian/patches/syslog-level-silent.patch
index 30ba118e8..7cbd3a7e3 100644
--- a/debian/patches/syslog-level-silent.patch
+++ b/debian/patches/syslog-level-silent.patch
@@ -1,4 +1,4 @@
1From 3afa62c176aa4ea42a87372f10f355efa48f582b Mon Sep 17 00:00:00 2001 1From b8ed36cdf2dbebc01e52e83eece4bb1d78607e84 Mon Sep 17 00:00:00 2001
2From: Jonathan David Amery <jdamery@ysolde.ucam.org> 2From: Jonathan David Amery <jdamery@ysolde.ucam.org>
3Date: Sun, 9 Feb 2014 16:09:54 +0000 3Date: Sun, 9 Feb 2014 16:09:54 +0000
4Subject: "LogLevel SILENT" compatibility 4Subject: "LogLevel SILENT" compatibility
@@ -33,10 +33,10 @@ index 32e1d2e..53e7b65 100644
33 { "FATAL", SYSLOG_LEVEL_FATAL }, 33 { "FATAL", SYSLOG_LEVEL_FATAL },
34 { "ERROR", SYSLOG_LEVEL_ERROR }, 34 { "ERROR", SYSLOG_LEVEL_ERROR },
35diff --git a/ssh.c b/ssh.c 35diff --git a/ssh.c b/ssh.c
36index 5de8fcf..0cea713 100644 36index 1e6cb90..3e63708 100644
37--- a/ssh.c 37--- a/ssh.c
38+++ b/ssh.c 38+++ b/ssh.c
39@@ -889,7 +889,7 @@ main(int ac, char **av) 39@@ -965,7 +965,7 @@ main(int ac, char **av)
40 /* Do not allocate a tty if stdin is not a tty. */ 40 /* Do not allocate a tty if stdin is not a tty. */
41 if ((!isatty(fileno(stdin)) || stdin_null_flag) && 41 if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
42 options.request_tty != REQUEST_TTY_FORCE) { 42 options.request_tty != REQUEST_TTY_FORCE) {
diff --git a/debian/patches/user-group-modes.patch b/debian/patches/user-group-modes.patch
index 5062d7d80..3cdb9d8a1 100644
--- a/debian/patches/user-group-modes.patch
+++ b/debian/patches/user-group-modes.patch
@@ -1,4 +1,4 @@
1From 0879622ccc5a92902c6ffd88391824cfb2d27924 Mon Sep 17 00:00:00 2001 1From 77638f6662ecd8500e1b97e537233b1277ca829f Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:09:58 +0000 3Date: Sun, 9 Feb 2014 16:09:58 +0000
4Subject: Allow harmless group-writability 4Subject: Allow harmless group-writability
@@ -216,10 +216,10 @@ index 4aab9a9..f99de7f 100644
216- return 0; 216- return 0;
217-} 217-}
218diff --git a/readconf.c b/readconf.c 218diff --git a/readconf.c b/readconf.c
219index e79e355..273552d 100644 219index 6409937..32c4b42 100644
220--- a/readconf.c 220--- a/readconf.c
221+++ b/readconf.c 221+++ b/readconf.c
222@@ -36,6 +36,8 @@ 222@@ -37,6 +37,8 @@
223 #include <stdio.h> 223 #include <stdio.h>
224 #include <string.h> 224 #include <string.h>
225 #include <unistd.h> 225 #include <unistd.h>
@@ -228,7 +228,7 @@ index e79e355..273552d 100644
228 #ifdef HAVE_UTIL_H 228 #ifdef HAVE_UTIL_H
229 #include <util.h> 229 #include <util.h>
230 #endif 230 #endif
231@@ -1475,8 +1477,7 @@ read_config_file(const char *filename, struct passwd *pw, const char *host, 231@@ -1477,8 +1479,7 @@ read_config_file(const char *filename, struct passwd *pw, const char *host,
232 232
233 if (fstat(fileno(f), &sb) == -1) 233 if (fstat(fileno(f), &sb) == -1)
234 fatal("fstat %s: %s", filename, strerror(errno)); 234 fatal("fstat %s: %s", filename, strerror(errno));
@@ -252,10 +252,10 @@ index 27794e2..ff5e6ac 100644
252 .It Pa ~/.ssh/environment 252 .It Pa ~/.ssh/environment
253 Contains additional definitions for environment variables; see 253 Contains additional definitions for environment variables; see
254diff --git a/ssh_config.5 b/ssh_config.5 254diff --git a/ssh_config.5 b/ssh_config.5
255index b3c5dc6..3c6b9d4 100644 255index 3172fd4..4bf7cbb 100644
256--- a/ssh_config.5 256--- a/ssh_config.5
257+++ b/ssh_config.5 257+++ b/ssh_config.5
258@@ -1523,6 +1523,8 @@ The format of this file is described above. 258@@ -1529,6 +1529,8 @@ The format of this file is described above.
259 This file is used by the SSH client. 259 This file is used by the SSH client.
260 Because of the potential for abuse, this file must have strict permissions: 260 Because of the potential for abuse, this file must have strict permissions:
261 read/write for the user, and not accessible by others. 261 read/write for the user, and not accessible by others.
diff --git a/digest-libc.c b/digest-libc.c
new file mode 100644
index 000000000..1804b0698
--- /dev/null
+++ b/digest-libc.c
@@ -0,0 +1,238 @@
1/* $OpenBSD: digest-libc.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */
2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * Copyright (c) 2014 Markus Friedl. All rights reserved.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include "includes.h"
20
21#include <sys/types.h>
22#include <limits.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <md5.h>
27#include <rmd160.h>
28#include <sha1.h>
29#include <sha2.h>
30
31#include "buffer.h"
32#include "digest.h"
33
34typedef void md_init_fn(void *mdctx);
35typedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen);
36typedef void md_final_fn(u_int8_t[], void *mdctx);
37
38struct ssh_digest_ctx {
39 int alg;
40 void *mdctx;
41};
42
43struct ssh_digest {
44 int id;
45 const char *name;
46 size_t block_len;
47 size_t digest_len;
48 size_t ctx_len;
49 md_init_fn *md_init;
50 md_update_fn *md_update;
51 md_final_fn *md_final;
52};
53
54/* NB. Indexed directly by algorithm number */
55const struct ssh_digest digests[SSH_DIGEST_MAX] = {
56 {
57 SSH_DIGEST_MD5,
58 "MD5",
59 MD5_BLOCK_LENGTH,
60 MD5_DIGEST_LENGTH,
61 sizeof(MD5_CTX),
62 (md_init_fn *) MD5Init,
63 (md_update_fn *) MD5Update,
64 (md_final_fn *) MD5Final
65 },
66 {
67 SSH_DIGEST_RIPEMD160,
68 "RIPEMD160",
69 RMD160_BLOCK_LENGTH,
70 RMD160_DIGEST_LENGTH,
71 sizeof(RMD160_CTX),
72 (md_init_fn *) RMD160Init,
73 (md_update_fn *) RMD160Update,
74 (md_final_fn *) RMD160Final
75 },
76 {
77 SSH_DIGEST_SHA1,
78 "SHA1",
79 SHA1_BLOCK_LENGTH,
80 SHA1_DIGEST_LENGTH,
81 sizeof(SHA1_CTX),
82 (md_init_fn *) SHA1Init,
83 (md_update_fn *) SHA1Update,
84 (md_final_fn *) SHA1Final
85 },
86 {
87 SSH_DIGEST_SHA256,
88 "SHA256",
89 SHA256_BLOCK_LENGTH,
90 SHA256_DIGEST_LENGTH,
91 sizeof(SHA2_CTX),
92 (md_init_fn *) SHA256Init,
93 (md_update_fn *) SHA256Update,
94 (md_final_fn *) SHA256Final
95 },
96 {
97 SSH_DIGEST_SHA384,
98 "SHA384",
99 SHA384_BLOCK_LENGTH,
100 SHA384_DIGEST_LENGTH,
101 sizeof(SHA2_CTX),
102 (md_init_fn *) SHA384Init,
103 (md_update_fn *) SHA384Update,
104 (md_final_fn *) SHA384Final
105 },
106 {
107 SSH_DIGEST_SHA512,
108 "SHA512",
109 SHA512_BLOCK_LENGTH,
110 SHA512_DIGEST_LENGTH,
111 sizeof(SHA2_CTX),
112 (md_init_fn *) SHA512Init,
113 (md_update_fn *) SHA512Update,
114 (md_final_fn *) SHA512Final
115 }
116};
117
118static const struct ssh_digest *
119ssh_digest_by_alg(int alg)
120{
121 if (alg < 0 || alg >= SSH_DIGEST_MAX)
122 return NULL;
123 if (digests[alg].id != alg) /* sanity */
124 return NULL;
125 return &(digests[alg]);
126}
127
128size_t
129ssh_digest_bytes(int alg)
130{
131 const struct ssh_digest *digest = ssh_digest_by_alg(alg);
132
133 return digest == NULL ? 0 : digest->digest_len;
134}
135
136size_t
137ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
138{
139 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
140
141 return digest == NULL ? 0 : digest->block_len;
142}
143
144struct ssh_digest_ctx *
145ssh_digest_start(int alg)
146{
147 const struct ssh_digest *digest = ssh_digest_by_alg(alg);
148 struct ssh_digest_ctx *ret;
149
150 if (digest == NULL || (ret = calloc(1, sizeof(ret))) == NULL)
151 return NULL;
152 if ((ret->mdctx = calloc(1, digest->ctx_len)) == NULL) {
153 free(ret);
154 return NULL;
155 }
156 ret->alg = alg;
157 digest->md_init(ret->mdctx);
158 return ret;
159}
160
161int
162ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
163{
164 const struct ssh_digest *digest = ssh_digest_by_alg(from->alg);
165
166 if (digest == NULL || from->alg != to->alg)
167 return -1;
168 memcpy(to->mdctx, from->mdctx, digest->ctx_len);
169 return 0;
170}
171
172int
173ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
174{
175 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
176
177 if (digest == NULL)
178 return -1;
179 digest->md_update(ctx->mdctx, m, mlen);
180 return 0;
181}
182
183int
184ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b)
185{
186 return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b));
187}
188
189int
190ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
191{
192 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
193
194 if (digest == NULL)
195 return -1;
196 if (dlen > UINT_MAX)
197 return -1;
198 if (dlen < digest->digest_len) /* No truncation allowed */
199 return -1;
200 digest->md_final(d, ctx->mdctx);
201 return 0;
202}
203
204void
205ssh_digest_free(struct ssh_digest_ctx *ctx)
206{
207 const struct ssh_digest *digest;
208
209 if (ctx != NULL) {
210 digest = ssh_digest_by_alg(ctx->alg);
211 if (digest) {
212 explicit_bzero(ctx->mdctx, digest->ctx_len);
213 free(ctx->mdctx);
214 explicit_bzero(ctx, sizeof(*ctx));
215 free(ctx);
216 }
217 }
218}
219
220int
221ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
222{
223 struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
224
225 if (ctx == NULL)
226 return -1;
227 if (ssh_digest_update(ctx, m, mlen) != 0 ||
228 ssh_digest_final(ctx, d, dlen) != 0)
229 return -1;
230 ssh_digest_free(ctx);
231 return 0;
232}
233
234int
235ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
236{
237 return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen);
238}
diff --git a/digest.c b/digest-openssl.c
index a221819eb..863d37d03 100644
--- a/digest.c
+++ b/digest-openssl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest.c,v 1.3 2014/01/20 00:08:48 djm Exp $ */ 1/* $OpenBSD: digest-openssl.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -72,6 +72,12 @@ ssh_digest_bytes(int alg)
72 return digest == NULL ? 0 : digest->digest_len; 72 return digest == NULL ? 0 : digest->digest_len;
73} 73}
74 74
75size_t
76ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
77{
78 return EVP_MD_CTX_block_size(&ctx->mdctx);
79}
80
75struct ssh_digest_ctx * 81struct ssh_digest_ctx *
76ssh_digest_start(int alg) 82ssh_digest_start(int alg)
77{ 83{
@@ -90,6 +96,15 @@ ssh_digest_start(int alg)
90} 96}
91 97
92int 98int
99ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
100{
101 /* we have bcopy-style order while openssl has memcpy-style */
102 if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
103 return -1;
104 return 0;
105}
106
107int
93ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) 108ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
94{ 109{
95 if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) 110 if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
@@ -123,9 +138,11 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
123void 138void
124ssh_digest_free(struct ssh_digest_ctx *ctx) 139ssh_digest_free(struct ssh_digest_ctx *ctx)
125{ 140{
126 EVP_MD_CTX_cleanup(&ctx->mdctx); 141 if (ctx != NULL) {
127 memset(ctx, 0, sizeof(*ctx)); 142 EVP_MD_CTX_cleanup(&ctx->mdctx);
128 free(ctx); 143 explicit_bzero(ctx, sizeof(*ctx));
144 free(ctx);
145 }
129} 146}
130 147
131int 148int
diff --git a/digest.h b/digest.h
index faefda3f5..0fb207fca 100644
--- a/digest.h
+++ b/digest.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: digest.h,v 1.2 2014/01/27 18:58:14 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -30,9 +30,18 @@
30#define SSH_DIGEST_SHA512 5 30#define SSH_DIGEST_SHA512 5
31#define SSH_DIGEST_MAX 6 31#define SSH_DIGEST_MAX 6
32 32
33struct ssh_digest_ctx;
34
33/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ 35/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
34size_t ssh_digest_bytes(int alg); 36size_t ssh_digest_bytes(int alg);
35 37
38/* Returns the block size of the digest, e.g. for implementing HMAC */
39size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx);
40
41/* Copies internal state of digest of 'from' to 'to' */
42int ssh_digest_copy_state(struct ssh_digest_ctx *from,
43 struct ssh_digest_ctx *to);
44
36/* One-shot API */ 45/* One-shot API */
37int ssh_digest_memory(int alg, const void *m, size_t mlen, 46int ssh_digest_memory(int alg, const void *m, size_t mlen,
38 u_char *d, size_t dlen) 47 u_char *d, size_t dlen)
@@ -42,7 +51,6 @@ int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
42 __attribute__((__bounded__(__buffer__, 3, 4))); 51 __attribute__((__bounded__(__buffer__, 3, 4)));
43 52
44/* Update API */ 53/* Update API */
45struct ssh_digest_ctx;
46struct ssh_digest_ctx *ssh_digest_start(int alg); 54struct ssh_digest_ctx *ssh_digest_start(int alg);
47int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) 55int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
48 __attribute__((__bounded__(__buffer__, 2, 3))); 56 __attribute__((__bounded__(__buffer__, 2, 3)));
diff --git a/gss-serv.c b/gss-serv.c
index feb1ed763..c33463bdf 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gss-serv.c,v 1.24 2013/07/20 01:55:13 djm Exp $ */ 1/* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
@@ -72,6 +72,25 @@ ssh_gssapi_mech* supported_mechs[]= {
72 &gssapi_null_mech, 72 &gssapi_null_mech,
73}; 73};
74 74
75/*
76 * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the
77 * list of supported mechanisms before privsep is set up.
78 */
79static gss_OID_set supported_oids;
80
81void
82ssh_gssapi_prepare_supported_oids(void)
83{
84 ssh_gssapi_supported_oids(&supported_oids);
85}
86
87OM_uint32
88ssh_gssapi_test_oid_supported(OM_uint32 *ms, gss_OID member, int *present)
89{
90 if (supported_oids == NULL)
91 ssh_gssapi_prepare_supported_oids();
92 return gss_test_oid_set_member(ms, member, supported_oids, present);
93}
75 94
76/* 95/*
77 * Acquire credentials for a server running on the current host. 96 * Acquire credentials for a server running on the current host.
@@ -435,7 +454,8 @@ ssh_gssapi_userok(char *user, struct passwd *pw)
435 gss_release_buffer(&lmin, &gssapi_client.displayname); 454 gss_release_buffer(&lmin, &gssapi_client.displayname);
436 gss_release_buffer(&lmin, &gssapi_client.exportedname); 455 gss_release_buffer(&lmin, &gssapi_client.exportedname);
437 gss_release_cred(&lmin, &gssapi_client.creds); 456 gss_release_cred(&lmin, &gssapi_client.creds);
438 memset(&gssapi_client, 0, sizeof(ssh_gssapi_client)); 457 explicit_bzero(&gssapi_client,
458 sizeof(ssh_gssapi_client));
439 return 0; 459 return 0;
440 } 460 }
441 else 461 else
diff --git a/hmac.c b/hmac.c
new file mode 100644
index 000000000..99317b0f9
--- /dev/null
+++ b/hmac.c
@@ -0,0 +1,197 @@
1/* $OpenBSD: hmac.c,v 1.10 2014/01/31 16:39:19 tedu Exp $ */
2/*
3 * Copyright (c) 2014 Markus Friedl. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "includes.h"
19
20#include <sys/types.h>
21#include <string.h>
22
23#include "buffer.h"
24#include "digest.h"
25#include "hmac.h"
26
27struct ssh_hmac_ctx {
28 int alg;
29 struct ssh_digest_ctx *ictx;
30 struct ssh_digest_ctx *octx;
31 struct ssh_digest_ctx *digest;
32 u_char *buf;
33 size_t buf_len;
34};
35
36size_t
37ssh_hmac_bytes(int alg)
38{
39 return ssh_digest_bytes(alg);
40}
41
42struct ssh_hmac_ctx *
43ssh_hmac_start(int alg)
44{
45 struct ssh_hmac_ctx *ret;
46
47 if ((ret = calloc(1, sizeof(*ret))) == NULL)
48 return NULL;
49 ret->alg = alg;
50 if ((ret->ictx = ssh_digest_start(alg)) == NULL ||
51 (ret->octx = ssh_digest_start(alg)) == NULL ||
52 (ret->digest = ssh_digest_start(alg)) == NULL)
53 goto fail;
54 ret->buf_len = ssh_digest_blocksize(ret->ictx);
55 if ((ret->buf = calloc(1, ret->buf_len)) == NULL)
56 goto fail;
57 return ret;
58fail:
59 ssh_hmac_free(ret);
60 return NULL;
61}
62
63int
64ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)
65{
66 size_t i;
67
68 /* reset ictx and octx if no is key given */
69 if (key != NULL) {
70 /* truncate long keys */
71 if (klen <= ctx->buf_len)
72 memcpy(ctx->buf, key, klen);
73 else if (ssh_digest_memory(ctx->alg, key, klen, ctx->buf,
74 ctx->buf_len) < 0)
75 return -1;
76 for (i = 0; i < ctx->buf_len; i++)
77 ctx->buf[i] ^= 0x36;
78 if (ssh_digest_update(ctx->ictx, ctx->buf, ctx->buf_len) < 0)
79 return -1;
80 for (i = 0; i < ctx->buf_len; i++)
81 ctx->buf[i] ^= 0x36 ^ 0x5c;
82 if (ssh_digest_update(ctx->octx, ctx->buf, ctx->buf_len) < 0)
83 return -1;
84 explicit_bzero(ctx->buf, ctx->buf_len);
85 }
86 /* start with ictx */
87 if (ssh_digest_copy_state(ctx->ictx, ctx->digest) < 0)
88 return -1;
89 return 0;
90}
91
92int
93ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)
94{
95 return ssh_digest_update(ctx->digest, m, mlen);
96}
97
98int
99ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b)
100{
101 return ssh_digest_update_buffer(ctx->digest, b);
102}
103
104int
105ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)
106{
107 size_t len;
108
109 len = ssh_digest_bytes(ctx->alg);
110 if (dlen < len ||
111 ssh_digest_final(ctx->digest, ctx->buf, len))
112 return -1;
113 /* switch to octx */
114 if (ssh_digest_copy_state(ctx->octx, ctx->digest) < 0 ||
115 ssh_digest_update(ctx->digest, ctx->buf, len) < 0 ||
116 ssh_digest_final(ctx->digest, d, dlen) < 0)
117 return -1;
118 return 0;
119}
120
121void
122ssh_hmac_free(struct ssh_hmac_ctx *ctx)
123{
124 if (ctx != NULL) {
125 ssh_digest_free(ctx->ictx);
126 ssh_digest_free(ctx->octx);
127 ssh_digest_free(ctx->digest);
128 if (ctx->buf) {
129 explicit_bzero(ctx->buf, ctx->buf_len);
130 free(ctx->buf);
131 }
132 explicit_bzero(ctx, sizeof(*ctx));
133 free(ctx);
134 }
135}
136
137#ifdef TEST
138
139/* cc -DTEST hmac.c digest.c buffer.c cleanup.c fatal.c log.c xmalloc.c -lcrypto */
140static void
141hmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen)
142{
143 struct ssh_hmac_ctx *ctx;
144 size_t i;
145 u_char digest[16];
146
147 if ((ctx = ssh_hmac_start(SSH_DIGEST_MD5)) == NULL)
148 printf("ssh_hmac_start failed");
149 if (ssh_hmac_init(ctx, key, klen) < 0 ||
150 ssh_hmac_update(ctx, m, mlen) < 0 ||
151 ssh_hmac_final(ctx, digest, sizeof(digest)) < 0)
152 printf("ssh_hmac_xxx failed");
153 ssh_hmac_free(ctx);
154
155 if (memcmp(e, digest, elen)) {
156 for (i = 0; i < elen; i++)
157 printf("[%zd] %2.2x %2.2x\n", i, e[i], digest[i]);
158 printf("mismatch\n");
159 } else
160 printf("ok\n");
161}
162
163int
164main(int argc, char **argv)
165{
166 /* try test vectors from RFC 2104 */
167
168 u_char key1[16] = {
169 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
170 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb };
171 u_char *data1 = "Hi There";
172 u_char dig1[16] = {
173 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
174 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d };
175
176 u_char *key2 = "Jefe";
177 u_char *data2 = "what do ya want for nothing?";
178 u_char dig2[16] = {
179 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
180 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 };
181
182 u_char key3[16];
183 u_char data3[50];
184 u_char dig3[16] = {
185 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
186 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 };
187 memset(key3, 0xaa, sizeof(key3));
188 memset(data3, 0xdd, sizeof(data3));
189
190 hmac_test(key1, sizeof(key1), data1, strlen(data1), dig1, sizeof(dig1));
191 hmac_test(key2, strlen(key2), data2, strlen(data2), dig2, sizeof(dig2));
192 hmac_test(key3, sizeof(key3), data3, sizeof(data3), dig3, sizeof(dig3));
193
194 return 0;
195}
196
197#endif
diff --git a/hmac.h b/hmac.h
new file mode 100644
index 000000000..2374a6955
--- /dev/null
+++ b/hmac.h
@@ -0,0 +1,37 @@
1/* $OpenBSD: hmac.h,v 1.6 2014/01/27 18:58:14 markus Exp $ */
2/*
3 * Copyright (c) 2014 Markus Friedl. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef _HMAC_H
19#define _HMAC_H
20
21/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
22size_t ssh_hmac_bytes(int alg);
23
24struct ssh_hmac_ctx;
25struct ssh_hmac_ctx *ssh_hmac_start(int alg);
26
27/* Sets the state of the HMAC or resets the state if key == NULL */
28int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)
29 __attribute__((__bounded__(__buffer__, 2, 3)));
30int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)
31 __attribute__((__bounded__(__buffer__, 2, 3)));
32int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b);
33int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)
34 __attribute__((__bounded__(__buffer__, 2, 3)));
35void ssh_hmac_free(struct ssh_hmac_ctx *ctx);
36
37#endif /* _HMAC_H */
diff --git a/hostfile.c b/hostfile.c
index 2778fb5df..8bc9540b7 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: hostfile.c,v 1.55 2014/01/31 16:39:19 tedu 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
@@ -42,9 +42,6 @@
42 42
43#include <netinet/in.h> 43#include <netinet/in.h>
44 44
45#include <openssl/hmac.h>
46#include <openssl/sha.h>
47
48#include <resolv.h> 45#include <resolv.h>
49#include <stdarg.h> 46#include <stdarg.h>
50#include <stdio.h> 47#include <stdio.h>
@@ -58,6 +55,7 @@
58#include "log.h" 55#include "log.h"
59#include "misc.h" 56#include "misc.h"
60#include "digest.h" 57#include "digest.h"
58#include "hmac.h"
61 59
62struct hostkeys { 60struct hostkeys {
63 struct hostkey_entry *entries; 61 struct hostkey_entry *entries;
@@ -102,9 +100,9 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
102 debug2("extract_salt: salt decode error"); 100 debug2("extract_salt: salt decode error");
103 return (-1); 101 return (-1);
104 } 102 }
105 if (ret != SHA_DIGEST_LENGTH) { 103 if (ret != (int)ssh_hmac_bytes(SSH_DIGEST_SHA1)) {
106 debug2("extract_salt: expected salt len %d, got %d", 104 debug2("extract_salt: expected salt len %zd, got %d",
107 SHA_DIGEST_LENGTH, ret); 105 ssh_hmac_bytes(SSH_DIGEST_SHA1), ret);
108 return (-1); 106 return (-1);
109 } 107 }
110 108
@@ -114,14 +112,13 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
114char * 112char *
115host_hash(const char *host, const char *name_from_hostfile, u_int src_len) 113host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
116{ 114{
117 const EVP_MD *md = EVP_sha1(); 115 struct ssh_hmac_ctx *ctx;
118 HMAC_CTX mac_ctx;
119 u_char salt[256], result[256]; 116 u_char salt[256], result[256];
120 char uu_salt[512], uu_result[512]; 117 char uu_salt[512], uu_result[512];
121 static char encoded[1024]; 118 static char encoded[1024];
122 u_int i, len; 119 u_int i, len;
123 120
124 len = EVP_MD_size(md); 121 len = ssh_digest_bytes(SSH_DIGEST_SHA1);
125 122
126 if (name_from_hostfile == NULL) { 123 if (name_from_hostfile == NULL) {
127 /* Create new salt */ 124 /* Create new salt */
@@ -134,14 +131,16 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
134 return (NULL); 131 return (NULL);
135 } 132 }
136 133
137 HMAC_Init(&mac_ctx, salt, len, md); 134 if ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL ||
138 HMAC_Update(&mac_ctx, (u_char *)host, strlen(host)); 135 ssh_hmac_init(ctx, salt, len) < 0 ||
139 HMAC_Final(&mac_ctx, result, NULL); 136 ssh_hmac_update(ctx, host, strlen(host)) < 0 ||
140 HMAC_cleanup(&mac_ctx); 137 ssh_hmac_final(ctx, result, sizeof(result)))
138 fatal("%s: ssh_hmac failed", __func__);
139 ssh_hmac_free(ctx);
141 140
142 if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || 141 if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
143 __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) 142 __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
144 fatal("host_hash: __b64_ntop failed"); 143 fatal("%s: __b64_ntop failed", __func__);
145 144
146 snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, 145 snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
147 HASH_DELIM, uu_result); 146 HASH_DELIM, uu_result);
@@ -334,10 +333,10 @@ free_hostkeys(struct hostkeys *hostkeys)
334 free(hostkeys->entries[i].host); 333 free(hostkeys->entries[i].host);
335 free(hostkeys->entries[i].file); 334 free(hostkeys->entries[i].file);
336 key_free(hostkeys->entries[i].key); 335 key_free(hostkeys->entries[i].key);
337 bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); 336 explicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries));
338 } 337 }
339 free(hostkeys->entries); 338 free(hostkeys->entries);
340 bzero(hostkeys, sizeof(*hostkeys)); 339 explicit_bzero(hostkeys, sizeof(*hostkeys));
341 free(hostkeys); 340 free(hostkeys);
342} 341}
343 342
diff --git a/jpake.c b/jpake.c
deleted file mode 100644
index 3dd87916a..000000000
--- a/jpake.c
+++ /dev/null
@@ -1,456 +0,0 @@
1/* $OpenBSD: jpake.c,v 1.8 2013/05/17 00:13:13 djm Exp $ */
2/*
3 * Copyright (c) 2008 Damien Miller. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/*
19 * Shared components of zero-knowledge password auth using J-PAKE protocol
20 * as described in:
21 *
22 * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling",
23 * 16th Workshop on Security Protocols, Cambridge, April 2008
24 *
25 * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
26 */
27
28#include "includes.h"
29
30#include <sys/types.h>
31
32#include <stdio.h>
33#include <string.h>
34#include <stdarg.h>
35
36#include <openssl/bn.h>
37#include <openssl/evp.h>
38
39#include "xmalloc.h"
40#include "ssh2.h"
41#include "key.h"
42#include "hostfile.h"
43#include "auth.h"
44#include "buffer.h"
45#include "packet.h"
46#include "dispatch.h"
47#include "log.h"
48#include "misc.h"
49
50#include "jpake.h"
51#include "schnorr.h"
52
53#ifdef JPAKE
54
55/* RFC3526 group 5, 1536 bits */
56#define JPAKE_GROUP_G "2"
57#define JPAKE_GROUP_P \
58 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" \
59 "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" \
60 "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
61 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" \
62 "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \
63 "9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
64
65struct modp_group *
66jpake_default_group(void)
67{
68 return modp_group_from_g_and_safe_p(JPAKE_GROUP_G, JPAKE_GROUP_P);
69}
70
71struct jpake_ctx *
72jpake_new(void)
73{
74 struct jpake_ctx *ret;
75
76 ret = xcalloc(1, sizeof(*ret));
77
78 ret->grp = jpake_default_group();
79
80 ret->s = ret->k = NULL;
81 ret->x1 = ret->x2 = ret->x3 = ret->x4 = NULL;
82 ret->g_x1 = ret->g_x2 = ret->g_x3 = ret->g_x4 = NULL;
83 ret->a = ret->b = NULL;
84
85 ret->client_id = ret->server_id = NULL;
86 ret->h_k_cid_sessid = ret->h_k_sid_sessid = NULL;
87
88 debug3("%s: alloc %p", __func__, ret);
89
90 return ret;
91}
92
93void
94jpake_free(struct jpake_ctx *pctx)
95{
96 debug3("%s: free %p", __func__, pctx);
97
98#define JPAKE_BN_CLEAR_FREE(v) \
99 do { \
100 if ((v) != NULL) { \
101 BN_clear_free(v); \
102 (v) = NULL; \
103 } \
104 } while (0)
105#define JPAKE_BUF_CLEAR_FREE(v, l) \
106 do { \
107 if ((v) != NULL) { \
108 bzero((v), (l)); \
109 free(v); \
110 (v) = NULL; \
111 (l) = 0; \
112 } \
113 } while (0)
114
115 JPAKE_BN_CLEAR_FREE(pctx->s);
116 JPAKE_BN_CLEAR_FREE(pctx->k);
117 JPAKE_BN_CLEAR_FREE(pctx->x1);
118 JPAKE_BN_CLEAR_FREE(pctx->x2);
119 JPAKE_BN_CLEAR_FREE(pctx->x3);
120 JPAKE_BN_CLEAR_FREE(pctx->x4);
121 JPAKE_BN_CLEAR_FREE(pctx->g_x1);
122 JPAKE_BN_CLEAR_FREE(pctx->g_x2);
123 JPAKE_BN_CLEAR_FREE(pctx->g_x3);
124 JPAKE_BN_CLEAR_FREE(pctx->g_x4);
125 JPAKE_BN_CLEAR_FREE(pctx->a);
126 JPAKE_BN_CLEAR_FREE(pctx->b);
127
128 JPAKE_BUF_CLEAR_FREE(pctx->client_id, pctx->client_id_len);
129 JPAKE_BUF_CLEAR_FREE(pctx->server_id, pctx->server_id_len);
130 JPAKE_BUF_CLEAR_FREE(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
131 JPAKE_BUF_CLEAR_FREE(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
132
133#undef JPAKE_BN_CLEAR_FREE
134#undef JPAKE_BUF_CLEAR_FREE
135
136 bzero(pctx, sizeof(*pctx));
137 free(pctx);
138}
139
140/* dump entire jpake_ctx. NB. includes private values! */
141void
142jpake_dump(struct jpake_ctx *pctx, const char *fmt, ...)
143{
144 char *out;
145 va_list args;
146
147 out = NULL;
148 va_start(args, fmt);
149 vasprintf(&out, fmt, args);
150 va_end(args);
151 if (out == NULL)
152 fatal("%s: vasprintf failed", __func__);
153
154 debug3("%s: %s (ctx at %p)", __func__, out, pctx);
155 if (pctx == NULL) {
156 free(out);
157 return;
158 }
159
160#define JPAKE_DUMP_BN(a) do { \
161 if ((a) != NULL) \
162 JPAKE_DEBUG_BN(((a), "%s = ", #a)); \
163 } while (0)
164#define JPAKE_DUMP_BUF(a, b) do { \
165 if ((a) != NULL) \
166 JPAKE_DEBUG_BUF((a, b, "%s", #a)); \
167 } while (0)
168
169 JPAKE_DUMP_BN(pctx->s);
170 JPAKE_DUMP_BN(pctx->k);
171 JPAKE_DUMP_BN(pctx->x1);
172 JPAKE_DUMP_BN(pctx->x2);
173 JPAKE_DUMP_BN(pctx->x3);
174 JPAKE_DUMP_BN(pctx->x4);
175 JPAKE_DUMP_BN(pctx->g_x1);
176 JPAKE_DUMP_BN(pctx->g_x2);
177 JPAKE_DUMP_BN(pctx->g_x3);
178 JPAKE_DUMP_BN(pctx->g_x4);
179 JPAKE_DUMP_BN(pctx->a);
180 JPAKE_DUMP_BN(pctx->b);
181
182 JPAKE_DUMP_BUF(pctx->client_id, pctx->client_id_len);
183 JPAKE_DUMP_BUF(pctx->server_id, pctx->server_id_len);
184 JPAKE_DUMP_BUF(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
185 JPAKE_DUMP_BUF(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
186
187 debug3("%s: %s done", __func__, out);
188 free(out);
189}
190
191/* Shared parts of step 1 exchange calculation */
192void
193jpake_step1(struct modp_group *grp,
194 u_char **id, u_int *id_len,
195 BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
196 u_char **priv1_proof, u_int *priv1_proof_len,
197 u_char **priv2_proof, u_int *priv2_proof_len)
198{
199 BN_CTX *bn_ctx;
200
201 if ((bn_ctx = BN_CTX_new()) == NULL)
202 fatal("%s: BN_CTX_new", __func__);
203
204 /* Random nonce to prevent replay */
205 *id = xmalloc(KZP_ID_LEN);
206 *id_len = KZP_ID_LEN;
207 arc4random_buf(*id, *id_len);
208
209 /*
210 * x1/x3 is a random element of Zq
211 * x2/x4 is a random element of Z*q
212 * We also exclude [1] from x1/x3 candidates and [0, 1] from
213 * x2/x4 candiates to avoid possible degeneracy (i.e. g^0, g^1).
214 */
215 if ((*priv1 = bn_rand_range_gt_one(grp->q)) == NULL ||
216 (*priv2 = bn_rand_range_gt_one(grp->q)) == NULL)
217 fatal("%s: bn_rand_range_gt_one", __func__);
218
219 /*
220 * client: g_x1 = g^x1 mod p / server: g_x3 = g^x3 mod p
221 * client: g_x2 = g^x2 mod p / server: g_x4 = g^x4 mod p
222 */
223 if ((*g_priv1 = BN_new()) == NULL ||
224 (*g_priv2 = BN_new()) == NULL)
225 fatal("%s: BN_new", __func__);
226 if (BN_mod_exp(*g_priv1, grp->g, *priv1, grp->p, bn_ctx) == -1)
227 fatal("%s: BN_mod_exp", __func__);
228 if (BN_mod_exp(*g_priv2, grp->g, *priv2, grp->p, bn_ctx) == -1)
229 fatal("%s: BN_mod_exp", __func__);
230
231 /* Generate proofs for holding x1/x3 and x2/x4 */
232 if (schnorr_sign_buf(grp->p, grp->q, grp->g,
233 *priv1, *g_priv1, *id, *id_len,
234 priv1_proof, priv1_proof_len) != 0)
235 fatal("%s: schnorr_sign", __func__);
236 if (schnorr_sign_buf(grp->p, grp->q, grp->g,
237 *priv2, *g_priv2, *id, *id_len,
238 priv2_proof, priv2_proof_len) != 0)
239 fatal("%s: schnorr_sign", __func__);
240
241 BN_CTX_free(bn_ctx);
242}
243
244/* Shared parts of step 2 exchange calculation */
245void
246jpake_step2(struct modp_group *grp, BIGNUM *s,
247 BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
248 const u_char *theirid, u_int theirid_len,
249 const u_char *myid, u_int myid_len,
250 const u_char *theirpub1_proof, u_int theirpub1_proof_len,
251 const u_char *theirpub2_proof, u_int theirpub2_proof_len,
252 BIGNUM **newpub,
253 u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len)
254{
255 BN_CTX *bn_ctx;
256 BIGNUM *tmp, *exponent;
257
258 /* Validate peer's step 1 values */
259 if (BN_cmp(theirpub1, BN_value_one()) <= 0)
260 fatal("%s: theirpub1 <= 1", __func__);
261 if (BN_cmp(theirpub1, grp->p) >= 0)
262 fatal("%s: theirpub1 >= p", __func__);
263 if (BN_cmp(theirpub2, BN_value_one()) <= 0)
264 fatal("%s: theirpub2 <= 1", __func__);
265 if (BN_cmp(theirpub2, grp->p) >= 0)
266 fatal("%s: theirpub2 >= p", __func__);
267
268 if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1,
269 theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1)
270 fatal("%s: schnorr_verify theirpub1 failed", __func__);
271 if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub2,
272 theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1)
273 fatal("%s: schnorr_verify theirpub2 failed", __func__);
274
275 if ((bn_ctx = BN_CTX_new()) == NULL)
276 fatal("%s: BN_CTX_new", __func__);
277
278 if ((*newpub = BN_new()) == NULL ||
279 (tmp = BN_new()) == NULL ||
280 (exponent = BN_new()) == NULL)
281 fatal("%s: BN_new", __func__);
282
283 /*
284 * client: exponent = x2 * s mod p
285 * server: exponent = x4 * s mod p
286 */
287 if (BN_mod_mul(exponent, mypriv2, s, grp->q, bn_ctx) != 1)
288 fatal("%s: BN_mod_mul (exponent = mypriv2 * s mod p)",
289 __func__);
290
291 /*
292 * client: tmp = g^(x1 + x3 + x4) mod p
293 * server: tmp = g^(x1 + x2 + x3) mod p
294 */
295 if (BN_mod_mul(tmp, mypub1, theirpub1, grp->p, bn_ctx) != 1)
296 fatal("%s: BN_mod_mul (tmp = mypub1 * theirpub1 mod p)",
297 __func__);
298 if (BN_mod_mul(tmp, tmp, theirpub2, grp->p, bn_ctx) != 1)
299 fatal("%s: BN_mod_mul (tmp = tmp * theirpub2 mod p)", __func__);
300
301 /*
302 * client: a = tmp^exponent = g^((x1+x3+x4) * x2 * s) mod p
303 * server: b = tmp^exponent = g^((x1+x2+x3) * x4 * s) mod p
304 */
305 if (BN_mod_exp(*newpub, tmp, exponent, grp->p, bn_ctx) != 1)
306 fatal("%s: BN_mod_mul (newpub = tmp^exponent mod p)", __func__);
307
308 JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
309 JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__));
310
311 /* Note the generator here is 'tmp', not g */
312 if (schnorr_sign_buf(grp->p, grp->q, tmp, exponent, *newpub,
313 myid, myid_len,
314 newpub_exponent_proof, newpub_exponent_proof_len) != 0)
315 fatal("%s: schnorr_sign newpub", __func__);
316
317 BN_clear_free(tmp); /* XXX stash for later use? */
318 BN_clear_free(exponent); /* XXX stash for later use? (yes, in conf) */
319
320 BN_CTX_free(bn_ctx);
321}
322
323/* Confirmation hash calculation */
324void
325jpake_confirm_hash(const BIGNUM *k,
326 const u_char *endpoint_id, u_int endpoint_id_len,
327 const u_char *sess_id, u_int sess_id_len,
328 u_char **confirm_hash, u_int *confirm_hash_len)
329{
330 Buffer b;
331
332 /*
333 * Calculate confirmation proof:
334 * client: H(k || client_id || session_id)
335 * server: H(k || server_id || session_id)
336 */
337 buffer_init(&b);
338 buffer_put_bignum2(&b, k);
339 buffer_put_string(&b, endpoint_id, endpoint_id_len);
340 buffer_put_string(&b, sess_id, sess_id_len);
341 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
342 confirm_hash, confirm_hash_len) != 0)
343 fatal("%s: hash_buffer", __func__);
344 buffer_free(&b);
345}
346
347/* Shared parts of key derivation and confirmation calculation */
348void
349jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
350 BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
351 BIGNUM *theirpub1, BIGNUM *theirpub2,
352 const u_char *my_id, u_int my_id_len,
353 const u_char *their_id, u_int their_id_len,
354 const u_char *sess_id, u_int sess_id_len,
355 const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len,
356 BIGNUM **k,
357 u_char **confirm_hash, u_int *confirm_hash_len)
358{
359 BN_CTX *bn_ctx;
360 BIGNUM *tmp;
361
362 if ((bn_ctx = BN_CTX_new()) == NULL)
363 fatal("%s: BN_CTX_new", __func__);
364 if ((tmp = BN_new()) == NULL ||
365 (*k = BN_new()) == NULL)
366 fatal("%s: BN_new", __func__);
367
368 /* Validate step 2 values */
369 if (BN_cmp(step2_val, BN_value_one()) <= 0)
370 fatal("%s: step2_val <= 1", __func__);
371 if (BN_cmp(step2_val, grp->p) >= 0)
372 fatal("%s: step2_val >= p", __func__);
373
374 /*
375 * theirpriv2_s_proof is calculated with a different generator:
376 * tmp = g^(mypriv1+mypriv2+theirpub1) = g^mypub1*g^mypub2*g^theirpub1
377 * Calculate it here so we can check the signature.
378 */
379 if (BN_mod_mul(tmp, mypub1, mypub2, grp->p, bn_ctx) != 1)
380 fatal("%s: BN_mod_mul (tmp = mypub1 * mypub2 mod p)", __func__);
381 if (BN_mod_mul(tmp, tmp, theirpub1, grp->p, bn_ctx) != 1)
382 fatal("%s: BN_mod_mul (tmp = tmp * theirpub1 mod p)", __func__);
383
384 JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
385
386 if (schnorr_verify_buf(grp->p, grp->q, tmp, step2_val,
387 their_id, their_id_len,
388 theirpriv2_s_proof, theirpriv2_s_proof_len) != 1)
389 fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__);
390
391 /*
392 * Derive shared key:
393 * client: k = (b / g^(x2*x4*s))^x2 = g^((x1+x3)*x2*x4*s)
394 * server: k = (a / g^(x2*x4*s))^x4 = g^((x1+x3)*x2*x4*s)
395 *
396 * Computed as:
397 * client: k = (g_x4^(q - (x2 * s)) * b)^x2 mod p
398 * server: k = (g_x2^(q - (x4 * s)) * b)^x4 mod p
399 */
400 if (BN_mul(tmp, mypriv2, s, bn_ctx) != 1)
401 fatal("%s: BN_mul (tmp = mypriv2 * s)", __func__);
402 if (BN_mod_sub(tmp, grp->q, tmp, grp->q, bn_ctx) != 1)
403 fatal("%s: BN_mod_sub (tmp = q - tmp mod q)", __func__);
404 if (BN_mod_exp(tmp, theirpub2, tmp, grp->p, bn_ctx) != 1)
405 fatal("%s: BN_mod_exp (tmp = theirpub2^tmp) mod p", __func__);
406 if (BN_mod_mul(tmp, tmp, step2_val, grp->p, bn_ctx) != 1)
407 fatal("%s: BN_mod_mul (tmp = tmp * step2_val) mod p", __func__);
408 if (BN_mod_exp(*k, tmp, mypriv2, grp->p, bn_ctx) != 1)
409 fatal("%s: BN_mod_exp (k = tmp^mypriv2) mod p", __func__);
410
411 BN_CTX_free(bn_ctx);
412 BN_clear_free(tmp);
413
414 jpake_confirm_hash(*k, my_id, my_id_len, sess_id, sess_id_len,
415 confirm_hash, confirm_hash_len);
416}
417
418/*
419 * Calculate and check confirmation hash from peer. Returns 1 on success
420 * 0 on failure/mismatch.
421 */
422int
423jpake_check_confirm(const BIGNUM *k,
424 const u_char *peer_id, u_int peer_id_len,
425 const u_char *sess_id, u_int sess_id_len,
426 const u_char *peer_confirm_hash, u_int peer_confirm_hash_len)
427{
428 u_char *expected_confirm_hash;
429 u_int expected_confirm_hash_len;
430 int success = 0;
431
432 /* Calculate and verify expected confirmation hash */
433 jpake_confirm_hash(k, peer_id, peer_id_len, sess_id, sess_id_len,
434 &expected_confirm_hash, &expected_confirm_hash_len);
435
436 JPAKE_DEBUG_BUF((expected_confirm_hash, expected_confirm_hash_len,
437 "%s: expected confirm hash", __func__));
438 JPAKE_DEBUG_BUF((peer_confirm_hash, peer_confirm_hash_len,
439 "%s: received confirm hash", __func__));
440
441 if (peer_confirm_hash_len != expected_confirm_hash_len)
442 error("%s: confirmation length mismatch (my %u them %u)",
443 __func__, expected_confirm_hash_len, peer_confirm_hash_len);
444 else if (timingsafe_bcmp(peer_confirm_hash, expected_confirm_hash,
445 expected_confirm_hash_len) == 0)
446 success = 1;
447 bzero(expected_confirm_hash, expected_confirm_hash_len);
448 free(expected_confirm_hash);
449 debug3("%s: success = %d", __func__, success);
450 return success;
451}
452
453/* XXX main() function with tests */
454
455#endif /* JPAKE */
456
diff --git a/jpake.h b/jpake.h
deleted file mode 100644
index a3f2cf025..000000000
--- a/jpake.h
+++ /dev/null
@@ -1,114 +0,0 @@
1/* $OpenBSD: jpake.h,v 1.2 2009/03/05 07:18:19 djm Exp $ */
2/*
3 * Copyright (c) 2008 Damien Miller. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef JPAKE_H
19#define JPAKE_H
20
21#include <sys/types.h>
22
23#include <openssl/bn.h>
24
25/* Set JPAKE_DEBUG in CFLAGS for privacy-violating debugging */
26#ifndef JPAKE_DEBUG
27# define JPAKE_DEBUG_BN(a)
28# define JPAKE_DEBUG_BUF(a)
29# define JPAKE_DEBUG_CTX(a)
30#else
31# define JPAKE_DEBUG_BN(a) debug3_bn a
32# define JPAKE_DEBUG_BUF(a) debug3_buf a
33# define JPAKE_DEBUG_CTX(a) jpake_dump a
34#endif /* JPAKE_DEBUG */
35
36#define KZP_ID_LEN 16 /* Length of client and server IDs */
37
38struct jpake_ctx {
39 /* Parameters */
40 struct modp_group *grp;
41
42 /* Private values shared by client and server */
43 BIGNUM *s; /* Secret (salted, crypted password) */
44 BIGNUM *k; /* Derived key */
45
46 /* Client private values (NULL for server) */
47 BIGNUM *x1; /* random in Zq */
48 BIGNUM *x2; /* random in Z*q */
49
50 /* Server private values (NULL for server) */
51 BIGNUM *x3; /* random in Zq */
52 BIGNUM *x4; /* random in Z*q */
53
54 /* Step 1: C->S */
55 u_char *client_id; /* Anti-replay nonce */
56 u_int client_id_len;
57 BIGNUM *g_x1; /* g^x1 */
58 BIGNUM *g_x2; /* g^x2 */
59
60 /* Step 1: S->C */
61 u_char *server_id; /* Anti-replay nonce */
62 u_int server_id_len;
63 BIGNUM *g_x3; /* g^x3 */
64 BIGNUM *g_x4; /* g^x4 */
65
66 /* Step 2: C->S */
67 BIGNUM *a; /* g^((x1+x3+x4)*x2*s) */
68
69 /* Step 2: S->C */
70 BIGNUM *b; /* g^((x1+x2+x3)*x4*s) */
71
72 /* Confirmation: C->S */
73 u_char *h_k_cid_sessid; /* H(k || client_id || session_id) */
74 u_int h_k_cid_sessid_len;
75
76 /* Confirmation: S->C */
77 u_char *h_k_sid_sessid; /* H(k || server_id || session_id) */
78 u_int h_k_sid_sessid_len;
79};
80
81/* jpake.c */
82struct modp_group *jpake_default_group(void);
83void jpake_dump(struct jpake_ctx *, const char *, ...)
84 __attribute__((__nonnull__ (2)))
85 __attribute__((format(printf, 2, 3)));
86struct jpake_ctx *jpake_new(void);
87void jpake_free(struct jpake_ctx *);
88
89void jpake_step1(struct modp_group *, u_char **, u_int *,
90 BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
91 u_char **, u_int *, u_char **, u_int *);
92
93void jpake_step2(struct modp_group *, BIGNUM *,
94 BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
95 const u_char *, u_int, const u_char *, u_int,
96 const u_char *, u_int, const u_char *, u_int,
97 BIGNUM **, u_char **, u_int *);
98
99void jpake_confirm_hash(const BIGNUM *,
100 const u_char *, u_int,
101 const u_char *, u_int,
102 u_char **, u_int *);
103
104void jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
105 BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
106 const u_char *, u_int, const u_char *, u_int,
107 const u_char *, u_int, const u_char *, u_int,
108 BIGNUM **, u_char **, u_int *);
109
110int jpake_check_confirm(const BIGNUM *, const u_char *, u_int,
111 const u_char *, u_int, const u_char *, u_int);
112
113#endif /* JPAKE_H */
114
diff --git a/kex.c b/kex.c
index 49d0fc8fd..d114ee3e0 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.97 2014/01/25 20:35:37 markus Exp $ */ 1/* $OpenBSD: kex.c,v 1.98 2014/02/02 03:44:31 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 *
@@ -682,8 +682,8 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
682 fatal("%s: ssh_digest_final failed", __func__); 682 fatal("%s: ssh_digest_final failed", __func__);
683 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); 683 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
684 684
685 memset(nbuf, 0, sizeof(nbuf)); 685 explicit_bzero(nbuf, sizeof(nbuf));
686 memset(obuf, 0, sizeof(obuf)); 686 explicit_bzero(obuf, sizeof(obuf));
687} 687}
688 688
689#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 689#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
diff --git a/kex.h b/kex.h
index 8fbcb2b79..ea698c467 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.h,v 1.61 2014/01/25 10:12:50 dtucker Exp $ */ 1/* $OpenBSD: kex.h,v 1.62 2014/01/27 18:58:14 markus 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.
@@ -108,9 +108,8 @@ struct Mac {
108 u_int key_len; 108 u_int key_len;
109 int type; 109 int type;
110 int etm; /* Encrypt-then-MAC */ 110 int etm; /* Encrypt-then-MAC */
111 const EVP_MD *evp_md; 111 struct ssh_hmac_ctx *hmac_ctx;
112 HMAC_CTX evp_ctx; 112 struct umac_ctx *umac_ctx;
113 struct umac_ctx *umac_ctx;
114}; 113};
115struct Comp { 114struct Comp {
116 int type; 115 int type;
diff --git a/kexc25519.c b/kexc25519.c
index 48ca4aaa2..ee79b4327 100644
--- a/kexc25519.c
+++ b/kexc25519.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexc25519.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ 1/* $OpenBSD: kexc25519.c,v 1.5 2014/01/31 16:39:19 tedu 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.
@@ -70,7 +70,7 @@ kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
70#endif 70#endif
71 buffer_clear(out); 71 buffer_clear(out);
72 buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE); 72 buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE);
73 memset(shared_key, 0, CURVE25519_SIZE); /* XXX explicit_bzero() */ 73 explicit_bzero(shared_key, CURVE25519_SIZE);
74} 74}
75 75
76void 76void
diff --git a/kexdhc.c b/kexdhc.c
index 78509af21..f7a19fc13 100644
--- a/kexdhc.c
+++ b/kexdhc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexdhc.c,v 1.14 2014/01/12 08:13:13 djm Exp $ */ 1/* $OpenBSD: kexdhc.c,v 1.15 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -124,7 +124,7 @@ kexdh_client(Kex *kex)
124 fatal("kexdh_client: BN_new failed"); 124 fatal("kexdh_client: BN_new failed");
125 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 125 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
126 fatal("kexdh_client: BN_bin2bn failed"); 126 fatal("kexdh_client: BN_bin2bn failed");
127 memset(kbuf, 0, klen); 127 explicit_bzero(kbuf, klen);
128 free(kbuf); 128 free(kbuf);
129 129
130 /* calc and verify H */ 130 /* calc and verify H */
diff --git a/kexdhs.c b/kexdhs.c
index d2c7adc96..c3011f741 100644
--- a/kexdhs.c
+++ b/kexdhs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexdhs.c,v 1.17 2014/01/12 08:13:13 djm Exp $ */ 1/* $OpenBSD: kexdhs.c,v 1.18 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -110,7 +110,7 @@ kexdh_server(Kex *kex)
110 fatal("kexdh_server: BN_new failed"); 110 fatal("kexdh_server: BN_new failed");
111 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 111 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
112 fatal("kexdh_server: BN_bin2bn failed"); 112 fatal("kexdh_server: BN_bin2bn failed");
113 memset(kbuf, 0, klen); 113 explicit_bzero(kbuf, klen);
114 free(kbuf); 114 free(kbuf);
115 115
116 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); 116 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
diff --git a/kexecdhc.c b/kexecdhc.c
index e3d1cf5f9..2f7629cca 100644
--- a/kexecdhc.c
+++ b/kexecdhc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdhc.c,v 1.6 2014/01/12 08:13:13 djm Exp $ */ 1/* $OpenBSD: kexecdhc.c,v 1.7 2014/02/02 03:44:31 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.
@@ -119,7 +119,7 @@ kexecdh_client(Kex *kex)
119 fatal("%s: BN_new failed", __func__); 119 fatal("%s: BN_new failed", __func__);
120 if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) 120 if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
121 fatal("%s: BN_bin2bn failed", __func__); 121 fatal("%s: BN_bin2bn failed", __func__);
122 memset(kbuf, 0, klen); 122 explicit_bzero(kbuf, klen);
123 free(kbuf); 123 free(kbuf);
124 124
125 /* calc and verify H */ 125 /* calc and verify H */
diff --git a/kexecdhs.c b/kexecdhs.c
index 6fbb79c9d..2700b7219 100644
--- a/kexecdhs.c
+++ b/kexecdhs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdhs.c,v 1.9 2014/01/12 08:13:13 djm Exp $ */ 1/* $OpenBSD: kexecdhs.c,v 1.10 2014/02/02 03:44:31 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.
@@ -103,7 +103,7 @@ kexecdh_server(Kex *kex)
103 fatal("%s: BN_new failed", __func__); 103 fatal("%s: BN_new failed", __func__);
104 if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) 104 if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
105 fatal("%s: BN_bin2bn failed", __func__); 105 fatal("%s: BN_bin2bn failed", __func__);
106 memset(kbuf, 0, klen); 106 explicit_bzero(kbuf, klen);
107 free(kbuf); 107 free(kbuf);
108 108
109 /* calc H */ 109 /* calc H */
diff --git a/kexgexc.c b/kexgexc.c
index 629b5fbbc..355b7ba31 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgexc.c,v 1.16 2014/01/25 10:12:50 dtucker Exp $ */ 1/* $OpenBSD: kexgexc.c,v 1.17 2014/02/02 03:44:31 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.
@@ -162,7 +162,7 @@ kexgex_client(Kex *kex)
162 fatal("kexgex_client: BN_new failed"); 162 fatal("kexgex_client: BN_new failed");
163 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 163 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
164 fatal("kexgex_client: BN_bin2bn failed"); 164 fatal("kexgex_client: BN_bin2bn failed");
165 memset(kbuf, 0, klen); 165 explicit_bzero(kbuf, klen);
166 free(kbuf); 166 free(kbuf);
167 167
168 if (datafellows & SSH_OLD_DHGEX) 168 if (datafellows & SSH_OLD_DHGEX)
diff --git a/kexgexs.c b/kexgexs.c
index 8773778ed..770ad28a8 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgexs.c,v 1.18 2014/01/12 08:13:13 djm Exp $ */ 1/* $OpenBSD: kexgexs.c,v 1.19 2014/02/02 03:44:31 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.
@@ -150,7 +150,7 @@ kexgex_server(Kex *kex)
150 fatal("kexgex_server: BN_new failed"); 150 fatal("kexgex_server: BN_new failed");
151 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 151 if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
152 fatal("kexgex_server: BN_bin2bn failed"); 152 fatal("kexgex_server: BN_bin2bn failed");
153 memset(kbuf, 0, klen); 153 explicit_bzero(kbuf, klen);
154 free(kbuf); 154 free(kbuf);
155 155
156 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); 156 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
diff --git a/key.c b/key.c
index 7ac844c66..3d640e79f 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.115 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: key.c,v 1.116 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * read_bignum(): 3 * read_bignum():
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -242,12 +242,12 @@ key_free(Key *k)
242 case KEY_ED25519: 242 case KEY_ED25519:
243 case KEY_ED25519_CERT: 243 case KEY_ED25519_CERT:
244 if (k->ed25519_pk) { 244 if (k->ed25519_pk) {
245 memset(k->ed25519_pk, 0, ED25519_PK_SZ); 245 explicit_bzero(k->ed25519_pk, ED25519_PK_SZ);
246 free(k->ed25519_pk); 246 free(k->ed25519_pk);
247 k->ed25519_pk = NULL; 247 k->ed25519_pk = NULL;
248 } 248 }
249 if (k->ed25519_sk) { 249 if (k->ed25519_sk) {
250 memset(k->ed25519_sk, 0, ED25519_SK_SZ); 250 explicit_bzero(k->ed25519_sk, ED25519_SK_SZ);
251 free(k->ed25519_sk); 251 free(k->ed25519_sk);
252 k->ed25519_sk = NULL; 252 k->ed25519_sk = NULL;
253 } 253 }
@@ -415,7 +415,7 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
415 if ((ssh_digest_memory(hash_alg, blob, len, 415 if ((ssh_digest_memory(hash_alg, blob, len,
416 retval, SSH_DIGEST_MAX_LENGTH)) != 0) 416 retval, SSH_DIGEST_MAX_LENGTH)) != 0)
417 fatal("%s: digest_memory failed", __func__); 417 fatal("%s: digest_memory failed", __func__);
418 memset(blob, 0, len); 418 explicit_bzero(blob, len);
419 free(blob); 419 free(blob);
420 *dgst_raw_length = ssh_digest_bytes(hash_alg); 420 *dgst_raw_length = ssh_digest_bytes(hash_alg);
421 } else { 421 } else {
@@ -623,7 +623,7 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
623 dgst_rep); 623 dgst_rep);
624 break; 624 break;
625 } 625 }
626 memset(dgst_raw, 0, dgst_raw_len); 626 explicit_bzero(dgst_raw, dgst_raw_len);
627 free(dgst_raw); 627 free(dgst_raw);
628 return retval; 628 return retval;
629} 629}
@@ -1745,7 +1745,7 @@ to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain)
1745 *blobp = xmalloc(len); 1745 *blobp = xmalloc(len);
1746 memcpy(*blobp, buffer_ptr(&b), len); 1746 memcpy(*blobp, buffer_ptr(&b), len);
1747 } 1747 }
1748 memset(buffer_ptr(&b), 0, len); 1748 explicit_bzero(buffer_ptr(&b), len);
1749 buffer_free(&b); 1749 buffer_free(&b);
1750 return len; 1750 return len;
1751} 1751}
diff --git a/krl.c b/krl.c
index b2d0354f2..3b4cded05 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17/* $OpenBSD: krl.c,v 1.13 2013/07/20 22:20:42 djm Exp $ */ 17/* $OpenBSD: krl.c,v 1.14 2014/01/31 16:39:19 tedu Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -238,7 +238,7 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
238 struct revoked_serial rs, *ers, *crs, *irs; 238 struct revoked_serial rs, *ers, *crs, *irs;
239 239
240 KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi)); 240 KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi));
241 bzero(&rs, sizeof(rs)); 241 memset(&rs, 0, sizeof(rs));
242 rs.lo = lo; 242 rs.lo = lo;
243 rs.hi = hi; 243 rs.hi = hi;
244 ers = RB_NFIND(revoked_serial_tree, rt, &rs); 244 ers = RB_NFIND(revoked_serial_tree, rt, &rs);
@@ -1115,7 +1115,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
1115 struct revoked_certs *rc; 1115 struct revoked_certs *rc;
1116 1116
1117 /* Check explicitly revoked hashes first */ 1117 /* Check explicitly revoked hashes first */
1118 bzero(&rb, sizeof(rb)); 1118 memset(&rb, 0, sizeof(rb));
1119 if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL) 1119 if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL)
1120 return -1; 1120 return -1;
1121 erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); 1121 erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
@@ -1126,7 +1126,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
1126 } 1126 }
1127 1127
1128 /* Next, explicit keys */ 1128 /* Next, explicit keys */
1129 bzero(&rb, sizeof(rb)); 1129 memset(&rb, 0, sizeof(rb));
1130 if (plain_key_blob(key, &rb.blob, &rb.len) != 0) 1130 if (plain_key_blob(key, &rb.blob, &rb.len) != 0)
1131 return -1; 1131 return -1;
1132 erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); 1132 erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
@@ -1147,7 +1147,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
1147 return 0; /* No entry for this CA */ 1147 return 0; /* No entry for this CA */
1148 1148
1149 /* Check revocation by cert key ID */ 1149 /* Check revocation by cert key ID */
1150 bzero(&rki, sizeof(rki)); 1150 memset(&rki, 0, sizeof(rki));
1151 rki.key_id = key->cert->key_id; 1151 rki.key_id = key->cert->key_id;
1152 erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); 1152 erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki);
1153 if (erki != NULL) { 1153 if (erki != NULL) {
@@ -1162,7 +1162,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
1162 if (key_cert_is_legacy(key) || key->cert->serial == 0) 1162 if (key_cert_is_legacy(key) || key->cert->serial == 0)
1163 return 0; 1163 return 0;
1164 1164
1165 bzero(&rs, sizeof(rs)); 1165 memset(&rs, 0, sizeof(rs));
1166 rs.lo = rs.hi = key->cert->serial; 1166 rs.lo = rs.hi = key->cert->serial;
1167 ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); 1167 ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs);
1168 if (ers != NULL) { 1168 if (ers != NULL) {
diff --git a/mac.c b/mac.c
index d3a0b935f..097757213 100644
--- a/mac.c
+++ b/mac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mac.c,v 1.26 2014/01/04 17:50:55 tedu Exp $ */ 1/* $OpenBSD: mac.c,v 1.28 2014/02/07 06:55:54 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -27,8 +27,6 @@
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29 29
30#include <openssl/hmac.h>
31
32#include <stdarg.h> 30#include <stdarg.h>
33#include <string.h> 31#include <string.h>
34#include <signal.h> 32#include <signal.h>
@@ -42,18 +40,20 @@
42#include "mac.h" 40#include "mac.h"
43#include "misc.h" 41#include "misc.h"
44 42
43#include "digest.h"
44#include "hmac.h"
45#include "umac.h" 45#include "umac.h"
46 46
47#include "openbsd-compat/openssl-compat.h" 47#include "openbsd-compat/openssl-compat.h"
48 48
49#define SSH_EVP 1 /* OpenSSL EVP-based MAC */ 49#define SSH_DIGEST 1 /* SSH_DIGEST_XXX */
50#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ 50#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */
51#define SSH_UMAC128 3 51#define SSH_UMAC128 3
52 52
53struct macalg { 53struct macalg {
54 char *name; 54 char *name;
55 int type; 55 int type;
56 const EVP_MD * (*mdfunc)(void); 56 int alg;
57 int truncatebits; /* truncate digest if != 0 */ 57 int truncatebits; /* truncate digest if != 0 */
58 int key_len; /* just for UMAC */ 58 int key_len; /* just for UMAC */
59 int len; /* just for UMAC */ 59 int len; /* just for UMAC */
@@ -62,33 +62,33 @@ struct macalg {
62 62
63static const struct macalg macs[] = { 63static const struct macalg macs[] = {
64 /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ 64 /* Encrypt-and-MAC (encrypt-and-authenticate) variants */
65 { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, 65 { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
66 { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 }, 66 { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 },
67#ifdef HAVE_EVP_SHA256 67#ifdef HAVE_EVP_SHA256
68 { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 }, 68 { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },
69 { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 }, 69 { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },
70#endif 70#endif
71 { "hmac-md5", SSH_EVP, EVP_md5, 0, 0, 0, 0 }, 71 { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },
72 { "hmac-md5-96", SSH_EVP, EVP_md5, 96, 0, 0, 0 }, 72 { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },
73 { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, 73 { "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
74 { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, 74 { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
75 { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 }, 75 { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },
76 { "umac-128@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 0 }, 76 { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 },
77 77
78 /* Encrypt-then-MAC variants */ 78 /* Encrypt-then-MAC variants */
79 { "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 }, 79 { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
80 { "hmac-sha1-96-etm@openssh.com", SSH_EVP, EVP_sha1, 96, 0, 0, 1 }, 80 { "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 },
81#ifdef HAVE_EVP_SHA256 81#ifdef HAVE_EVP_SHA256
82 { "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 }, 82 { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },
83 { "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 }, 83 { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },
84#endif 84#endif
85 { "hmac-md5-etm@openssh.com", SSH_EVP, EVP_md5, 0, 0, 0, 1 }, 85 { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },
86 { "hmac-md5-96-etm@openssh.com", SSH_EVP, EVP_md5, 96, 0, 0, 1 }, 86 { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },
87 { "hmac-ripemd160-etm@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 1 }, 87 { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },
88 { "umac-64-etm@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 1 }, 88 { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 },
89 { "umac-128-etm@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 1 }, 89 { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 },
90 90
91 { NULL, 0, NULL, 0, 0, 0, 0 } 91 { NULL, 0, 0, 0, 0, 0, 0 }
92}; 92};
93 93
94/* Returns a list of supported MACs separated by the specified char. */ 94/* Returns a list of supported MACs separated by the specified char. */
@@ -113,14 +113,11 @@ mac_alg_list(char sep)
113static void 113static void
114mac_setup_by_alg(Mac *mac, const struct macalg *macalg) 114mac_setup_by_alg(Mac *mac, const struct macalg *macalg)
115{ 115{
116 int evp_len;
117
118 mac->type = macalg->type; 116 mac->type = macalg->type;
119 if (mac->type == SSH_EVP) { 117 if (mac->type == SSH_DIGEST) {
120 mac->evp_md = macalg->mdfunc(); 118 if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)
121 if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) 119 fatal("ssh_hmac_start(alg=%d) failed", macalg->alg);
122 fatal("mac %s len %d", mac->name, evp_len); 120 mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
123 mac->key_len = mac->mac_len = (u_int)evp_len;
124 } else { 121 } else {
125 mac->mac_len = macalg->len / 8; 122 mac->mac_len = macalg->len / 8;
126 mac->key_len = macalg->key_len / 8; 123 mac->key_len = macalg->key_len / 8;
@@ -139,9 +136,10 @@ mac_setup(Mac *mac, char *name)
139 for (m = macs; m->name != NULL; m++) { 136 for (m = macs; m->name != NULL; m++) {
140 if (strcmp(name, m->name) != 0) 137 if (strcmp(name, m->name) != 0)
141 continue; 138 continue;
142 if (mac != NULL) 139 if (mac != NULL) {
143 mac_setup_by_alg(mac, m); 140 mac_setup_by_alg(mac, m);
144 debug2("mac_setup: found %s", name); 141 debug2("mac_setup: setup %s", name);
142 }
145 return (0); 143 return (0);
146 } 144 }
147 debug2("mac_setup: unknown %s", name); 145 debug2("mac_setup: unknown %s", name);
@@ -152,13 +150,12 @@ int
152mac_init(Mac *mac) 150mac_init(Mac *mac)
153{ 151{
154 if (mac->key == NULL) 152 if (mac->key == NULL)
155 fatal("mac_init: no key"); 153 fatal("%s: no key", __func__);
156 switch (mac->type) { 154 switch (mac->type) {
157 case SSH_EVP: 155 case SSH_DIGEST:
158 if (mac->evp_md == NULL) 156 if (mac->hmac_ctx == NULL ||
157 ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
159 return -1; 158 return -1;
160 HMAC_CTX_init(&mac->evp_ctx);
161 HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md);
162 return 0; 159 return 0;
163 case SSH_UMAC: 160 case SSH_UMAC:
164 mac->umac_ctx = umac_new(mac->key); 161 mac->umac_ctx = umac_new(mac->key);
@@ -185,13 +182,14 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
185 mac->mac_len, sizeof(u)); 182 mac->mac_len, sizeof(u));
186 183
187 switch (mac->type) { 184 switch (mac->type) {
188 case SSH_EVP: 185 case SSH_DIGEST:
189 put_u32(b, seqno); 186 put_u32(b, seqno);
190 /* reset HMAC context */ 187 /* reset HMAC context */
191 HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); 188 if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 ||
192 HMAC_Update(&mac->evp_ctx, b, sizeof(b)); 189 ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 ||
193 HMAC_Update(&mac->evp_ctx, data, datalen); 190 ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 ||
194 HMAC_Final(&mac->evp_ctx, u.m, NULL); 191 ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)
192 fatal("ssh_hmac failed");
195 break; 193 break;
196 case SSH_UMAC: 194 case SSH_UMAC:
197 put_u64(nonce, seqno); 195 put_u64(nonce, seqno);
@@ -218,9 +216,9 @@ mac_clear(Mac *mac)
218 } else if (mac->type == SSH_UMAC128) { 216 } else if (mac->type == SSH_UMAC128) {
219 if (mac->umac_ctx != NULL) 217 if (mac->umac_ctx != NULL)
220 umac128_delete(mac->umac_ctx); 218 umac128_delete(mac->umac_ctx);
221 } else if (mac->evp_md != NULL) 219 } else if (mac->hmac_ctx != NULL)
222 HMAC_cleanup(&mac->evp_ctx); 220 ssh_hmac_free(mac->hmac_ctx);
223 mac->evp_md = NULL; 221 mac->hmac_ctx = NULL;
224 mac->umac_ctx = NULL; 222 mac->umac_ctx = NULL;
225} 223}
226 224
@@ -240,8 +238,6 @@ mac_valid(const char *names)
240 debug("bad mac %s [%s]", p, names); 238 debug("bad mac %s [%s]", p, names);
241 free(maclist); 239 free(maclist);
242 return (0); 240 return (0);
243 } else {
244 debug3("mac ok: %s [%s]", p, names);
245 } 241 }
246 } 242 }
247 debug3("macs ok: [%s]", names); 243 debug3("macs ok: [%s]", names);
diff --git a/moduli.0 b/moduli.0
index 7dc2cd540..7d678b459 100644
--- a/moduli.0
+++ b/moduli.0
@@ -71,4 +71,4 @@ STANDARDS
71 the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, 71 the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006,
72 2006. 72 2006.
73 73
74OpenBSD 5.4 September 26, 2012 OpenBSD 5.4 74OpenBSD 5.5 September 26, 2012 OpenBSD 5.5
diff --git a/monitor.c b/monitor.c
index 8ffea4f13..7c105e687 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.128 2013/11/04 11:51:16 markus Exp $ */ 1/* $OpenBSD: monitor.c,v 1.131 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -95,7 +95,6 @@
95#include "misc.h" 95#include "misc.h"
96#include "compat.h" 96#include "compat.h"
97#include "ssh2.h" 97#include "ssh2.h"
98#include "jpake.h"
99#include "roaming.h" 98#include "roaming.h"
100#include "authfd.h" 99#include "authfd.h"
101#ifdef USE_CONSOLEKIT 100#ifdef USE_CONSOLEKIT
@@ -165,11 +164,6 @@ int mm_answer_rsa_challenge(int, Buffer *);
165int mm_answer_rsa_response(int, Buffer *); 164int mm_answer_rsa_response(int, Buffer *);
166int mm_answer_sesskey(int, Buffer *); 165int mm_answer_sesskey(int, Buffer *);
167int mm_answer_sessid(int, Buffer *); 166int mm_answer_sessid(int, Buffer *);
168int mm_answer_jpake_get_pwdata(int, Buffer *);
169int mm_answer_jpake_step1(int, Buffer *);
170int mm_answer_jpake_step2(int, Buffer *);
171int mm_answer_jpake_key_confirm(int, Buffer *);
172int mm_answer_jpake_check_confirm(int, Buffer *);
173 167
174#ifdef USE_PAM 168#ifdef USE_PAM
175int mm_answer_pam_start(int, Buffer *); 169int mm_answer_pam_start(int, Buffer *);
@@ -266,13 +260,6 @@ struct mon_table mon_dispatch_proto20[] = {
266 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 260 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
267 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, 261 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
268#endif 262#endif
269#ifdef JPAKE
270 {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
271 {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1},
272 {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2},
273 {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm},
274 {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm},
275#endif
276 {0, 0, NULL} 263 {0, 0, NULL}
277}; 264};
278 265
@@ -455,15 +442,6 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
455 if (!authenticated) 442 if (!authenticated)
456 authctxt->failures++; 443 authctxt->failures++;
457 } 444 }
458#ifdef JPAKE
459 /* Cleanup JPAKE context after authentication */
460 if (ent->flags & MON_AUTHDECIDE) {
461 if (authctxt->jpake_ctx != NULL) {
462 jpake_free(authctxt->jpake_ctx);
463 authctxt->jpake_ctx = NULL;
464 }
465 }
466#endif
467 } 445 }
468 446
469 if (!authctxt->valid) 447 if (!authctxt->valid)
@@ -601,7 +579,7 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
601 struct pollfd pfd[2]; 579 struct pollfd pfd[2];
602 580
603 for (;;) { 581 for (;;) {
604 bzero(&pfd, sizeof(pfd)); 582 memset(&pfd, 0, sizeof(pfd));
605 pfd[0].fd = pmonitor->m_sendfd; 583 pfd[0].fd = pmonitor->m_sendfd;
606 pfd[0].events = POLLIN; 584 pfd[0].events = POLLIN;
607 pfd[1].fd = pmonitor->m_log_recvfd; 585 pfd[1].fd = pmonitor->m_log_recvfd;
@@ -939,7 +917,7 @@ mm_answer_authpassword(int sock, Buffer *m)
939 /* Only authenticate if the context is valid */ 917 /* Only authenticate if the context is valid */
940 authenticated = options.password_authentication && 918 authenticated = options.password_authentication &&
941 auth_password(authctxt, passwd); 919 auth_password(authctxt, passwd);
942 memset(passwd, 0, strlen(passwd)); 920 explicit_bzero(passwd, strlen(passwd));
943 free(passwd); 921 free(passwd);
944 922
945 buffer_clear(m); 923 buffer_clear(m);
@@ -1881,13 +1859,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1881 /* XXX inefficient for large buffers, need: buffer_init_from_string */ 1859 /* XXX inefficient for large buffers, need: buffer_init_from_string */
1882 buffer_clear(packet_get_input()); 1860 buffer_clear(packet_get_input());
1883 buffer_append(packet_get_input(), child_state.input, child_state.ilen); 1861 buffer_append(packet_get_input(), child_state.input, child_state.ilen);
1884 memset(child_state.input, 0, child_state.ilen); 1862 explicit_bzero(child_state.input, child_state.ilen);
1885 free(child_state.input); 1863 free(child_state.input);
1886 1864
1887 buffer_clear(packet_get_output()); 1865 buffer_clear(packet_get_output());
1888 buffer_append(packet_get_output(), child_state.output, 1866 buffer_append(packet_get_output(), child_state.output,
1889 child_state.olen); 1867 child_state.olen);
1890 memset(child_state.output, 0, child_state.olen); 1868 explicit_bzero(child_state.output, child_state.olen);
1891 free(child_state.output); 1869 free(child_state.output);
1892 1870
1893 /* Roaming */ 1871 /* Roaming */
@@ -2307,209 +2285,6 @@ mm_answer_gss_updatecreds(int socket, Buffer *m) {
2307 2285
2308#endif /* GSSAPI */ 2286#endif /* GSSAPI */
2309 2287
2310#ifdef JPAKE
2311int
2312mm_answer_jpake_step1(int sock, Buffer *m)
2313{
2314 struct jpake_ctx *pctx;
2315 u_char *x3_proof, *x4_proof;
2316 u_int x3_proof_len, x4_proof_len;
2317
2318 if (!options.zero_knowledge_password_authentication)
2319 fatal("zero_knowledge_password_authentication disabled");
2320
2321 if (authctxt->jpake_ctx != NULL)
2322 fatal("%s: authctxt->jpake_ctx already set (%p)",
2323 __func__, authctxt->jpake_ctx);
2324 authctxt->jpake_ctx = pctx = jpake_new();
2325
2326 jpake_step1(pctx->grp,
2327 &pctx->server_id, &pctx->server_id_len,
2328 &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4,
2329 &x3_proof, &x3_proof_len,
2330 &x4_proof, &x4_proof_len);
2331
2332 JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__));
2333
2334 buffer_clear(m);
2335
2336 buffer_put_string(m, pctx->server_id, pctx->server_id_len);
2337 buffer_put_bignum2(m, pctx->g_x3);
2338 buffer_put_bignum2(m, pctx->g_x4);
2339 buffer_put_string(m, x3_proof, x3_proof_len);
2340 buffer_put_string(m, x4_proof, x4_proof_len);
2341
2342 debug3("%s: sending step1", __func__);
2343 mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m);
2344
2345 bzero(x3_proof, x3_proof_len);
2346 bzero(x4_proof, x4_proof_len);
2347 free(x3_proof);
2348 free(x4_proof);
2349
2350 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1);
2351 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0);
2352
2353 return 0;
2354}
2355
2356int
2357mm_answer_jpake_get_pwdata(int sock, Buffer *m)
2358{
2359 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2360 char *hash_scheme, *salt;
2361
2362 if (pctx == NULL)
2363 fatal("%s: pctx == NULL", __func__);
2364
2365 auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt);
2366
2367 buffer_clear(m);
2368 /* pctx->s is sensitive, not returned to slave */
2369 buffer_put_cstring(m, hash_scheme);
2370 buffer_put_cstring(m, salt);
2371
2372 debug3("%s: sending pwdata", __func__);
2373 mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m);
2374
2375 bzero(hash_scheme, strlen(hash_scheme));
2376 bzero(salt, strlen(salt));
2377 free(hash_scheme);
2378 free(salt);
2379
2380 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1);
2381
2382 return 0;
2383}
2384
2385int
2386mm_answer_jpake_step2(int sock, Buffer *m)
2387{
2388 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2389 u_char *x1_proof, *x2_proof, *x4_s_proof;
2390 u_int x1_proof_len, x2_proof_len, x4_s_proof_len;
2391
2392 if (pctx == NULL)
2393 fatal("%s: pctx == NULL", __func__);
2394
2395 if ((pctx->g_x1 = BN_new()) == NULL ||
2396 (pctx->g_x2 = BN_new()) == NULL)
2397 fatal("%s: BN_new", __func__);
2398 buffer_get_bignum2(m, pctx->g_x1);
2399 buffer_get_bignum2(m, pctx->g_x2);
2400 pctx->client_id = buffer_get_string(m, &pctx->client_id_len);
2401 x1_proof = buffer_get_string(m, &x1_proof_len);
2402 x2_proof = buffer_get_string(m, &x2_proof_len);
2403
2404 jpake_step2(pctx->grp, pctx->s, pctx->g_x3,
2405 pctx->g_x1, pctx->g_x2, pctx->x4,
2406 pctx->client_id, pctx->client_id_len,
2407 pctx->server_id, pctx->server_id_len,
2408 x1_proof, x1_proof_len,
2409 x2_proof, x2_proof_len,
2410 &pctx->b,
2411 &x4_s_proof, &x4_s_proof_len);
2412
2413 JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__));
2414
2415 bzero(x1_proof, x1_proof_len);
2416 bzero(x2_proof, x2_proof_len);
2417 free(x1_proof);
2418 free(x2_proof);
2419
2420 buffer_clear(m);
2421
2422 buffer_put_bignum2(m, pctx->b);
2423 buffer_put_string(m, x4_s_proof, x4_s_proof_len);
2424
2425 debug3("%s: sending step2", __func__);
2426 mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m);
2427
2428 bzero(x4_s_proof, x4_s_proof_len);
2429 free(x4_s_proof);
2430
2431 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1);
2432
2433 return 0;
2434}
2435
2436int
2437mm_answer_jpake_key_confirm(int sock, Buffer *m)
2438{
2439 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2440 u_char *x2_s_proof;
2441 u_int x2_s_proof_len;
2442
2443 if (pctx == NULL)
2444 fatal("%s: pctx == NULL", __func__);
2445
2446 if ((pctx->a = BN_new()) == NULL)
2447 fatal("%s: BN_new", __func__);
2448 buffer_get_bignum2(m, pctx->a);
2449 x2_s_proof = buffer_get_string(m, &x2_s_proof_len);
2450
2451 jpake_key_confirm(pctx->grp, pctx->s, pctx->a,
2452 pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2,
2453 pctx->server_id, pctx->server_id_len,
2454 pctx->client_id, pctx->client_id_len,
2455 session_id2, session_id2_len,
2456 x2_s_proof, x2_s_proof_len,
2457 &pctx->k,
2458 &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len);
2459
2460 JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__));
2461
2462 bzero(x2_s_proof, x2_s_proof_len);
2463 buffer_clear(m);
2464
2465 /* pctx->k is sensitive, not sent */
2466 buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
2467
2468 debug3("%s: sending confirmation hash", __func__);
2469 mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m);
2470
2471 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1);
2472
2473 return 0;
2474}
2475
2476int
2477mm_answer_jpake_check_confirm(int sock, Buffer *m)
2478{
2479 int authenticated = 0;
2480 u_char *peer_confirm_hash;
2481 u_int peer_confirm_hash_len;
2482 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2483
2484 if (pctx == NULL)
2485 fatal("%s: pctx == NULL", __func__);
2486
2487 peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len);
2488
2489 authenticated = jpake_check_confirm(pctx->k,
2490 pctx->client_id, pctx->client_id_len,
2491 session_id2, session_id2_len,
2492 peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid;
2493
2494 JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__));
2495
2496 bzero(peer_confirm_hash, peer_confirm_hash_len);
2497 free(peer_confirm_hash);
2498
2499 buffer_clear(m);
2500 buffer_put_int(m, authenticated);
2501
2502 debug3("%s: sending result %d", __func__, authenticated);
2503 mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m);
2504
2505 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1);
2506
2507 auth_method = "jpake-01@openssh.com";
2508 return authenticated;
2509}
2510
2511#endif /* JPAKE */
2512
2513#ifdef USE_CONSOLEKIT 2288#ifdef USE_CONSOLEKIT
2514int 2289int
2515mm_answer_consolekit_register(int sock, Buffer *m) 2290mm_answer_consolekit_register(int sock, Buffer *m)
diff --git a/monitor.h b/monitor.h
index cd8342823..10ba59ea9 100644
--- a/monitor.h
+++ b/monitor.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.h,v 1.17 2012/12/02 20:34:10 djm Exp $ */ 1/* $OpenBSD: monitor.h,v 1.18 2014/01/29 06:18:35 djm Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -56,11 +56,6 @@ enum monitor_reqtype {
56 MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, 56 MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47,
57 MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, 57 MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49,
58 MONITOR_REQ_TERM = 50, 58 MONITOR_REQ_TERM = 50,
59 MONITOR_REQ_JPAKE_STEP1 = 52, MONITOR_ANS_JPAKE_STEP1 = 53,
60 MONITOR_REQ_JPAKE_GET_PWDATA = 54, MONITOR_ANS_JPAKE_GET_PWDATA = 55,
61 MONITOR_REQ_JPAKE_STEP2 = 56, MONITOR_ANS_JPAKE_STEP2 = 57,
62 MONITOR_REQ_JPAKE_KEY_CONFIRM = 58, MONITOR_ANS_JPAKE_KEY_CONFIRM = 59,
63 MONITOR_REQ_JPAKE_CHECK_CONFIRM = 60, MONITOR_ANS_JPAKE_CHECK_CONFIRM = 61,
64 59
65 MONITOR_REQ_PAM_START = 100, 60 MONITOR_REQ_PAM_START = 100,
66 MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, 61 MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 670b62dfb..a8fb07b52 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.77 2013/11/06 16:52:11 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.79 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -71,8 +71,6 @@
71#include "atomicio.h" 71#include "atomicio.h"
72#include "monitor_fdpass.h" 72#include "monitor_fdpass.h"
73#include "misc.h" 73#include "misc.h"
74#include "schnorr.h"
75#include "jpake.h"
76#include "uuencode.h" 74#include "uuencode.h"
77 75
78#include "channels.h" 76#include "channels.h"
@@ -592,7 +590,7 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
592 *blobp = xmalloc(len); 590 *blobp = xmalloc(len);
593 memcpy(*blobp, buffer_ptr(&b), len); 591 memcpy(*blobp, buffer_ptr(&b), len);
594 } 592 }
595 memset(buffer_ptr(&b), 0, len); 593 explicit_bzero(buffer_ptr(&b), len);
596 buffer_free(&b); 594 buffer_free(&b);
597 return len; 595 return len;
598} 596}
@@ -636,7 +634,7 @@ mm_send_keystate(struct monitor *monitor)
636 key = xmalloc(keylen+1); /* add 1 if keylen == 0 */ 634 key = xmalloc(keylen+1); /* add 1 if keylen == 0 */
637 keylen = packet_get_encryption_key(key); 635 keylen = packet_get_encryption_key(key);
638 buffer_put_string(&m, key, keylen); 636 buffer_put_string(&m, key, keylen);
639 memset(key, 0, keylen); 637 explicit_bzero(key, keylen);
640 free(key); 638 free(key);
641 639
642 ivlen = packet_get_keyiv_len(MODE_OUT); 640 ivlen = packet_get_keyiv_len(MODE_OUT);
@@ -1355,168 +1353,6 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
1355 1353
1356#endif /* GSSAPI */ 1354#endif /* GSSAPI */
1357 1355
1358#ifdef JPAKE
1359void
1360mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
1361 char **hash_scheme, char **salt)
1362{
1363 Buffer m;
1364
1365 debug3("%s entering", __func__);
1366
1367 buffer_init(&m);
1368 mm_request_send(pmonitor->m_recvfd,
1369 MONITOR_REQ_JPAKE_GET_PWDATA, &m);
1370
1371 debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__);
1372 mm_request_receive_expect(pmonitor->m_recvfd,
1373 MONITOR_ANS_JPAKE_GET_PWDATA, &m);
1374
1375 *hash_scheme = buffer_get_string(&m, NULL);
1376 *salt = buffer_get_string(&m, NULL);
1377
1378 buffer_free(&m);
1379}
1380
1381void
1382mm_jpake_step1(struct modp_group *grp,
1383 u_char **id, u_int *id_len,
1384 BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
1385 u_char **priv1_proof, u_int *priv1_proof_len,
1386 u_char **priv2_proof, u_int *priv2_proof_len)
1387{
1388 Buffer m;
1389
1390 debug3("%s entering", __func__);
1391
1392 buffer_init(&m);
1393 mm_request_send(pmonitor->m_recvfd,
1394 MONITOR_REQ_JPAKE_STEP1, &m);
1395
1396 debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__);
1397 mm_request_receive_expect(pmonitor->m_recvfd,
1398 MONITOR_ANS_JPAKE_STEP1, &m);
1399
1400 if ((*priv1 = BN_new()) == NULL ||
1401 (*priv2 = BN_new()) == NULL ||
1402 (*g_priv1 = BN_new()) == NULL ||
1403 (*g_priv2 = BN_new()) == NULL)
1404 fatal("%s: BN_new", __func__);
1405
1406 *id = buffer_get_string(&m, id_len);
1407 /* priv1 and priv2 are, well, private */
1408 buffer_get_bignum2(&m, *g_priv1);
1409 buffer_get_bignum2(&m, *g_priv2);
1410 *priv1_proof = buffer_get_string(&m, priv1_proof_len);
1411 *priv2_proof = buffer_get_string(&m, priv2_proof_len);
1412
1413 buffer_free(&m);
1414}
1415
1416void
1417mm_jpake_step2(struct modp_group *grp, BIGNUM *s,
1418 BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
1419 const u_char *theirid, u_int theirid_len,
1420 const u_char *myid, u_int myid_len,
1421 const u_char *theirpub1_proof, u_int theirpub1_proof_len,
1422 const u_char *theirpub2_proof, u_int theirpub2_proof_len,
1423 BIGNUM **newpub,
1424 u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len)
1425{
1426 Buffer m;
1427
1428 debug3("%s entering", __func__);
1429
1430 buffer_init(&m);
1431 /* monitor already has all bignums except theirpub1, theirpub2 */
1432 buffer_put_bignum2(&m, theirpub1);
1433 buffer_put_bignum2(&m, theirpub2);
1434 /* monitor already knows our id */
1435 buffer_put_string(&m, theirid, theirid_len);
1436 buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len);
1437 buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len);
1438
1439 mm_request_send(pmonitor->m_recvfd,
1440 MONITOR_REQ_JPAKE_STEP2, &m);
1441
1442 debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__);
1443 mm_request_receive_expect(pmonitor->m_recvfd,
1444 MONITOR_ANS_JPAKE_STEP2, &m);
1445
1446 if ((*newpub = BN_new()) == NULL)
1447 fatal("%s: BN_new", __func__);
1448
1449 buffer_get_bignum2(&m, *newpub);
1450 *newpub_exponent_proof = buffer_get_string(&m,
1451 newpub_exponent_proof_len);
1452
1453 buffer_free(&m);
1454}
1455
1456void
1457mm_jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
1458 BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
1459 BIGNUM *theirpub1, BIGNUM *theirpub2,
1460 const u_char *my_id, u_int my_id_len,
1461 const u_char *their_id, u_int their_id_len,
1462 const u_char *sess_id, u_int sess_id_len,
1463 const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len,
1464 BIGNUM **k,
1465 u_char **confirm_hash, u_int *confirm_hash_len)
1466{
1467 Buffer m;
1468
1469 debug3("%s entering", __func__);
1470
1471 buffer_init(&m);
1472 /* monitor already has all bignums except step2_val */
1473 buffer_put_bignum2(&m, step2_val);
1474 /* monitor already knows all the ids */
1475 buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len);
1476
1477 mm_request_send(pmonitor->m_recvfd,
1478 MONITOR_REQ_JPAKE_KEY_CONFIRM, &m);
1479
1480 debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__);
1481 mm_request_receive_expect(pmonitor->m_recvfd,
1482 MONITOR_ANS_JPAKE_KEY_CONFIRM, &m);
1483
1484 /* 'k' is sensitive and stays in the monitor */
1485 *confirm_hash = buffer_get_string(&m, confirm_hash_len);
1486
1487 buffer_free(&m);
1488}
1489
1490int
1491mm_jpake_check_confirm(const BIGNUM *k,
1492 const u_char *peer_id, u_int peer_id_len,
1493 const u_char *sess_id, u_int sess_id_len,
1494 const u_char *peer_confirm_hash, u_int peer_confirm_hash_len)
1495{
1496 Buffer m;
1497 int success = 0;
1498
1499 debug3("%s entering", __func__);
1500
1501 buffer_init(&m);
1502 /* k is dummy in slave, ignored */
1503 /* monitor knows all the ids */
1504 buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len);
1505 mm_request_send(pmonitor->m_recvfd,
1506 MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m);
1507
1508 debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__);
1509 mm_request_receive_expect(pmonitor->m_recvfd,
1510 MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m);
1511
1512 success = buffer_get_int(&m);
1513 buffer_free(&m);
1514
1515 debug3("%s: success = %d", __func__, success);
1516 return success;
1517}
1518#endif /* JPAKE */
1519
1520#ifdef USE_CONSOLEKIT 1356#ifdef USE_CONSOLEKIT
1521char * 1357char *
1522mm_consolekit_register(Session *s, const char *display) 1358mm_consolekit_register(Session *s, const char *display)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 360fb9f57..00e93fe9c 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.h,v 1.23 2011/06/17 21:44:31 djm Exp $ */ 1/* $OpenBSD: monitor_wrap.h,v 1.24 2014/01/29 06:18:35 djm Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -105,26 +105,6 @@ int mm_bsdauth_respond(void *, u_int, char **);
105int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); 105int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
106int mm_skey_respond(void *, u_int, char **); 106int mm_skey_respond(void *, u_int, char **);
107 107
108/* jpake */
109struct modp_group;
110void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
111void mm_jpake_step1(struct modp_group *, u_char **, u_int *,
112 BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
113 u_char **, u_int *, u_char **, u_int *);
114void mm_jpake_step2(struct modp_group *, BIGNUM *,
115 BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
116 const u_char *, u_int, const u_char *, u_int,
117 const u_char *, u_int, const u_char *, u_int,
118 BIGNUM **, u_char **, u_int *);
119void mm_jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
120 BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
121 const u_char *, u_int, const u_char *, u_int,
122 const u_char *, u_int, const u_char *, u_int,
123 BIGNUM **, u_char **, u_int *);
124int mm_jpake_check_confirm(const BIGNUM *,
125 const u_char *, u_int, const u_char *, u_int, const u_char *, u_int);
126
127
128/* zlib allocation hooks */ 108/* zlib allocation hooks */
129 109
130void *mm_zalloc(struct mm_master *, u_int, u_int); 110void *mm_zalloc(struct mm_master *, u_int, u_int);
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 276646fa6..6ecfb93d5 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.54 2013/12/07 01:37:54 djm Exp $ 1# $Id: Makefile.in,v 1.55 2014/02/04 00:37:50 djm Exp $
2 2
3sysconfdir=@sysconfdir@ 3sysconfdir=@sysconfdir@
4piddir=@piddir@ 4piddir=@piddir@
@@ -16,7 +16,7 @@ RANLIB=@RANLIB@
16INSTALL=@INSTALL@ 16INSTALL=@INSTALL@
17LDFLAGS=-L. @LDFLAGS@ 17LDFLAGS=-L. @LDFLAGS@
18 18
19OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o 19OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
20 20
21COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o 21COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
22 22
diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c
index c7ef82776..73a852480 100644
--- a/openbsd-compat/bsd-poll.c
+++ b/openbsd-compat/bsd-poll.c
@@ -1,4 +1,4 @@
1/* $Id: bsd-poll.c,v 1.5 2013/11/08 10:12:58 dtucker Exp $ */ 1/* $Id: bsd-poll.c,v 1.6 2014/02/05 23:44:13 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). 4 * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au).
@@ -109,12 +109,9 @@ poll(struct pollfd *fds, nfds_t nfds, int timeout)
109 } 109 }
110 110
111out: 111out:
112 if (readfds != NULL) 112 free(readfds);
113 free(readfds); 113 free(writefds);
114 if (writefds != NULL) 114 free(exceptfds);
115 free(writefds);
116 if (exceptfds != NULL)
117 free(exceptfds);
118 if (ret == -1) 115 if (ret == -1)
119 errno = saved_errno; 116 errno = saved_errno;
120 return ret; 117 return ret;
diff --git a/openbsd-compat/explicit_bzero.c b/openbsd-compat/explicit_bzero.c
new file mode 100644
index 000000000..b106741e5
--- /dev/null
+++ b/openbsd-compat/explicit_bzero.c
@@ -0,0 +1,20 @@
1/* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */
2/* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */
3/*
4 * Public domain.
5 * Written by Ted Unangst
6 */
7
8#include "includes.h"
9
10#ifndef HAVE_EXPLICIT_BZERO
11
12/*
13 * explicit_bzero - don't let the compiler optimize away bzero
14 */
15void
16explicit_bzero(void *p, size_t n)
17{
18 bzero(p, n);
19}
20#endif
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index f34619e4a..bc9888e31 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
1/* $Id: openbsd-compat.h,v 1.60 2013/12/07 00:51:54 djm Exp $ */ 1/* $Id: openbsd-compat.h,v 1.61 2014/02/04 00:18:23 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999-2003 Damien Miller. All rights reserved. 4 * Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@@ -246,6 +246,10 @@ int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t,
246 u_int8_t *, size_t, unsigned int); 246 u_int8_t *, size_t, unsigned int);
247#endif 247#endif
248 248
249#ifndef HAVE_EXPLICIT_BZERO
250void explicit_bzero(void *p, size_t n);
251#endif
252
249void *xmmap(size_t size); 253void *xmmap(size_t size);
250char *xcrypt(const char *password, const char *salt); 254char *xcrypt(const char *password, const char *salt);
251char *shadow_pw(struct passwd *pw); 255char *shadow_pw(struct passwd *pw);
diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c
index 60eac4b17..885c121f2 100644
--- a/openbsd-compat/openssl-compat.c
+++ b/openbsd-compat/openssl-compat.c
@@ -1,4 +1,4 @@
1/* $Id: openssl-compat.c,v 1.16 2014/01/17 07:00:41 dtucker Exp $ */ 1/* $Id: openssl-compat.c,v 1.17 2014/02/13 05:38:33 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> 4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@@ -96,6 +96,14 @@ ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt)
96} 96}
97#endif 97#endif
98 98
99#ifndef HAVE_EVP_MD_CTX_COPY_EX
100int
101EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
102{
103 return EVP_MD_CTX_copy(out, in);
104}
105#endif
106
99#ifndef HAVE_BN_IS_PRIME_EX 107#ifndef HAVE_BN_IS_PRIME_EX
100int 108int
101BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb) 109BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb)
diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h
index 021ea98f5..276b9706d 100644
--- a/openbsd-compat/openssl-compat.h
+++ b/openbsd-compat/openssl-compat.h
@@ -1,4 +1,4 @@
1/* $Id: openssl-compat.h,v 1.25 2014/01/17 06:32:31 dtucker Exp $ */ 1/* $Id: openssl-compat.h,v 1.26 2014/02/13 05:38:33 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> 4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@@ -156,6 +156,10 @@ int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, void *);
156int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *); 156int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *);
157# endif 157# endif
158 158
159# ifndef EVP_MD_CTX_COPY_EX
160int EVP_MD_CTX_copy_ex(EVP_MD_CTX *, const EVP_MD_CTX *);
161# endif
162
159int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *, 163int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *,
160 unsigned char *, int); 164 unsigned char *, int);
161int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int); 165int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int);
diff --git a/packet.c b/packet.c
index 6cf7edbb8..54c0558f9 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.191 2013/12/06 13:34:54 markus Exp $ */ 1/* $OpenBSD: packet.c,v 1.192 2014/02/02 03:44:31 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
@@ -764,9 +764,9 @@ set_newkeys(int mode)
764 mac = &active_state->newkeys[mode]->mac; 764 mac = &active_state->newkeys[mode]->mac;
765 comp = &active_state->newkeys[mode]->comp; 765 comp = &active_state->newkeys[mode]->comp;
766 mac_clear(mac); 766 mac_clear(mac);
767 memset(enc->iv, 0, enc->iv_len); 767 explicit_bzero(enc->iv, enc->iv_len);
768 memset(enc->key, 0, enc->key_len); 768 explicit_bzero(enc->key, enc->key_len);
769 memset(mac->key, 0, mac->key_len); 769 explicit_bzero(mac->key, mac->key_len);
770 free(enc->name); 770 free(enc->name);
771 free(enc->iv); 771 free(enc->iv);
772 free(enc->key); 772 free(enc->key);
@@ -787,9 +787,9 @@ set_newkeys(int mode)
787 cipher_init(cc, enc->cipher, enc->key, enc->key_len, 787 cipher_init(cc, enc->cipher, enc->key, enc->key_len,
788 enc->iv, enc->iv_len, crypt_type); 788 enc->iv, enc->iv_len, crypt_type);
789 /* Deleting the keys does not gain extra security */ 789 /* Deleting the keys does not gain extra security */
790 /* memset(enc->iv, 0, enc->block_size); 790 /* explicit_bzero(enc->iv, enc->block_size);
791 memset(enc->key, 0, enc->key_len); 791 explicit_bzero(enc->key, enc->key_len);
792 memset(mac->key, 0, mac->key_len); */ 792 explicit_bzero(mac->key, mac->key_len); */
793 if ((comp->type == COMP_ZLIB || 793 if ((comp->type == COMP_ZLIB ||
794 (comp->type == COMP_DELAYED && 794 (comp->type == COMP_DELAYED &&
795 active_state->after_authentication)) && comp->enabled == 0) { 795 active_state->after_authentication)) && comp->enabled == 0) {
@@ -928,7 +928,7 @@ packet_send2_wrapped(void)
928 } 928 }
929 } else { 929 } else {
930 /* clear padding */ 930 /* clear padding */
931 memset(cp, 0, padlen); 931 explicit_bzero(cp, padlen);
932 } 932 }
933 /* sizeof (packet_len + pad_len + payload + padding) */ 933 /* sizeof (packet_len + pad_len + payload + padding) */
934 len = buffer_len(&active_state->outgoing_packet); 934 len = buffer_len(&active_state->outgoing_packet);
diff --git a/readconf.c b/readconf.c
index 6ac8beae0..5429fc2ad 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.215 2013/12/06 13:39:49 markus Exp $ */ 1/* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 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
@@ -22,6 +22,7 @@
22#include <netinet/in.h> 22#include <netinet/in.h>
23#include <netinet/in_systm.h> 23#include <netinet/in_systm.h>
24#include <netinet/ip.h> 24#include <netinet/ip.h>
25#include <arpa/inet.h>
25 26
26#include <ctype.h> 27#include <ctype.h>
27#include <errno.h> 28#include <errno.h>
@@ -148,7 +149,7 @@ typedef enum {
148 oSendEnv, oControlPath, oControlMaster, oControlPersist, 149 oSendEnv, oControlPath, oControlMaster, oControlPersist,
149 oHashKnownHosts, 150 oHashKnownHosts,
150 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 151 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
151 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 152 oVisualHostKey, oUseRoaming,
152 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 153 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
153 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 154 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
154 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 155 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
@@ -266,12 +267,6 @@ static struct {
266 { "permitlocalcommand", oPermitLocalCommand }, 267 { "permitlocalcommand", oPermitLocalCommand },
267 { "visualhostkey", oVisualHostKey }, 268 { "visualhostkey", oVisualHostKey },
268 { "useroaming", oUseRoaming }, 269 { "useroaming", oUseRoaming },
269#ifdef JPAKE
270 { "zeroknowledgepasswordauthentication",
271 oZeroKnowledgePasswordAuthentication },
272#else
273 { "zeroknowledgepasswordauthentication", oUnsupported },
274#endif
275 { "kexalgorithms", oKexAlgorithms }, 270 { "kexalgorithms", oKexAlgorithms },
276 { "ipqos", oIPQoS }, 271 { "ipqos", oIPQoS },
277 { "requesttty", oRequestTTY }, 272 { "requesttty", oRequestTTY },
@@ -559,16 +554,27 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
559 "r", ruser, 554 "r", ruser,
560 "u", pw->pw_name, 555 "u", pw->pw_name,
561 (char *)NULL); 556 (char *)NULL);
562 r = execute_in_shell(cmd); 557 if (result != 1) {
563 if (r == -1) { 558 /* skip execution if prior predicate failed */
564 fatal("%.200s line %d: match exec '%.100s' " 559 debug("%.200s line %d: skipped exec \"%.100s\"",
565 "error", filename, linenum, cmd);
566 } else if (r == 0) {
567 debug("%.200s line %d: matched "
568 "'exec \"%.100s\"' ",
569 filename, linenum, cmd); 560 filename, linenum, cmd);
570 } else 561 } else {
571 result = 0; 562 r = execute_in_shell(cmd);
563 if (r == -1) {
564 fatal("%.200s line %d: match exec "
565 "'%.100s' error", filename,
566 linenum, cmd);
567 } else if (r == 0) {
568 debug("%.200s line %d: matched "
569 "'exec \"%.100s\"'", filename,
570 linenum, cmd);
571 } else {
572 debug("%.200s line %d: no match "
573 "'exec \"%.100s\"'", filename,
574 linenum, cmd);
575 result = 0;
576 }
577 }
572 free(cmd); 578 free(cmd);
573 } else { 579 } else {
574 error("Unsupported Match attribute %s", attrib); 580 error("Unsupported Match attribute %s", attrib);
@@ -820,10 +826,6 @@ parse_time:
820 intptr = &options->password_authentication; 826 intptr = &options->password_authentication;
821 goto parse_flag; 827 goto parse_flag;
822 828
823 case oZeroKnowledgePasswordAuthentication:
824 intptr = &options->zero_knowledge_password_authentication;
825 goto parse_flag;
826
827 case oKbdInteractiveAuthentication: 829 case oKbdInteractiveAuthentication:
828 intptr = &options->kbd_interactive_authentication; 830 intptr = &options->kbd_interactive_authentication;
829 goto parse_flag; 831 goto parse_flag;
@@ -1503,6 +1505,13 @@ read_config_file(const char *filename, struct passwd *pw, const char *host,
1503 return 1; 1505 return 1;
1504} 1506}
1505 1507
1508/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1509int
1510option_clear_or_none(const char *o)
1511{
1512 return o == NULL || strcasecmp(o, "none") == 0;
1513}
1514
1506/* 1515/*
1507 * Initializes options to special values that indicate that they have not yet 1516 * Initializes options to special values that indicate that they have not yet
1508 * been set. Read_config_file will only set options with this value. Options 1517 * been set. Read_config_file will only set options with this value. Options
@@ -1592,7 +1601,6 @@ initialize_options(Options * options)
1592 options->permit_local_command = -1; 1601 options->permit_local_command = -1;
1593 options->use_roaming = -1; 1602 options->use_roaming = -1;
1594 options->visual_host_key = -1; 1603 options->visual_host_key = -1;
1595 options->zero_knowledge_password_authentication = -1;
1596 options->ip_qos_interactive = -1; 1604 options->ip_qos_interactive = -1;
1597 options->ip_qos_bulk = -1; 1605 options->ip_qos_bulk = -1;
1598 options->request_tty = -1; 1606 options->request_tty = -1;
@@ -1606,10 +1614,24 @@ initialize_options(Options * options)
1606} 1614}
1607 1615
1608/* 1616/*
1617 * A petite version of fill_default_options() that just fills the options
1618 * needed for hostname canonicalization to proceed.
1619 */
1620void
1621fill_default_options_for_canonicalization(Options *options)
1622{
1623 if (options->canonicalize_max_dots == -1)
1624 options->canonicalize_max_dots = 1;
1625 if (options->canonicalize_fallback_local == -1)
1626 options->canonicalize_fallback_local = 1;
1627 if (options->canonicalize_hostname == -1)
1628 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1629}
1630
1631/*
1609 * Called after processing other sources of option data, this fills those 1632 * Called after processing other sources of option data, this fills those
1610 * options for which no value has been specified with their default values. 1633 * options for which no value has been specified with their default values.
1611 */ 1634 */
1612
1613void 1635void
1614fill_default_options(Options * options) 1636fill_default_options(Options * options)
1615{ 1637{
@@ -1759,8 +1781,6 @@ fill_default_options(Options * options)
1759 options->use_roaming = 1; 1781 options->use_roaming = 1;
1760 if (options->visual_host_key == -1) 1782 if (options->visual_host_key == -1)
1761 options->visual_host_key = 0; 1783 options->visual_host_key = 0;
1762 if (options->zero_knowledge_password_authentication == -1)
1763 options->zero_knowledge_password_authentication = 0;
1764 if (options->ip_qos_interactive == -1) 1784 if (options->ip_qos_interactive == -1)
1765 options->ip_qos_interactive = IPTOS_LOWDELAY; 1785 options->ip_qos_interactive = IPTOS_LOWDELAY;
1766 if (options->ip_qos_bulk == -1) 1786 if (options->ip_qos_bulk == -1)
@@ -1777,7 +1797,7 @@ fill_default_options(Options * options)
1777 options->canonicalize_hostname = SSH_CANONICALISE_NO; 1797 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1778#define CLEAR_ON_NONE(v) \ 1798#define CLEAR_ON_NONE(v) \
1779 do { \ 1799 do { \
1780 if (v != NULL && strcasecmp(v, "none") == 0) { \ 1800 if (option_clear_or_none(v)) { \
1781 free(v); \ 1801 free(v); \
1782 v = NULL; \ 1802 v = NULL; \
1783 } \ 1803 } \
diff --git a/readconf.h b/readconf.h
index 826c6767b..5cc97f0da 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.99 2013/10/16 22:49:38 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.101 2014/02/23 20:11:36 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -64,7 +64,6 @@ typedef struct {
64 * authentication. */ 64 * authentication. */
65 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ 65 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
66 char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ 66 char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
67 int zero_knowledge_password_authentication; /* Try jpake */
68 int batch_mode; /* Batch mode: do not ask for passwords. */ 67 int batch_mode; /* Batch mode: do not ask for passwords. */
69 int check_host_ip; /* Also keep track of keys for IP address */ 68 int check_host_ip; /* Also keep track of keys for IP address */
70 int strict_host_key_checking; /* Strict host key checking. */ 69 int strict_host_key_checking; /* Strict host key checking. */
@@ -182,12 +181,14 @@ typedef struct {
182 181
183void initialize_options(Options *); 182void initialize_options(Options *);
184void fill_default_options(Options *); 183void fill_default_options(Options *);
184void fill_default_options_for_canonicalization(Options *);
185int process_config_line(Options *, struct passwd *, const char *, char *, 185int process_config_line(Options *, struct passwd *, const char *, char *,
186 const char *, int, int *, int); 186 const char *, int, int *, int);
187int read_config_file(const char *, struct passwd *, const char *, 187int read_config_file(const char *, struct passwd *, const char *,
188 Options *, int); 188 Options *, int);
189int parse_forward(Forward *, const char *, int, int); 189int parse_forward(Forward *, const char *, int, int);
190int default_ssh_port(void); 190int default_ssh_port(void);
191int option_clear_or_none(const char *);
191 192
192void add_local_forward(Options *, const Forward *); 193void add_local_forward(Options *, const Forward *);
193void add_remote_forward(Options *, const Forward *); 194void add_remote_forward(Options *, const Forward *);
diff --git a/readpass.c b/readpass.c
index e37d31158..869d86425 100644
--- a/readpass.c
+++ b/readpass.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readpass.c,v 1.49 2013/05/17 00:13:14 djm Exp $ */ 1/* $OpenBSD: readpass.c,v 1.50 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -99,13 +99,13 @@ ssh_askpass(char *askpass, const char *msg)
99 break; 99 break;
100 signal(SIGCHLD, osigchld); 100 signal(SIGCHLD, osigchld);
101 if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { 101 if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
102 memset(buf, 0, sizeof(buf)); 102 explicit_bzero(buf, sizeof(buf));
103 return NULL; 103 return NULL;
104 } 104 }
105 105
106 buf[strcspn(buf, "\r\n")] = '\0'; 106 buf[strcspn(buf, "\r\n")] = '\0';
107 pass = xstrdup(buf); 107 pass = xstrdup(buf);
108 memset(buf, 0, sizeof(buf)); 108 explicit_bzero(buf, sizeof(buf));
109 return pass; 109 return pass;
110} 110}
111 111
@@ -162,7 +162,7 @@ read_passphrase(const char *prompt, int flags)
162 } 162 }
163 163
164 ret = xstrdup(buf); 164 ret = xstrdup(buf);
165 memset(buf, 'x', sizeof buf); 165 explicit_bzero(buf, sizeof(buf));
166 return ret; 166 return ret;
167} 167}
168 168
diff --git a/regress/Makefile b/regress/Makefile
index 0c66b1774..6e3b8d634 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.67 2013/12/06 13:52:46 markus Exp $ 1# $OpenBSD: Makefile,v 1.68 2014/01/25 04:35:32 dtucker Exp $
2 2
3REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec 3REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec
4tests: $(REGRESS_TARGETS) 4tests: $(REGRESS_TARGETS)
@@ -65,6 +65,7 @@ LTESTS= connect \
65 forward-control \ 65 forward-control \
66 integrity \ 66 integrity \
67 krl 67 krl
68# dhgex \
68 69
69INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers 70INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
70#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp 71#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
diff --git a/regress/agent-ptrace.sh b/regress/agent-ptrace.sh
index ae150641f..1912ca8f9 100644
--- a/regress/agent-ptrace.sh
+++ b/regress/agent-ptrace.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: agent-ptrace.sh,v 1.1 2002/12/09 15:38:30 markus Exp $ 1# $OpenBSD: agent-ptrace.sh,v 1.2 2014/02/27 21:21:25 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="disallow agent ptrace attach" 4tid="disallow agent ptrace attach"
diff --git a/regress/agent.sh b/regress/agent.sh
index cf1a45fe0..caad3c88e 100644
--- a/regress/agent.sh
+++ b/regress/agent.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: agent.sh,v 1.9 2013/12/06 13:52:46 markus Exp $ 1# $OpenBSD: agent.sh,v 1.10 2014/02/27 21:21:25 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="simple agent test" 4tid="simple agent test"
diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh
index a1318cd53..1d9e0ed8e 100644
--- a/regress/cert-hostkey.sh
+++ b/regress/cert-hostkey.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cert-hostkey.sh,v 1.8 2013/12/06 13:52:46 markus Exp $ 1# $OpenBSD: cert-hostkey.sh,v 1.9 2014/01/26 10:22:10 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="certified host keys" 4tid="certified host keys"
diff --git a/regress/dhgex.sh b/regress/dhgex.sh
new file mode 100644
index 000000000..4c1a3d83c
--- /dev/null
+++ b/regress/dhgex.sh
@@ -0,0 +1,54 @@
1# $OpenBSD: dhgex.sh,v 1.1 2014/01/25 04:35:32 dtucker Exp $
2# Placed in the Public Domain.
3
4tid="dhgex"
5
6LOG=${TEST_SSH_LOGFILE}
7rm -f ${LOG}
8
9kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange`
10
11ssh_test_dhgex()
12{
13 bits="$1"; shift
14 cipher="$1"; shift
15 kex="$1"; shift
16
17 rm -f ${LOG}
18 opts="-oKexAlgorithms=$kex -oCiphers=$cipher"
19 groupsz="1024<$bits<8192"
20 verbose "$tid bits $bits $kex $cipher"
21 ${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true
22 if [ $? -ne 0 ]; then
23 fail "ssh failed ($@)"
24 fi
25 # check what we request
26 grep "SSH2_MSG_KEX_DH_GEX_REQUEST($groupsz) sent" ${LOG} >/dev/null
27 if [ $? != 0 ]; then
28 got=`egrep "SSH2_MSG_KEX_DH_GEX_REQUEST(.*) sent" ${LOG}`
29 fail "$tid unexpected GEX sizes, expected $groupsz, got $got"
30 fi
31 # check what we got (depends on contents of system moduli file)
32 gotbits="`awk '/bits set:/{print $4}' ${LOG} | head -1 | cut -f2 -d/`"
33 if [ "$gotbits" -lt "$bits" ]; then
34 fatal "$tid expected $bits bit group, got $gotbits"
35 fi
36}
37
38check()
39{
40 bits="$1"; shift
41
42 for c in $@; do
43 for k in $kexs; do
44 ssh_test_dhgex $bits $c $k
45 done
46 done
47}
48
49#check 2048 3des-cbc
50check 3072 `${SSH} -Q cipher | grep 128`
51check 3072 arcfour blowfish-cbc
52check 7680 `${SSH} -Q cipher | grep 192`
53check 8192 `${SSH} -Q cipher | grep 256`
54check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com
diff --git a/regress/host-expand.sh b/regress/host-expand.sh
index a0188363d..6cc0e6055 100644
--- a/regress/host-expand.sh
+++ b/regress/host-expand.sh
@@ -1,3 +1,4 @@
1# $OpenBSD: host-expand.sh,v 1.3 2014/02/27 23:17:41 djm Exp $
1# Placed in the Public Domain. 2# Placed in the Public Domain.
2 3
3tid="expand %h and %n" 4tid="expand %h and %n"
diff --git a/regress/login-timeout.sh b/regress/login-timeout.sh
index d73923b9c..d9b48f391 100644
--- a/regress/login-timeout.sh
+++ b/regress/login-timeout.sh
@@ -1,9 +1,11 @@
1# $OpenBSD: login-timeout.sh,v 1.5 2013/05/17 10:23:52 dtucker Exp $ 1# $OpenBSD: login-timeout.sh,v 1.6 2014/02/27 20:04:16 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="connect after login grace timeout" 4tid="connect after login grace timeout"
5 5
6trace "test login grace with privsep" 6trace "test login grace with privsep"
7cp $OBJ/sshd_config $OBJ/sshd_config.orig
8grep -vi LoginGraceTime $OBJ/sshd_config.orig > $OBJ/sshd_config
7echo "LoginGraceTime 10s" >> $OBJ/sshd_config 9echo "LoginGraceTime 10s" >> $OBJ/sshd_config
8echo "MaxStartups 1" >> $OBJ/sshd_config 10echo "MaxStartups 1" >> $OBJ/sshd_config
9start_sshd 11start_sshd
diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh
index c63bc2bc1..59f1ff63e 100644
--- a/regress/scp-ssh-wrapper.sh
+++ b/regress/scp-ssh-wrapper.sh
@@ -1,5 +1,5 @@
1#!/bin/sh 1#!/bin/sh
2# $OpenBSD: scp-ssh-wrapper.sh,v 1.2 2005/12/14 04:36:39 dtucker Exp $ 2# $OpenBSD: scp-ssh-wrapper.sh,v 1.3 2014/01/26 10:49:17 djm Exp $
3# Placed in the Public Domain. 3# Placed in the Public Domain.
4 4
5printname () { 5printname () {
diff --git a/regress/scp.sh b/regress/scp.sh
index c2da2a862..57cc77066 100644
--- a/regress/scp.sh
+++ b/regress/scp.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: scp.sh,v 1.9 2013/05/17 10:35:43 dtucker Exp $ 1# $OpenBSD: scp.sh,v 1.10 2014/01/26 10:49:17 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="scp" 4tid="scp"
diff --git a/regress/setuid-allowed.c b/regress/setuid-allowed.c
index 37b7dc8ad..676d2661c 100644
--- a/regress/setuid-allowed.c
+++ b/regress/setuid-allowed.c
@@ -23,6 +23,7 @@
23# include <sys/statvfs.h> 23# include <sys/statvfs.h>
24#endif 24#endif
25#include <stdio.h> 25#include <stdio.h>
26#include <string.h>
26#include <errno.h> 27#include <errno.h>
27 28
28void 29void
diff --git a/regress/sftp-chroot.sh b/regress/sftp-chroot.sh
index 03b9bc6d7..23f7456e8 100644
--- a/regress/sftp-chroot.sh
+++ b/regress/sftp-chroot.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: sftp-chroot.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $ 1# $OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="sftp in chroot" 4tid="sftp in chroot"
@@ -18,7 +18,8 @@ $SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \
18start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /" 18start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /"
19 19
20verbose "test $tid: get" 20verbose "test $tid: get"
21${SFTP} -qS "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY || \ 21${SFTP} -S "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY \
22 >>$TEST_REGRESS_LOGFILE 2>&1 || \
22 fatal "Fetch ${FILENAME} failed" 23 fatal "Fetch ${FILENAME} failed"
23cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ" 24cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ"
24 25
diff --git a/rsa.c b/rsa.c
index a9ee6b0ed..d0b5bbf5e 100644
--- a/rsa.c
+++ b/rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: rsa.c,v 1.30 2013/05/17 00:13:14 djm Exp $ */ 1/* $OpenBSD: rsa.c,v 1.31 2014/02/02 03:44:31 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
@@ -94,8 +94,8 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
94 if (BN_bin2bn(outbuf, len, out) == NULL) 94 if (BN_bin2bn(outbuf, len, out) == NULL)
95 fatal("rsa_public_encrypt: BN_bin2bn failed"); 95 fatal("rsa_public_encrypt: BN_bin2bn failed");
96 96
97 memset(outbuf, 0, olen); 97 explicit_bzero(outbuf, olen);
98 memset(inbuf, 0, ilen); 98 explicit_bzero(inbuf, ilen);
99 free(outbuf); 99 free(outbuf);
100 free(inbuf); 100 free(inbuf);
101} 101}
@@ -120,8 +120,8 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
120 if (BN_bin2bn(outbuf, len, out) == NULL) 120 if (BN_bin2bn(outbuf, len, out) == NULL)
121 fatal("rsa_private_decrypt: BN_bin2bn failed"); 121 fatal("rsa_private_decrypt: BN_bin2bn failed");
122 } 122 }
123 memset(outbuf, 0, olen); 123 explicit_bzero(outbuf, olen);
124 memset(inbuf, 0, ilen); 124 explicit_bzero(inbuf, ilen);
125 free(outbuf); 125 free(outbuf);
126 free(inbuf); 126 free(inbuf);
127 return len; 127 return len;
diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c
index ee2a7e79e..655f0d217 100644
--- a/sandbox-capsicum.c
+++ b/sandbox-capsicum.c
@@ -94,10 +94,12 @@ ssh_sandbox_child(struct ssh_sandbox *box)
94 fatal("can't limit stderr: %m"); 94 fatal("can't limit stderr: %m");
95 95
96 cap_rights_init(&rights, CAP_READ, CAP_WRITE); 96 cap_rights_init(&rights, CAP_READ, CAP_WRITE);
97 if (cap_rights_limit(box->monitor->m_recvfd, &rights) == -1) 97 if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 &&
98 errno != ENOSYS)
98 fatal("%s: failed to limit the network socket", __func__); 99 fatal("%s: failed to limit the network socket", __func__);
99 cap_rights_init(&rights, CAP_WRITE); 100 cap_rights_init(&rights, CAP_WRITE);
100 if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) == -1) 101 if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 &&
102 errno != ENOSYS)
101 fatal("%s: failed to limit the logging socket", __func__); 103 fatal("%s: failed to limit the logging socket", __func__);
102 if (cap_enter() < 0 && errno != ENOSYS) 104 if (cap_enter() < 0 && errno != ENOSYS)
103 fatal("%s: failed to enter capability mode", __func__); 105 fatal("%s: failed to enter capability mode", __func__);
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index 2f73067e1..c0c17c2fc 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -98,6 +98,9 @@ static const struct sock_filter preauth_insns[] = {
98 SC_ALLOW(read), 98 SC_ALLOW(read),
99 SC_ALLOW(write), 99 SC_ALLOW(write),
100 SC_ALLOW(close), 100 SC_ALLOW(close),
101#ifdef __NR_shutdown /* not defined on archs that go via socketcall(2) */
102 SC_ALLOW(shutdown),
103#endif
101 SC_ALLOW(brk), 104 SC_ALLOW(brk),
102 SC_ALLOW(poll), 105 SC_ALLOW(poll),
103#ifdef __NR__newselect 106#ifdef __NR__newselect
diff --git a/sandbox-systrace.c b/sandbox-systrace.c
index 53fbd47cb..6706c9a80 100644
--- a/sandbox-systrace.c
+++ b/sandbox-systrace.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sandbox-systrace.c,v 1.7 2013/06/01 13:15:52 dtucker Exp $ */ 1/* $OpenBSD: sandbox-systrace.c,v 1.9 2014/01/31 16:39:19 tedu Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -66,6 +66,7 @@ static const struct sandbox_policy preauth_policy[] = {
66 { SYS_munmap, SYSTR_POLICY_PERMIT }, 66 { SYS_munmap, SYSTR_POLICY_PERMIT },
67 { SYS_read, SYSTR_POLICY_PERMIT }, 67 { SYS_read, SYSTR_POLICY_PERMIT },
68 { SYS_select, SYSTR_POLICY_PERMIT }, 68 { SYS_select, SYSTR_POLICY_PERMIT },
69 { SYS_shutdown, SYSTR_POLICY_PERMIT },
69 { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, 70 { SYS_sigprocmask, SYSTR_POLICY_PERMIT },
70 { SYS_write, SYSTR_POLICY_PERMIT }, 71 { SYS_write, SYSTR_POLICY_PERMIT },
71 { -1, -1 } 72 { -1, -1 }
@@ -141,7 +142,7 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
141 box->systrace_fd, child_pid, strerror(errno)); 142 box->systrace_fd, child_pid, strerror(errno));
142 143
143 /* Allocate and assign policy */ 144 /* Allocate and assign policy */
144 bzero(&policy, sizeof(policy)); 145 memset(&policy, 0, sizeof(policy));
145 policy.strp_op = SYSTR_POLICY_NEW; 146 policy.strp_op = SYSTR_POLICY_NEW;
146 policy.strp_maxents = SYS_MAXSYSCALL; 147 policy.strp_maxents = SYS_MAXSYSCALL;
147 if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) 148 if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
diff --git a/schnorr.c b/schnorr.c
deleted file mode 100644
index aa3a57770..000000000
--- a/schnorr.c
+++ /dev/null
@@ -1,668 +0,0 @@
1/* $OpenBSD: schnorr.c,v 1.9 2014/01/09 23:20:00 djm Exp $ */
2/*
3 * Copyright (c) 2008 Damien Miller. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/*
19 * Implementation of Schnorr signatures / zero-knowledge proofs, based on
20 * description in:
21 *
22 * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling",
23 * 16th Workshop on Security Protocols, Cambridge, April 2008
24 *
25 * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
26 */
27
28#include "includes.h"
29
30#include <sys/types.h>
31
32#include <string.h>
33#include <stdarg.h>
34#include <stdio.h>
35
36#include <openssl/evp.h>
37#include <openssl/bn.h>
38
39#include "xmalloc.h"
40#include "buffer.h"
41#include "log.h"
42
43#include "schnorr.h"
44#include "digest.h"
45
46#include "openbsd-compat/openssl-compat.h"
47
48/* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */
49/* #define SCHNORR_MAIN */ /* Include main() selftest */
50
51#ifndef SCHNORR_DEBUG
52# define SCHNORR_DEBUG_BN(a)
53# define SCHNORR_DEBUG_BUF(a)
54#else
55# define SCHNORR_DEBUG_BN(a) debug3_bn a
56# define SCHNORR_DEBUG_BUF(a) debug3_buf a
57#endif /* SCHNORR_DEBUG */
58
59/*
60 * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
61 * using the hash function defined by "hash_alg". Returns signature as
62 * bignum or NULL on error.
63 */
64static BIGNUM *
65schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
66 int hash_alg, const BIGNUM *g_v, const BIGNUM *g_x,
67 const u_char *id, u_int idlen)
68{
69 u_char *digest;
70 u_int digest_len;
71 BIGNUM *h;
72 Buffer b;
73 int success = -1;
74
75 if ((h = BN_new()) == NULL) {
76 error("%s: BN_new", __func__);
77 return NULL;
78 }
79
80 buffer_init(&b);
81
82 /* h = H(g || p || q || g^v || g^x || id) */
83 buffer_put_bignum2(&b, g);
84 buffer_put_bignum2(&b, p);
85 buffer_put_bignum2(&b, q);
86 buffer_put_bignum2(&b, g_v);
87 buffer_put_bignum2(&b, g_x);
88 buffer_put_string(&b, id, idlen);
89
90 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
91 "%s: hashblob", __func__));
92 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), hash_alg,
93 &digest, &digest_len) != 0) {
94 error("%s: hash_buffer", __func__);
95 goto out;
96 }
97 if (BN_bin2bn(digest, (int)digest_len, h) == NULL) {
98 error("%s: BN_bin2bn", __func__);
99 goto out;
100 }
101 success = 0;
102 SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
103 out:
104 buffer_free(&b);
105 bzero(digest, digest_len);
106 free(digest);
107 digest_len = 0;
108 if (success == 0)
109 return h;
110 BN_clear_free(h);
111 return NULL;
112}
113
114/*
115 * Generate Schnorr signature to prove knowledge of private value 'x' used
116 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
117 * using the hash function "hash_alg".
118 * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
119 * replay salt.
120 *
121 * On success, 0 is returned. The signature values are returned as *e_p
122 * (g^v mod p) and *r_p (v - xh mod q). The caller must free these values.
123 * On failure, -1 is returned.
124 */
125int
126schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
127 int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
128 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
129{
130 int success = -1;
131 BIGNUM *h, *tmp, *v, *g_v, *r;
132 BN_CTX *bn_ctx;
133
134 SCHNORR_DEBUG_BN((x, "%s: x = ", __func__));
135 SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
136
137 /* Avoid degenerate cases: g^0 yields a spoofable signature */
138 if (BN_cmp(g_x, BN_value_one()) <= 0) {
139 error("%s: g_x < 1", __func__);
140 return -1;
141 }
142 if (BN_cmp(g_x, grp_p) >= 0) {
143 error("%s: g_x > g", __func__);
144 return -1;
145 }
146
147 h = g_v = r = tmp = v = NULL;
148 if ((bn_ctx = BN_CTX_new()) == NULL) {
149 error("%s: BN_CTX_new", __func__);
150 goto out;
151 }
152 if ((g_v = BN_new()) == NULL ||
153 (r = BN_new()) == NULL ||
154 (tmp = BN_new()) == NULL) {
155 error("%s: BN_new", __func__);
156 goto out;
157 }
158
159 /*
160 * v must be a random element of Zq, so 1 <= v < q
161 * we also exclude v = 1, since g^1 looks dangerous
162 */
163 if ((v = bn_rand_range_gt_one(grp_p)) == NULL) {
164 error("%s: bn_rand_range2", __func__);
165 goto out;
166 }
167 SCHNORR_DEBUG_BN((v, "%s: v = ", __func__));
168
169 /* g_v = g^v mod p */
170 if (BN_mod_exp(g_v, grp_g, v, grp_p, bn_ctx) == -1) {
171 error("%s: BN_mod_exp (g^v mod p)", __func__);
172 goto out;
173 }
174 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
175
176 /* h = H(g || g^v || g^x || id) */
177 if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, g_v, g_x,
178 id, idlen)) == NULL) {
179 error("%s: schnorr_hash failed", __func__);
180 goto out;
181 }
182
183 /* r = v - xh mod q */
184 if (BN_mod_mul(tmp, x, h, grp_q, bn_ctx) == -1) {
185 error("%s: BN_mod_mul (tmp = xv mod q)", __func__);
186 goto out;
187 }
188 if (BN_mod_sub(r, v, tmp, grp_q, bn_ctx) == -1) {
189 error("%s: BN_mod_mul (r = v - tmp)", __func__);
190 goto out;
191 }
192 SCHNORR_DEBUG_BN((g_v, "%s: e = ", __func__));
193 SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
194
195 *e_p = g_v;
196 *r_p = r;
197
198 success = 0;
199 out:
200 BN_CTX_free(bn_ctx);
201 if (h != NULL)
202 BN_clear_free(h);
203 if (v != NULL)
204 BN_clear_free(v);
205 BN_clear_free(tmp);
206
207 return success;
208}
209
210/*
211 * Generate Schnorr signature to prove knowledge of private value 'x' used
212 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
213 * using a SHA256 hash.
214 * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
215 * replay salt.
216 * On success, 0 is returned and *siglen bytes of signature are returned in
217 * *sig (caller to free). Returns -1 on failure.
218 */
219int
220schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
221 const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
222 u_char **sig, u_int *siglen)
223{
224 Buffer b;
225 BIGNUM *r, *e;
226
227 if (schnorr_sign(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
228 x, g_x, id, idlen, &r, &e) != 0)
229 return -1;
230
231 /* Signature is (e, r) */
232 buffer_init(&b);
233 /* XXX sigtype-hash as string? */
234 buffer_put_bignum2(&b, e);
235 buffer_put_bignum2(&b, r);
236 *siglen = buffer_len(&b);
237 *sig = xmalloc(*siglen);
238 memcpy(*sig, buffer_ptr(&b), *siglen);
239 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
240 "%s: sigblob", __func__));
241 buffer_free(&b);
242
243 BN_clear_free(r);
244 BN_clear_free(e);
245
246 return 0;
247}
248
249/*
250 * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
251 * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
252 * 'grp_g' using hash "hash_alg".
253 * Signature hash will be salted with 'idlen' bytes from 'id'.
254 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
255 */
256int
257schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
258 int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
259 const BIGNUM *r, const BIGNUM *e)
260{
261 int success = -1;
262 BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL;
263 BIGNUM *expected = NULL;
264 BN_CTX *bn_ctx;
265
266 SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
267
268 /* Avoid degenerate cases: g^0 yields a spoofable signature */
269 if (BN_cmp(g_x, BN_value_one()) <= 0) {
270 error("%s: g_x <= 1", __func__);
271 return -1;
272 }
273 if (BN_cmp(g_x, grp_p) >= 0) {
274 error("%s: g_x >= p", __func__);
275 return -1;
276 }
277
278 h = g_xh = g_r = expected = NULL;
279 if ((bn_ctx = BN_CTX_new()) == NULL) {
280 error("%s: BN_CTX_new", __func__);
281 goto out;
282 }
283 if ((g_xh = BN_new()) == NULL ||
284 (g_r = BN_new()) == NULL ||
285 (gx_q = BN_new()) == NULL ||
286 (expected = BN_new()) == NULL) {
287 error("%s: BN_new", __func__);
288 goto out;
289 }
290
291 SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
292 SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
293
294 /* gx_q = (g^x)^q must === 1 mod p */
295 if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) {
296 error("%s: BN_mod_exp (g_x^q mod p)", __func__);
297 goto out;
298 }
299 if (BN_cmp(gx_q, BN_value_one()) != 0) {
300 error("%s: Invalid signature (g^x)^q != 1 mod p", __func__);
301 goto out;
302 }
303
304 SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
305 /* h = H(g || g^v || g^x || id) */
306 if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, e, g_x,
307 id, idlen)) == NULL) {
308 error("%s: schnorr_hash failed", __func__);
309 goto out;
310 }
311
312 /* g_xh = (g^x)^h */
313 if (BN_mod_exp(g_xh, g_x, h, grp_p, bn_ctx) == -1) {
314 error("%s: BN_mod_exp (g_x^h mod p)", __func__);
315 goto out;
316 }
317 SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
318
319 /* g_r = g^r */
320 if (BN_mod_exp(g_r, grp_g, r, grp_p, bn_ctx) == -1) {
321 error("%s: BN_mod_exp (g_x^h mod p)", __func__);
322 goto out;
323 }
324 SCHNORR_DEBUG_BN((g_r, "%s: g_r = ", __func__));
325
326 /* expected = g^r * g_xh */
327 if (BN_mod_mul(expected, g_r, g_xh, grp_p, bn_ctx) == -1) {
328 error("%s: BN_mod_mul (expected = g_r mod p)", __func__);
329 goto out;
330 }
331 SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
332
333 /* Check e == expected */
334 success = BN_cmp(expected, e) == 0;
335 out:
336 BN_CTX_free(bn_ctx);
337 if (h != NULL)
338 BN_clear_free(h);
339 if (gx_q != NULL)
340 BN_clear_free(gx_q);
341 if (g_xh != NULL)
342 BN_clear_free(g_xh);
343 if (g_r != NULL)
344 BN_clear_free(g_r);
345 if (expected != NULL)
346 BN_clear_free(expected);
347 return success;
348}
349
350/*
351 * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
352 * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g' using a
353 * SHA256 hash.
354 * Signature hash will be salted with 'idlen' bytes from 'id'.
355 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
356 */
357int
358schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
359 const BIGNUM *grp_g,
360 const BIGNUM *g_x, const u_char *id, u_int idlen,
361 const u_char *sig, u_int siglen)
362{
363 Buffer b;
364 int ret = -1;
365 u_int rlen;
366 BIGNUM *r, *e;
367
368 e = r = NULL;
369 if ((e = BN_new()) == NULL ||
370 (r = BN_new()) == NULL) {
371 error("%s: BN_new", __func__);
372 goto out;
373 }
374
375 /* Extract g^v and r from signature blob */
376 buffer_init(&b);
377 buffer_append(&b, sig, siglen);
378 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
379 "%s: sigblob", __func__));
380 buffer_get_bignum2(&b, e);
381 buffer_get_bignum2(&b, r);
382 rlen = buffer_len(&b);
383 buffer_free(&b);
384 if (rlen != 0) {
385 error("%s: remaining bytes in signature %d", __func__, rlen);
386 goto out;
387 }
388
389 ret = schnorr_verify(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
390 g_x, id, idlen, r, e);
391 out:
392 BN_clear_free(e);
393 BN_clear_free(r);
394
395 return ret;
396}
397
398/* Helper functions */
399
400/*
401 * Generate uniformly distributed random number in range (1, high).
402 * Return number on success, NULL on failure.
403 */
404BIGNUM *
405bn_rand_range_gt_one(const BIGNUM *high)
406{
407 BIGNUM *r, *tmp;
408 int success = -1;
409
410 if ((tmp = BN_new()) == NULL) {
411 error("%s: BN_new", __func__);
412 return NULL;
413 }
414 if ((r = BN_new()) == NULL) {
415 error("%s: BN_new failed", __func__);
416 goto out;
417 }
418 if (BN_set_word(tmp, 2) != 1) {
419 error("%s: BN_set_word(tmp, 2)", __func__);
420 goto out;
421 }
422 if (BN_sub(tmp, high, tmp) == -1) {
423 error("%s: BN_sub failed (tmp = high - 2)", __func__);
424 goto out;
425 }
426 if (BN_rand_range(r, tmp) == -1) {
427 error("%s: BN_rand_range failed", __func__);
428 goto out;
429 }
430 if (BN_set_word(tmp, 2) != 1) {
431 error("%s: BN_set_word(tmp, 2)", __func__);
432 goto out;
433 }
434 if (BN_add(r, r, tmp) == -1) {
435 error("%s: BN_add failed (r = r + 2)", __func__);
436 goto out;
437 }
438 success = 0;
439 out:
440 BN_clear_free(tmp);
441 if (success == 0)
442 return r;
443 BN_clear_free(r);
444 return NULL;
445}
446
447/* XXX convert all callers of this to use ssh_digest_memory() directly */
448/*
449 * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
450 * with digest via 'digestp' (caller to free) and length via 'lenp'.
451 * Returns -1 on failure.
452 */
453int
454hash_buffer(const u_char *buf, u_int len, int hash_alg,
455 u_char **digestp, u_int *lenp)
456{
457 u_char digest[SSH_DIGEST_MAX_LENGTH];
458 u_int digest_len = ssh_digest_bytes(hash_alg);
459
460 if (digest_len == 0) {
461 error("%s: invalid hash", __func__);
462 return -1;
463 }
464 if (ssh_digest_memory(hash_alg, buf, len, digest, digest_len) != 0) {
465 error("%s: digest_memory failed", __func__);
466 return -1;
467 }
468 *digestp = xmalloc(digest_len);
469 *lenp = digest_len;
470 memcpy(*digestp, digest, *lenp);
471 bzero(digest, sizeof(digest));
472 digest_len = 0;
473 return 0;
474}
475
476/* print formatted string followed by bignum */
477void
478debug3_bn(const BIGNUM *n, const char *fmt, ...)
479{
480 char *out, *h;
481 va_list args;
482 int ret;
483
484 out = NULL;
485 va_start(args, fmt);
486 ret = vasprintf(&out, fmt, args);
487 va_end(args);
488 if (ret == -1 || out == NULL)
489 fatal("%s: vasprintf failed", __func__);
490
491 if (n == NULL)
492 debug3("%s(null)", out);
493 else {
494 h = BN_bn2hex(n);
495 debug3("%s0x%s", out, h);
496 free(h);
497 }
498 free(out);
499}
500
501/* print formatted string followed by buffer contents in hex */
502void
503debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
504{
505 char *out, h[65];
506 u_int i, j;
507 va_list args;
508 int ret;
509
510 out = NULL;
511 va_start(args, fmt);
512 ret = vasprintf(&out, fmt, args);
513 va_end(args);
514 if (ret == -1 || out == NULL)
515 fatal("%s: vasprintf failed", __func__);
516
517 debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
518 free(out);
519 if (buf == NULL)
520 return;
521
522 *h = '\0';
523 for (i = j = 0; i < len; i++) {
524 snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
525 j += 2;
526 if (j >= sizeof(h) - 1 || i == len - 1) {
527 debug3(" %s", h);
528 *h = '\0';
529 j = 0;
530 }
531 }
532}
533
534/*
535 * Construct a MODP group from hex strings p (which must be a safe
536 * prime) and g, automatically calculating subgroup q as (p / 2)
537 */
538struct modp_group *
539modp_group_from_g_and_safe_p(const char *grp_g, const char *grp_p)
540{
541 struct modp_group *ret;
542
543 ret = xcalloc(1, sizeof(*ret));
544 ret->p = ret->q = ret->g = NULL;
545 if (BN_hex2bn(&ret->p, grp_p) == 0 ||
546 BN_hex2bn(&ret->g, grp_g) == 0)
547 fatal("%s: BN_hex2bn", __func__);
548 /* Subgroup order is p/2 (p is a safe prime) */
549 if ((ret->q = BN_new()) == NULL)
550 fatal("%s: BN_new", __func__);
551 if (BN_rshift1(ret->q, ret->p) != 1)
552 fatal("%s: BN_rshift1", __func__);
553
554 return ret;
555}
556
557void
558modp_group_free(struct modp_group *grp)
559{
560 if (grp->g != NULL)
561 BN_clear_free(grp->g);
562 if (grp->p != NULL)
563 BN_clear_free(grp->p);
564 if (grp->q != NULL)
565 BN_clear_free(grp->q);
566 bzero(grp, sizeof(*grp));
567 free(grp);
568}
569
570/* main() function for self-test */
571
572#ifdef SCHNORR_MAIN
573static void
574schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
575 const BIGNUM *grp_g, const BIGNUM *x)
576{
577 BIGNUM *g_x;
578 u_char *sig;
579 u_int siglen;
580 BN_CTX *bn_ctx;
581
582 if ((bn_ctx = BN_CTX_new()) == NULL)
583 fatal("%s: BN_CTX_new", __func__);
584 if ((g_x = BN_new()) == NULL)
585 fatal("%s: BN_new", __func__);
586
587 if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
588 fatal("%s: g_x", __func__);
589 if (schnorr_sign_buf(grp_p, grp_q, grp_g, x, g_x, "junk", 4,
590 &sig, &siglen))
591 fatal("%s: schnorr_sign", __func__);
592 if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
593 sig, siglen) != 1)
594 fatal("%s: verify fail", __func__);
595 if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
596 sig, siglen) != 0)
597 fatal("%s: verify should have failed (bad ID)", __func__);
598 sig[4] ^= 1;
599 if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
600 sig, siglen) != 0)
601 fatal("%s: verify should have failed (bit error)", __func__);
602 free(sig);
603 BN_free(g_x);
604 BN_CTX_free(bn_ctx);
605}
606
607static void
608schnorr_selftest(void)
609{
610 BIGNUM *x;
611 struct modp_group *grp;
612 u_int i;
613 char *hh;
614
615 grp = jpake_default_group();
616 if ((x = BN_new()) == NULL)
617 fatal("%s: BN_new", __func__);
618 SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__));
619 SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__));
620 SCHNORR_DEBUG_BN((grp->g, "%s: grp->g = ", __func__));
621
622 /* [1, 20) */
623 for (i = 1; i < 20; i++) {
624 printf("x = %u\n", i);
625 fflush(stdout);
626 if (BN_set_word(x, i) != 1)
627 fatal("%s: set x word", __func__);
628 schnorr_selftest_one(grp->p, grp->q, grp->g, x);
629 }
630
631 /* 100 x random [0, p) */
632 for (i = 0; i < 100; i++) {
633 if (BN_rand_range(x, grp->p) != 1)
634 fatal("%s: BN_rand_range", __func__);
635 hh = BN_bn2hex(x);
636 printf("x = (random) 0x%s\n", hh);
637 free(hh);
638 fflush(stdout);
639 schnorr_selftest_one(grp->p, grp->q, grp->g, x);
640 }
641
642 /* [q-20, q) */
643 if (BN_set_word(x, 20) != 1)
644 fatal("%s: BN_set_word (x = 20)", __func__);
645 if (BN_sub(x, grp->q, x) != 1)
646 fatal("%s: BN_sub (q - x)", __func__);
647 for (i = 0; i < 19; i++) {
648 hh = BN_bn2hex(x);
649 printf("x = (q - %d) 0x%s\n", 20 - i, hh);
650 free(hh);
651 fflush(stdout);
652 schnorr_selftest_one(grp->p, grp->q, grp->g, x);
653 if (BN_add(x, x, BN_value_one()) != 1)
654 fatal("%s: BN_add (x + 1)", __func__);
655 }
656 BN_free(x);
657}
658
659int
660main(int argc, char **argv)
661{
662 log_init(argv[0], SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_USER, 1);
663
664 schnorr_selftest();
665 return 0;
666}
667#endif
668
diff --git a/schnorr.h b/schnorr.h
deleted file mode 100644
index e2405c102..000000000
--- a/schnorr.h
+++ /dev/null
@@ -1,60 +0,0 @@
1/* $OpenBSD: schnorr.h,v 1.2 2014/01/09 23:20:00 djm Exp $ */
2/*
3 * Copyright (c) 2009 Damien Miller. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef SCHNORR_H
19#define SCHNORR_H
20
21#include <sys/types.h>
22
23#include <openssl/bn.h>
24
25struct modp_group {
26 BIGNUM *p, *q, *g;
27};
28
29BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
30int hash_buffer(const u_char *, u_int, int, u_char **, u_int *);
31void debug3_bn(const BIGNUM *, const char *, ...)
32 __attribute__((__nonnull__ (2)))
33 __attribute__((format(printf, 2, 3)));
34void debug3_buf(const u_char *, u_int, const char *, ...)
35 __attribute__((__nonnull__ (3)))
36 __attribute__((format(printf, 3, 4)));
37struct modp_group *modp_group_from_g_and_safe_p(const char *, const char *);
38void modp_group_free(struct modp_group *);
39
40/* Signature and verification functions */
41int
42schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
43 int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
44 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p);
45int
46schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
47 const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
48 u_char **sig, u_int *siglen);
49int
50schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
51 int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
52 const BIGNUM *r, const BIGNUM *e);
53int
54schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
55 const BIGNUM *grp_g,
56 const BIGNUM *g_x, const u_char *id, u_int idlen,
57 const u_char *sig, u_int siglen);
58
59#endif /* JPAKE_H */
60
diff --git a/scp.0 b/scp.0
index ced71546b..b9eeffc4e 100644
--- a/scp.0
+++ b/scp.0
@@ -160,4 +160,4 @@ AUTHORS
160 Timo Rinne <tri@iki.fi> 160 Timo Rinne <tri@iki.fi>
161 Tatu Ylonen <ylo@cs.hut.fi> 161 Tatu Ylonen <ylo@cs.hut.fi>
162 162
163OpenBSD 5.4 October 20, 2013 OpenBSD 5.4 163OpenBSD 5.5 October 20, 2013 OpenBSD 5.5
diff --git a/servconf.c b/servconf.c
index 63ff4ffbc..37fd2de6d 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.248 2013/12/06 13:39:49 markus Exp $ */ 2/* $OpenBSD: servconf.c,v 1.249 2014/01/29 06:18:35 djm Exp $ */
3/* 3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved 5 * All rights reserved
@@ -150,7 +150,6 @@ initialize_server_options(ServerOptions *options)
150 options->chroot_directory = NULL; 150 options->chroot_directory = NULL;
151 options->authorized_keys_command = NULL; 151 options->authorized_keys_command = NULL;
152 options->authorized_keys_command_user = NULL; 152 options->authorized_keys_command_user = NULL;
153 options->zero_knowledge_password_authentication = -1;
154 options->revoked_keys_file = NULL; 153 options->revoked_keys_file = NULL;
155 options->trusted_user_ca_keys = NULL; 154 options->trusted_user_ca_keys = NULL;
156 options->authorized_principals_file = NULL; 155 options->authorized_principals_file = NULL;
@@ -305,8 +304,6 @@ fill_default_server_options(ServerOptions *options)
305 } 304 }
306 if (options->permit_tun == -1) 305 if (options->permit_tun == -1)
307 options->permit_tun = SSH_TUNMODE_NO; 306 options->permit_tun = SSH_TUNMODE_NO;
308 if (options->zero_knowledge_password_authentication == -1)
309 options->zero_knowledge_password_authentication = 0;
310 if (options->ip_qos_interactive == -1) 307 if (options->ip_qos_interactive == -1)
311 options->ip_qos_interactive = IPTOS_LOWDELAY; 308 options->ip_qos_interactive = IPTOS_LOWDELAY;
312 if (options->ip_qos_bulk == -1) 309 if (options->ip_qos_bulk == -1)
@@ -360,7 +357,7 @@ typedef enum {
360 sAcceptEnv, sPermitTunnel, 357 sAcceptEnv, sPermitTunnel,
361 sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 358 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
362 sUsePrivilegeSeparation, sAllowAgentForwarding, 359 sUsePrivilegeSeparation, sAllowAgentForwarding,
363 sZeroKnowledgePasswordAuthentication, sHostCertificate, 360 sHostCertificate,
364 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, 361 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
365 sKexAlgorithms, sIPQoS, sVersionAddendum, 362 sKexAlgorithms, sIPQoS, sVersionAddendum,
366 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, 363 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
@@ -443,11 +440,6 @@ static struct {
443 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 440 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
444 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 441 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
445 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ 442 { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
446#ifdef JPAKE
447 { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
448#else
449 { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
450#endif
451 { "checkmail", sDeprecated, SSHCFG_GLOBAL }, 443 { "checkmail", sDeprecated, SSHCFG_GLOBAL },
452 { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, 444 { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
453 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, 445 { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
@@ -1141,10 +1133,6 @@ process_server_config_line(ServerOptions *options, char *line,
1141 intptr = &options->password_authentication; 1133 intptr = &options->password_authentication;
1142 goto parse_flag; 1134 goto parse_flag;
1143 1135
1144 case sZeroKnowledgePasswordAuthentication:
1145 intptr = &options->zero_knowledge_password_authentication;
1146 goto parse_flag;
1147
1148 case sKbdInteractiveAuthentication: 1136 case sKbdInteractiveAuthentication:
1149 intptr = &options->kbd_interactive_authentication; 1137 intptr = &options->kbd_interactive_authentication;
1150 goto parse_flag; 1138 goto parse_flag;
@@ -1810,7 +1798,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1810 M_CP_INTOPT(hostbased_authentication); 1798 M_CP_INTOPT(hostbased_authentication);
1811 M_CP_INTOPT(hostbased_uses_name_from_packet_only); 1799 M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1812 M_CP_INTOPT(kbd_interactive_authentication); 1800 M_CP_INTOPT(kbd_interactive_authentication);
1813 M_CP_INTOPT(zero_knowledge_password_authentication);
1814 M_CP_INTOPT(permit_root_login); 1801 M_CP_INTOPT(permit_root_login);
1815 M_CP_INTOPT(permit_empty_passwd); 1802 M_CP_INTOPT(permit_empty_passwd);
1816 1803
@@ -2056,10 +2043,6 @@ dump_config(ServerOptions *o)
2056 dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); 2043 dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
2057 dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); 2044 dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
2058#endif 2045#endif
2059#ifdef JPAKE
2060 dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
2061 o->zero_knowledge_password_authentication);
2062#endif
2063 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 2046 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2064 dump_cfg_fmtint(sKbdInteractiveAuthentication, 2047 dump_cfg_fmtint(sKbdInteractiveAuthentication,
2065 o->kbd_interactive_authentication); 2048 o->kbd_interactive_authentication);
diff --git a/servconf.h b/servconf.h
index 98d68ceaf..dcd1c2ab8 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.111 2013/12/05 01:16:41 djm Exp $ */ 1/* $OpenBSD: servconf.h,v 1.112 2014/01/29 06:18:35 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -120,8 +120,6 @@ typedef struct {
120 * authentication. */ 120 * authentication. */
121 int kbd_interactive_authentication; /* If true, permit */ 121 int kbd_interactive_authentication; /* If true, permit */
122 int challenge_response_authentication; 122 int challenge_response_authentication;
123 int zero_knowledge_password_authentication;
124 /* If true, permit jpake auth */
125 int permit_empty_passwd; /* If false, do not permit empty 123 int permit_empty_passwd; /* If false, do not permit empty
126 * passwords. */ 124 * passwords. */
127 int permit_user_env; /* If true, read ~/.ssh/environment */ 125 int permit_user_env; /* If true, read ~/.ssh/environment */
diff --git a/serverloop.c b/serverloop.c
index d3079d25d..441d73b4d 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.169 2013/12/19 00:19:12 dtucker Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.170 2014/02/02 03:44:31 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
@@ -920,7 +920,7 @@ server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
920 data = packet_get_string(&data_len); 920 data = packet_get_string(&data_len);
921 packet_check_eom(); 921 packet_check_eom();
922 buffer_append(&stdin_buffer, data, data_len); 922 buffer_append(&stdin_buffer, data, data_len);
923 memset(data, 0, data_len); 923 explicit_bzero(data, data_len);
924 free(data); 924 free(data);
925} 925}
926 926
diff --git a/session.c b/session.c
index 14df2262c..9d43fc3c7 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.c,v 1.269 2014/01/18 09:36:26 dtucker Exp $ */ 1/* $OpenBSD: session.c,v 1.270 2014/01/31 16:39:19 tedu Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -979,6 +979,11 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
979 u_int envsize; 979 u_int envsize;
980 u_int i, namelen; 980 u_int i, namelen;
981 981
982 if (strchr(name, '=') != NULL) {
983 error("Invalid environment variable \"%.100s\"", name);
984 return;
985 }
986
982 /* 987 /*
983 * If we're passed an uninitialized list, allocate a single null 988 * If we're passed an uninitialized list, allocate a single null
984 * entry before continuing. 989 * entry before continuing.
@@ -1898,7 +1903,7 @@ session_unused(int id)
1898 fatal("%s: insane session id %d (max %d nalloc %d)", 1903 fatal("%s: insane session id %d (max %d nalloc %d)",
1899 __func__, id, options.max_sessions, sessions_nalloc); 1904 __func__, id, options.max_sessions, sessions_nalloc);
1900 } 1905 }
1901 bzero(&sessions[id], sizeof(*sessions)); 1906 memset(&sessions[id], 0, sizeof(*sessions));
1902 sessions[id].self = id; 1907 sessions[id].self = id;
1903 sessions[id].used = 0; 1908 sessions[id].used = 0;
1904 sessions[id].chanid = -1; 1909 sessions[id].chanid = -1;
@@ -2234,8 +2239,8 @@ session_env_req(Session *s)
2234 char *name, *val; 2239 char *name, *val;
2235 u_int name_len, val_len, i; 2240 u_int name_len, val_len, i;
2236 2241
2237 name = packet_get_string(&name_len); 2242 name = packet_get_cstring(&name_len);
2238 val = packet_get_string(&val_len); 2243 val = packet_get_cstring(&val_len);
2239 packet_check_eom(); 2244 packet_check_eom();
2240 2245
2241 /* Don't set too many environment variables */ 2246 /* Don't set too many environment variables */
diff --git a/sftp-client.c b/sftp-client.c
index fc035f2ef..2f5907c85 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-client.c,v 1.113 2014/01/17 00:21:06 djm Exp $ */ 1/* $OpenBSD: sftp-client.c,v 1.114 2014/01/31 16:39:19 tedu Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -310,7 +310,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
310 SSH2_FXP_EXTENDED_REPLY, type); 310 SSH2_FXP_EXTENDED_REPLY, type);
311 } 311 }
312 312
313 bzero(st, sizeof(*st)); 313 memset(st, 0, sizeof(*st));
314 st->f_bsize = buffer_get_int64(&msg); 314 st->f_bsize = buffer_get_int64(&msg);
315 st->f_frsize = buffer_get_int64(&msg); 315 st->f_frsize = buffer_get_int64(&msg);
316 st->f_blocks = buffer_get_int64(&msg); 316 st->f_blocks = buffer_get_int64(&msg);
diff --git a/sftp-server.0 b/sftp-server.0
index 5bf8da600..ce7ddc07f 100644
--- a/sftp-server.0
+++ b/sftp-server.0
@@ -92,4 +92,4 @@ HISTORY
92AUTHORS 92AUTHORS
93 Markus Friedl <markus@openbsd.org> 93 Markus Friedl <markus@openbsd.org>
94 94
95OpenBSD 5.4 October 14, 2013 OpenBSD 5.4 95OpenBSD 5.5 October 14, 2013 OpenBSD 5.5
diff --git a/sftp.0 b/sftp.0
index 248737046..7139aac43 100644
--- a/sftp.0
+++ b/sftp.0
@@ -367,4 +367,4 @@ SEE ALSO
367 T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- 367 T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
368 filexfer-00.txt, January 2001, work in progress material. 368 filexfer-00.txt, January 2001, work in progress material.
369 369
370OpenBSD 5.4 October 20, 2013 OpenBSD 5.4 370OpenBSD 5.5 October 20, 2013 OpenBSD 5.5
diff --git a/ssh-add.0 b/ssh-add.0
index 8d10f7ff4..ba43fee69 100644
--- a/ssh-add.0
+++ b/ssh-add.0
@@ -120,4 +120,4 @@ AUTHORS
120 created OpenSSH. Markus Friedl contributed the support for SSH protocol 120 created OpenSSH. Markus Friedl contributed the support for SSH protocol
121 versions 1.5 and 2.0. 121 versions 1.5 and 2.0.
122 122
123OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 123OpenBSD 5.5 December 7, 2013 OpenBSD 5.5
diff --git a/ssh-add.c b/ssh-add.c
index 63ce72083..3421452af 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.108 2013/12/19 00:10:30 djm Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.109 2014/02/02 03:44:31 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
@@ -90,7 +90,7 @@ static void
90clear_pass(void) 90clear_pass(void)
91{ 91{
92 if (pass) { 92 if (pass) {
93 memset(pass, 0, strlen(pass)); 93 explicit_bzero(pass, strlen(pass));
94 free(pass); 94 free(pass);
95 pass = NULL; 95 pass = NULL;
96 } 96 }
@@ -366,7 +366,7 @@ lock_agent(AuthenticationConnection *ac, int lock)
366 fprintf(stderr, "Passwords do not match.\n"); 366 fprintf(stderr, "Passwords do not match.\n");
367 passok = 0; 367 passok = 0;
368 } 368 }
369 memset(p2, 0, strlen(p2)); 369 explicit_bzero(p2, strlen(p2));
370 free(p2); 370 free(p2);
371 } 371 }
372 if (passok && ssh_lock_agent(ac, lock, p1)) { 372 if (passok && ssh_lock_agent(ac, lock, p1)) {
@@ -374,7 +374,7 @@ lock_agent(AuthenticationConnection *ac, int lock)
374 ret = 0; 374 ret = 0;
375 } else 375 } else
376 fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un"); 376 fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un");
377 memset(p1, 0, strlen(p1)); 377 explicit_bzero(p1, strlen(p1));
378 free(p1); 378 free(p1);
379 return (ret); 379 return (ret);
380} 380}
diff --git a/ssh-agent.0 b/ssh-agent.0
index c4c53ef94..c11523db3 100644
--- a/ssh-agent.0
+++ b/ssh-agent.0
@@ -125,4 +125,4 @@ AUTHORS
125 created OpenSSH. Markus Friedl contributed the support for SSH protocol 125 created OpenSSH. Markus Friedl contributed the support for SSH protocol
126 versions 1.5 and 2.0. 126 versions 1.5 and 2.0.
127 127
128OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 128OpenBSD 5.5 December 7, 2013 OpenBSD 5.5
diff --git a/ssh-agent.c b/ssh-agent.c
index 95117e076..ba2461211 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.181 2013/12/19 01:19:41 djm Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.183 2014/02/02 03:44:31 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
@@ -50,7 +50,6 @@
50#include "openbsd-compat/sys-queue.h" 50#include "openbsd-compat/sys-queue.h"
51 51
52#include <openssl/evp.h> 52#include <openssl/evp.h>
53#include <openssl/md5.h>
54#include "openbsd-compat/openssl-compat.h" 53#include "openbsd-compat/openssl-compat.h"
55 54
56#include <errno.h> 55#include <errno.h>
@@ -75,6 +74,7 @@
75#include "compat.h" 74#include "compat.h"
76#include "log.h" 75#include "log.h"
77#include "misc.h" 76#include "misc.h"
77#include "digest.h"
78 78
79#ifdef ENABLE_PKCS11 79#ifdef ENABLE_PKCS11
80#include "ssh-pkcs11.h" 80#include "ssh-pkcs11.h"
@@ -248,7 +248,7 @@ process_authentication_challenge1(SocketEntry *e)
248 Identity *id; 248 Identity *id;
249 int i, len; 249 int i, len;
250 Buffer msg; 250 Buffer msg;
251 MD5_CTX md; 251 struct ssh_digest_ctx *md;
252 Key *key; 252 Key *key;
253 253
254 buffer_init(&msg); 254 buffer_init(&msg);
@@ -284,10 +284,12 @@ process_authentication_challenge1(SocketEntry *e)
284 } 284 }
285 memset(buf, 0, 32); 285 memset(buf, 0, 32);
286 BN_bn2bin(challenge, buf + 32 - len); 286 BN_bn2bin(challenge, buf + 32 - len);
287 MD5_Init(&md); 287 if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
288 MD5_Update(&md, buf, 32); 288 ssh_digest_update(md, buf, 32) < 0 ||
289 MD5_Update(&md, session_id, 16); 289 ssh_digest_update(md, session_id, 16) < 0 ||
290 MD5_Final(mdbuf, &md); 290 ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
291 fatal("%s: md5 failed", __func__);
292 ssh_digest_free(md);
291 293
292 /* Send the response. */ 294 /* Send the response. */
293 buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); 295 buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE);
@@ -552,7 +554,7 @@ process_lock_agent(SocketEntry *e, int lock)
552 passwd = buffer_get_string(&e->request, NULL); 554 passwd = buffer_get_string(&e->request, NULL);
553 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { 555 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
554 locked = 0; 556 locked = 0;
555 memset(lock_passwd, 0, strlen(lock_passwd)); 557 explicit_bzero(lock_passwd, strlen(lock_passwd));
556 free(lock_passwd); 558 free(lock_passwd);
557 lock_passwd = NULL; 559 lock_passwd = NULL;
558 success = 1; 560 success = 1;
@@ -561,7 +563,7 @@ process_lock_agent(SocketEntry *e, int lock)
561 lock_passwd = xstrdup(passwd); 563 lock_passwd = xstrdup(passwd);
562 success = 1; 564 success = 1;
563 } 565 }
564 memset(passwd, 0, strlen(passwd)); 566 explicit_bzero(passwd, strlen(passwd));
565 free(passwd); 567 free(passwd);
566 568
567 buffer_put_int(&e->output, 1); 569 buffer_put_int(&e->output, 1);
diff --git a/ssh-dss.c b/ssh-dss.c
index 7b897475c..6b4abcb7d 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-dss.c,v 1.30 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: ssh-dss.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -65,7 +65,7 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
65 } 65 }
66 66
67 sig = DSA_do_sign(digest, dlen, key->dsa); 67 sig = DSA_do_sign(digest, dlen, key->dsa);
68 memset(digest, 'd', sizeof(digest)); 68 explicit_bzero(digest, sizeof(digest));
69 69
70 if (sig == NULL) { 70 if (sig == NULL) {
71 error("ssh_dss_sign: sign failed"); 71 error("ssh_dss_sign: sign failed");
@@ -79,7 +79,7 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
79 DSA_SIG_free(sig); 79 DSA_SIG_free(sig);
80 return -1; 80 return -1;
81 } 81 }
82 memset(sigblob, 0, SIGBLOB_LEN); 82 explicit_bzero(sigblob, SIGBLOB_LEN);
83 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); 83 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
84 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); 84 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
85 DSA_SIG_free(sig); 85 DSA_SIG_free(sig);
@@ -168,7 +168,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
168 fatal("%s: BN_bin2bn failed", __func__); 168 fatal("%s: BN_bin2bn failed", __func__);
169 169
170 /* clean up */ 170 /* clean up */
171 memset(sigblob, 0, len); 171 explicit_bzero(sigblob, len);
172 free(sigblob); 172 free(sigblob);
173 173
174 /* sha1 the data */ 174 /* sha1 the data */
@@ -179,7 +179,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
179 } 179 }
180 180
181 ret = DSA_do_verify(digest, dlen, sig, key->dsa); 181 ret = DSA_do_verify(digest, dlen, sig, key->dsa);
182 memset(digest, 'd', sizeof(digest)); 182 explicit_bzero(digest, sizeof(digest));
183 183
184 DSA_SIG_free(sig); 184 DSA_SIG_free(sig);
185 185
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 10ad9da60..551c9c460 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: ssh-ecdsa.c,v 1.10 2014/02/03 23:28:00 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) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -72,7 +72,7 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
72 } 72 }
73 73
74 sig = ECDSA_do_sign(digest, dlen, key->ecdsa); 74 sig = ECDSA_do_sign(digest, dlen, key->ecdsa);
75 memset(digest, 'd', sizeof(digest)); 75 explicit_bzero(digest, sizeof(digest));
76 76
77 if (sig == NULL) { 77 if (sig == NULL) {
78 error("%s: sign failed", __func__); 78 error("%s: sign failed", __func__);
@@ -140,9 +140,6 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
140 /* parse signature */ 140 /* parse signature */
141 if ((sig = ECDSA_SIG_new()) == NULL) 141 if ((sig = ECDSA_SIG_new()) == NULL)
142 fatal("%s: ECDSA_SIG_new failed", __func__); 142 fatal("%s: ECDSA_SIG_new failed", __func__);
143 if ((sig->r = BN_new()) == NULL ||
144 (sig->s = BN_new()) == NULL)
145 fatal("%s: BN_new failed", __func__);
146 143
147 buffer_init(&bb); 144 buffer_init(&bb);
148 buffer_append(&bb, sigblob, len); 145 buffer_append(&bb, sigblob, len);
@@ -153,7 +150,7 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
153 buffer_free(&bb); 150 buffer_free(&bb);
154 151
155 /* clean up */ 152 /* clean up */
156 memset(sigblob, 0, len); 153 explicit_bzero(sigblob, len);
157 free(sigblob); 154 free(sigblob);
158 155
159 /* hash the data */ 156 /* hash the data */
@@ -169,7 +166,7 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
169 } 166 }
170 167
171 ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); 168 ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
172 memset(digest, 'd', sizeof(digest)); 169 explicit_bzero(digest, sizeof(digest));
173 170
174 ECDSA_SIG_free(sig); 171 ECDSA_SIG_free(sig);
175 172
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index 1aedcf83a..160d1f23b 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ed25519.c,v 1.1 2013/12/06 13:39:49 markus Exp $ */ 1/* $OpenBSD: ssh-ed25519.c,v 1.3 2014/02/23 20:03:42 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2013 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -21,6 +21,7 @@
21 21
22#include "crypto_api.h" 22#include "crypto_api.h"
23 23
24#include <limits.h>
24#include <string.h> 25#include <string.h>
25#include <stdarg.h> 26#include <stdarg.h>
26 27
@@ -45,6 +46,11 @@ ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp,
45 error("%s: no ED25519 key", __func__); 46 error("%s: no ED25519 key", __func__);
46 return -1; 47 return -1;
47 } 48 }
49
50 if (datalen >= UINT_MAX - crypto_sign_ed25519_BYTES) {
51 error("%s: datalen %u too long", __func__, datalen);
52 return -1;
53 }
48 smlen = slen = datalen + crypto_sign_ed25519_BYTES; 54 smlen = slen = datalen + crypto_sign_ed25519_BYTES;
49 sig = xmalloc(slen); 55 sig = xmalloc(slen);
50 56
@@ -66,7 +72,7 @@ ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp,
66 memcpy(*sigp, buffer_ptr(&b), len); 72 memcpy(*sigp, buffer_ptr(&b), len);
67 } 73 }
68 buffer_free(&b); 74 buffer_free(&b);
69 memset(sig, 's', slen); 75 explicit_bzero(sig, slen);
70 free(sig); 76 free(sig);
71 77
72 return 0; 78 return 0;
@@ -130,9 +136,9 @@ ssh_ed25519_verify(const Key *key, const u_char *signature, u_int signaturelen,
130 } 136 }
131 /* XXX compare 'm' and 'data' ? */ 137 /* XXX compare 'm' and 'data' ? */
132 138
133 memset(sigblob, 's', len); 139 explicit_bzero(sigblob, len);
134 memset(sm, 'S', smlen); 140 explicit_bzero(sm, smlen);
135 memset(m, 'm', smlen); /* NB. mlen may be invalid if ret != 0 */ 141 explicit_bzero(m, smlen); /* NB. mlen may be invalid if ret != 0 */
136 free(sigblob); 142 free(sigblob);
137 free(sm); 143 free(sm);
138 free(m); 144 free(m);
diff --git a/ssh-gss.h b/ssh-gss.h
index 885e48185..914701bcf 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */ 1/* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. 3 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
4 * 4 *
@@ -121,6 +121,8 @@ void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
121void ssh_gssapi_set_oid(Gssctxt *, gss_OID); 121void ssh_gssapi_set_oid(Gssctxt *, gss_OID);
122void ssh_gssapi_supported_oids(gss_OID_set *); 122void ssh_gssapi_supported_oids(gss_OID_set *);
123ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *); 123ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *);
124void ssh_gssapi_prepare_supported_oids(void);
125OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *);
124 126
125OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); 127OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *);
126OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, 128OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int,
diff --git a/ssh-keygen.0 b/ssh-keygen.0
index a69b37d67..c43678ff0 100644
--- a/ssh-keygen.0
+++ b/ssh-keygen.0
@@ -4,7 +4,7 @@ NAME
4 ssh-keygen - authentication key generation, management and conversion 4 ssh-keygen - authentication key generation, management and conversion
5 5
6SYNOPSIS 6SYNOPSIS
7 ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment] 7 ssh-keygen [-q] [-b bits] [-t type] [-N new_passphrase] [-C comment]
8 [-f output_keyfile] 8 [-f output_keyfile]
9 ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] 9 ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
10 ssh-keygen -i [-m key_format] [-f input_keyfile] 10 ssh-keygen -i [-m key_format] [-f input_keyfile]
@@ -559,4 +559,4 @@ AUTHORS
559 created OpenSSH. Markus Friedl contributed the support for SSH protocol 559 created OpenSSH. Markus Friedl contributed the support for SSH protocol
560 versions 1.5 and 2.0. 560 versions 1.5 and 2.0.
561 561
562OpenBSD 5.4 December 21, 2013 OpenBSD 5.4 562OpenBSD 5.5 February 5, 2014 OpenBSD 5.5
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 299ccf8dd..a71de7481 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.119 2013/12/21 07:10:47 tedu Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.120 2014/02/05 20:13:25 naddy 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
@@ -35,7 +35,7 @@
35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37.\" 37.\"
38.Dd $Mdocdate: December 21 2013 $ 38.Dd $Mdocdate: February 5 2014 $
39.Dt SSH-KEYGEN 1 39.Dt SSH-KEYGEN 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -46,7 +46,7 @@
46.Nm ssh-keygen 46.Nm ssh-keygen
47.Op Fl q 47.Op Fl q
48.Op Fl b Ar bits 48.Op Fl b Ar bits
49.Fl t Ar type 49.Op Fl t Ar type
50.Op Fl N Ar new_passphrase 50.Op Fl N Ar new_passphrase
51.Op Fl C Ar comment 51.Op Fl C Ar comment
52.Op Fl f Ar output_keyfile 52.Op Fl f Ar output_keyfile
diff --git a/ssh-keygen.c b/ssh-keygen.c
index eae83a461..2a316bcea 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.238 2013/12/06 13:39:49 markus Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.241 2014/02/05 20:13:25 naddy Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -267,7 +267,7 @@ load_identity(char *filename)
267 pass = read_passphrase("Enter passphrase: ", 267 pass = read_passphrase("Enter passphrase: ",
268 RP_ALLOW_STDIN); 268 RP_ALLOW_STDIN);
269 prv = key_load_private(filename, pass, NULL); 269 prv = key_load_private(filename, pass, NULL);
270 memset(pass, 0, strlen(pass)); 270 explicit_bzero(pass, strlen(pass));
271 free(pass); 271 free(pass);
272 } 272 }
273 return prv; 273 return prv;
@@ -1258,7 +1258,7 @@ do_change_passphrase(struct passwd *pw)
1258 RP_ALLOW_STDIN); 1258 RP_ALLOW_STDIN);
1259 private = key_load_private(identity_file, old_passphrase, 1259 private = key_load_private(identity_file, old_passphrase,
1260 &comment); 1260 &comment);
1261 memset(old_passphrase, 0, strlen(old_passphrase)); 1261 explicit_bzero(old_passphrase, strlen(old_passphrase));
1262 free(old_passphrase); 1262 free(old_passphrase);
1263 if (private == NULL) { 1263 if (private == NULL) {
1264 printf("Bad passphrase.\n"); 1264 printf("Bad passphrase.\n");
@@ -1280,15 +1280,15 @@ do_change_passphrase(struct passwd *pw)
1280 1280
1281 /* Verify that they are the same. */ 1281 /* Verify that they are the same. */
1282 if (strcmp(passphrase1, passphrase2) != 0) { 1282 if (strcmp(passphrase1, passphrase2) != 0) {
1283 memset(passphrase1, 0, strlen(passphrase1)); 1283 explicit_bzero(passphrase1, strlen(passphrase1));
1284 memset(passphrase2, 0, strlen(passphrase2)); 1284 explicit_bzero(passphrase2, strlen(passphrase2));
1285 free(passphrase1); 1285 free(passphrase1);
1286 free(passphrase2); 1286 free(passphrase2);
1287 printf("Pass phrases do not match. Try again.\n"); 1287 printf("Pass phrases do not match. Try again.\n");
1288 exit(1); 1288 exit(1);
1289 } 1289 }
1290 /* Destroy the other copy. */ 1290 /* Destroy the other copy. */
1291 memset(passphrase2, 0, strlen(passphrase2)); 1291 explicit_bzero(passphrase2, strlen(passphrase2));
1292 free(passphrase2); 1292 free(passphrase2);
1293 } 1293 }
1294 1294
@@ -1296,14 +1296,14 @@ do_change_passphrase(struct passwd *pw)
1296 if (!key_save_private(private, identity_file, passphrase1, comment, 1296 if (!key_save_private(private, identity_file, passphrase1, comment,
1297 use_new_format, new_format_cipher, rounds)) { 1297 use_new_format, new_format_cipher, rounds)) {
1298 printf("Saving the key failed: %s.\n", identity_file); 1298 printf("Saving the key failed: %s.\n", identity_file);
1299 memset(passphrase1, 0, strlen(passphrase1)); 1299 explicit_bzero(passphrase1, strlen(passphrase1));
1300 free(passphrase1); 1300 free(passphrase1);
1301 key_free(private); 1301 key_free(private);
1302 free(comment); 1302 free(comment);
1303 exit(1); 1303 exit(1);
1304 } 1304 }
1305 /* Destroy the passphrase and the copy of the key in memory. */ 1305 /* Destroy the passphrase and the copy of the key in memory. */
1306 memset(passphrase1, 0, strlen(passphrase1)); 1306 explicit_bzero(passphrase1, strlen(passphrase1));
1307 free(passphrase1); 1307 free(passphrase1);
1308 key_free(private); /* Destroys contents */ 1308 key_free(private); /* Destroys contents */
1309 free(comment); 1309 free(comment);
@@ -1375,7 +1375,7 @@ do_change_comment(struct passwd *pw)
1375 /* Try to load using the passphrase. */ 1375 /* Try to load using the passphrase. */
1376 private = key_load_private(identity_file, passphrase, &comment); 1376 private = key_load_private(identity_file, passphrase, &comment);
1377 if (private == NULL) { 1377 if (private == NULL) {
1378 memset(passphrase, 0, strlen(passphrase)); 1378 explicit_bzero(passphrase, strlen(passphrase));
1379 free(passphrase); 1379 free(passphrase);
1380 printf("Bad passphrase.\n"); 1380 printf("Bad passphrase.\n");
1381 exit(1); 1381 exit(1);
@@ -1396,7 +1396,7 @@ do_change_comment(struct passwd *pw)
1396 printf("Enter new comment: "); 1396 printf("Enter new comment: ");
1397 fflush(stdout); 1397 fflush(stdout);
1398 if (!fgets(new_comment, sizeof(new_comment), stdin)) { 1398 if (!fgets(new_comment, sizeof(new_comment), stdin)) {
1399 memset(passphrase, 0, strlen(passphrase)); 1399 explicit_bzero(passphrase, strlen(passphrase));
1400 key_free(private); 1400 key_free(private);
1401 exit(1); 1401 exit(1);
1402 } 1402 }
@@ -1407,13 +1407,13 @@ do_change_comment(struct passwd *pw)
1407 if (!key_save_private(private, identity_file, passphrase, new_comment, 1407 if (!key_save_private(private, identity_file, passphrase, new_comment,
1408 use_new_format, new_format_cipher, rounds)) { 1408 use_new_format, new_format_cipher, rounds)) {
1409 printf("Saving the key failed: %s.\n", identity_file); 1409 printf("Saving the key failed: %s.\n", identity_file);
1410 memset(passphrase, 0, strlen(passphrase)); 1410 explicit_bzero(passphrase, strlen(passphrase));
1411 free(passphrase); 1411 free(passphrase);
1412 key_free(private); 1412 key_free(private);
1413 free(comment); 1413 free(comment);
1414 exit(1); 1414 exit(1);
1415 } 1415 }
1416 memset(passphrase, 0, strlen(passphrase)); 1416 explicit_bzero(passphrase, strlen(passphrase));
1417 free(passphrase); 1417 free(passphrase);
1418 public = key_from_private(private); 1418 public = key_from_private(private);
1419 key_free(private); 1419 key_free(private);
@@ -1716,7 +1716,7 @@ parse_absolute_time(const char *s)
1716 fatal("Invalid certificate time format %s", s); 1716 fatal("Invalid certificate time format %s", s);
1717 } 1717 }
1718 1718
1719 bzero(&tm, sizeof(tm)); 1719 memset(&tm, 0, sizeof(tm));
1720 if (strptime(buf, fmt, &tm) == NULL) 1720 if (strptime(buf, fmt, &tm) == NULL)
1721 fatal("Invalid certificate time %s", s); 1721 fatal("Invalid certificate time %s", s);
1722 if ((tt = mktime(&tm)) < 0) 1722 if ((tt = mktime(&tm)) < 0)
@@ -2196,8 +2196,8 @@ usage(void)
2196 fprintf(stderr, " -v Verbose.\n"); 2196 fprintf(stderr, " -v Verbose.\n");
2197 fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); 2197 fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n");
2198 fprintf(stderr, " -y Read private key file and print public key.\n"); 2198 fprintf(stderr, " -y Read private key file and print public key.\n");
2199 fprintf(stderr, " -z serial Specify a serial number.\n");
2200 fprintf(stderr, " -Z cipher Specify a cipher for new private key format.\n"); 2199 fprintf(stderr, " -Z cipher Specify a cipher for new private key format.\n");
2200 fprintf(stderr, " -z serial Specify a serial number.\n");
2201 2201
2202 exit(1); 2202 exit(1);
2203} 2203}
@@ -2632,15 +2632,15 @@ passphrase_again:
2632 * The passphrases do not match. Clear them and 2632 * The passphrases do not match. Clear them and
2633 * retry. 2633 * retry.
2634 */ 2634 */
2635 memset(passphrase1, 0, strlen(passphrase1)); 2635 explicit_bzero(passphrase1, strlen(passphrase1));
2636 memset(passphrase2, 0, strlen(passphrase2)); 2636 explicit_bzero(passphrase2, strlen(passphrase2));
2637 free(passphrase1); 2637 free(passphrase1);
2638 free(passphrase2); 2638 free(passphrase2);
2639 printf("Passphrases do not match. Try again.\n"); 2639 printf("Passphrases do not match. Try again.\n");
2640 goto passphrase_again; 2640 goto passphrase_again;
2641 } 2641 }
2642 /* Clear the other copy of the passphrase. */ 2642 /* Clear the other copy of the passphrase. */
2643 memset(passphrase2, 0, strlen(passphrase2)); 2643 explicit_bzero(passphrase2, strlen(passphrase2));
2644 free(passphrase2); 2644 free(passphrase2);
2645 } 2645 }
2646 2646
@@ -2655,12 +2655,12 @@ passphrase_again:
2655 if (!key_save_private(private, identity_file, passphrase1, comment, 2655 if (!key_save_private(private, identity_file, passphrase1, comment,
2656 use_new_format, new_format_cipher, rounds)) { 2656 use_new_format, new_format_cipher, rounds)) {
2657 printf("Saving the key failed: %s.\n", identity_file); 2657 printf("Saving the key failed: %s.\n", identity_file);
2658 memset(passphrase1, 0, strlen(passphrase1)); 2658 explicit_bzero(passphrase1, strlen(passphrase1));
2659 free(passphrase1); 2659 free(passphrase1);
2660 exit(1); 2660 exit(1);
2661 } 2661 }
2662 /* Clear the passphrase. */ 2662 /* Clear the passphrase. */
2663 memset(passphrase1, 0, strlen(passphrase1)); 2663 explicit_bzero(passphrase1, strlen(passphrase1));
2664 free(passphrase1); 2664 free(passphrase1);
2665 2665
2666 /* Clear the private key and the random number generator. */ 2666 /* Clear the private key and the random number generator. */
diff --git a/ssh-keyscan.0 b/ssh-keyscan.0
index 09cfa0afa..638c19b48 100644
--- a/ssh-keyscan.0
+++ b/ssh-keyscan.0
@@ -27,9 +27,10 @@ DESCRIPTION
27 -6 Forces ssh-keyscan to use IPv6 addresses only. 27 -6 Forces ssh-keyscan to use IPv6 addresses only.
28 28
29 -f file 29 -f file
30 Read hosts or addrlist namelist pairs from this file, one per 30 Read hosts or ``addrlist namelist'' pairs from file, one per
31 line. If - is supplied instead of a filename, ssh-keyscan will 31 line. If - is supplied instead of a filename, ssh-keyscan will
32 read hosts or addrlist namelist pairs from the standard input. 32 read hosts or ``addrlist namelist'' pairs from the standard
33 input.
33 34
34 -H Hash all hostnames and addresses in the output. Hashed names may 35 -H Hash all hostnames and addresses in the output. Hashed names may
35 be used normally by ssh and sshd, but they do not reveal 36 be used normally by ssh and sshd, but they do not reveal
@@ -106,4 +107,4 @@ BUGS
106 This is because it opens a connection to the ssh port, reads the public 107 This is because it opens a connection to the ssh port, reads the public
107 key, and drops the connection as soon as it gets the key. 108 key, and drops the connection as soon as it gets the key.
108 109
109OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 110OpenBSD 5.5 January 28, 2014 OpenBSD 5.5
diff --git a/ssh-keyscan.1 b/ssh-keyscan.1
index 65ef43efd..dae4fd9fb 100644
--- a/ssh-keyscan.1
+++ b/ssh-keyscan.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keyscan.1,v 1.33 2013/12/07 11:58:46 naddy Exp $ 1.\" $OpenBSD: ssh-keyscan.1,v 1.34 2014/01/28 14:13:39 jmc Exp $
2.\" 2.\"
3.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. 3.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
4.\" 4.\"
@@ -6,7 +6,7 @@
6.\" permitted provided that due credit is given to the author and the 6.\" permitted provided that due credit is given to the author and the
7.\" OpenBSD project by leaving this copyright notice intact. 7.\" OpenBSD project by leaving this copyright notice intact.
8.\" 8.\"
9.Dd $Mdocdate: December 7 2013 $ 9.Dd $Mdocdate: January 28 2014 $
10.Dt SSH-KEYSCAN 1 10.Dt SSH-KEYSCAN 1
11.Os 11.Os
12.Sh NAME 12.Sh NAME
@@ -56,14 +56,16 @@ Forces
56to use IPv6 addresses only. 56to use IPv6 addresses only.
57.It Fl f Ar file 57.It Fl f Ar file
58Read hosts or 58Read hosts or
59.Pa addrlist namelist 59.Dq addrlist namelist
60pairs from this file, one per line. 60pairs from
61.Ar file ,
62one per line.
61If 63If
62.Pa - 64.Pa -
63is supplied instead of a filename, 65is supplied instead of a filename,
64.Nm 66.Nm
65will read hosts or 67will read hosts or
66.Pa addrlist namelist 68.Dq addrlist namelist
67pairs from the standard input. 69pairs from the standard input.
68.It Fl H 70.It Fl H
69Hash all hostnames and addresses in the output. 71Hash all hostnames and addresses in the output.
@@ -78,7 +80,7 @@ Port to connect to on the remote host.
78.It Fl T Ar timeout 80.It Fl T Ar timeout
79Set the timeout for connection attempts. 81Set the timeout for connection attempts.
80If 82If
81.Pa timeout 83.Ar timeout
82seconds have elapsed since a connection was initiated to a host or since the 84seconds have elapsed since a connection was initiated to a host or since the
83last time anything was read from that host, then the connection is 85last time anything was read from that host, then the connection is
84closed and the host in question considered unavailable. 86closed and the host in question considered unavailable.
@@ -117,23 +119,23 @@ On the other hand, if the security model allows such a risk,
117can help in the detection of tampered keyfiles or man in the middle 119can help in the detection of tampered keyfiles or man in the middle
118attacks which have begun after the ssh_known_hosts file was created. 120attacks which have begun after the ssh_known_hosts file was created.
119.Sh FILES 121.Sh FILES
120.Pa Input format: 122Input format:
121.Bd -literal 123.Bd -literal
1221.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 1241.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
123.Ed 125.Ed
124.Pp 126.Pp
125.Pa Output format for rsa1 keys: 127Output format for rsa1 keys:
126.Bd -literal 128.Bd -literal
127host-or-namelist bits exponent modulus 129host-or-namelist bits exponent modulus
128.Ed 130.Ed
129.Pp 131.Pp
130.Pa Output format for rsa, dsa and ecdsa keys: 132Output format for rsa, dsa and ecdsa keys:
131.Bd -literal 133.Bd -literal
132host-or-namelist keytype base64-encoded-key 134host-or-namelist keytype base64-encoded-key
133.Ed 135.Ed
134.Pp 136.Pp
135Where 137Where
136.Pa keytype 138.Ar keytype
137is either 139is either
138.Dq ecdsa-sha2-nistp256 , 140.Dq ecdsa-sha2-nistp256 ,
139.Dq ecdsa-sha2-nistp384 , 141.Dq ecdsa-sha2-nistp384 ,
@@ -145,10 +147,8 @@ or
145.Pp 147.Pp
146.Pa /etc/ssh/ssh_known_hosts 148.Pa /etc/ssh/ssh_known_hosts
147.Sh EXAMPLES 149.Sh EXAMPLES
148Print the 150Print the rsa host key for machine
149.Pa rsa 151.Ar hostname :
150host key for machine
151.Pa hostname :
152.Bd -literal 152.Bd -literal
153$ ssh-keyscan hostname 153$ ssh-keyscan hostname
154.Ed 154.Ed
diff --git a/ssh-keysign.0 b/ssh-keysign.0
index 78a20e894..5f18b54e3 100644
--- a/ssh-keysign.0
+++ b/ssh-keysign.0
@@ -50,4 +50,4 @@ HISTORY
50AUTHORS 50AUTHORS
51 Markus Friedl <markus@openbsd.org> 51 Markus Friedl <markus@openbsd.org>
52 52
53OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 53OpenBSD 5.5 December 7, 2013 OpenBSD 5.5
diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0
index d9ea34248..20d62f7a9 100644
--- a/ssh-pkcs11-helper.0
+++ b/ssh-pkcs11-helper.0
@@ -22,4 +22,4 @@ HISTORY
22AUTHORS 22AUTHORS
23 Markus Friedl <markus@openbsd.org> 23 Markus Friedl <markus@openbsd.org>
24 24
25OpenBSD 5.4 July 16, 2013 OpenBSD 5.4 25OpenBSD 5.5 July 16, 2013 OpenBSD 5.5
diff --git a/ssh-rsa.c b/ssh-rsa.c
index a2112d033..c6f25b3ee 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-rsa.c,v 1.50 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: ssh-rsa.c,v 1.51 2014/02/02 03:44:31 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -70,7 +70,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
70 sig = xmalloc(slen); 70 sig = xmalloc(slen);
71 71
72 ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa); 72 ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
73 memset(digest, 'd', sizeof(digest)); 73 explicit_bzero(digest, sizeof(digest));
74 74
75 if (ok != 1) { 75 if (ok != 1) {
76 int ecode = ERR_get_error(); 76 int ecode = ERR_get_error();
@@ -84,7 +84,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
84 u_int diff = slen - len; 84 u_int diff = slen - len;
85 debug("slen %u > len %u", slen, len); 85 debug("slen %u > len %u", slen, len);
86 memmove(sig + diff, sig, len); 86 memmove(sig + diff, sig, len);
87 memset(sig, 0, diff); 87 explicit_bzero(sig, diff);
88 } else if (len > slen) { 88 } else if (len > slen) {
89 error("%s: slen %u slen2 %u", __func__, slen, len); 89 error("%s: slen %u slen2 %u", __func__, slen, len);
90 free(sig); 90 free(sig);
@@ -102,7 +102,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
102 memcpy(*sigp, buffer_ptr(&b), len); 102 memcpy(*sigp, buffer_ptr(&b), len);
103 } 103 }
104 buffer_free(&b); 104 buffer_free(&b);
105 memset(sig, 's', slen); 105 explicit_bzero(sig, slen);
106 free(sig); 106 free(sig);
107 107
108 return 0; 108 return 0;
@@ -161,7 +161,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
161 modlen, len); 161 modlen, len);
162 sigblob = xrealloc(sigblob, 1, modlen); 162 sigblob = xrealloc(sigblob, 1, modlen);
163 memmove(sigblob + diff, sigblob, len); 163 memmove(sigblob + diff, sigblob, len);
164 memset(sigblob, 0, diff); 164 explicit_bzero(sigblob, diff);
165 len = modlen; 165 len = modlen;
166 } 166 }
167 /* hash the data */ 167 /* hash the data */
@@ -178,8 +178,8 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
178 178
179 ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, 179 ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
180 key->rsa); 180 key->rsa);
181 memset(digest, 'd', sizeof(digest)); 181 explicit_bzero(digest, sizeof(digest));
182 memset(sigblob, 's', len); 182 explicit_bzero(sigblob, len);
183 free(sigblob); 183 free(sigblob);
184 debug("%s: signature %scorrect", __func__, (ret == 0) ? "in" : ""); 184 debug("%s: signature %scorrect", __func__, (ret == 0) ? "in" : "");
185 return ret; 185 return ret;
diff --git a/ssh.0 b/ssh.0
index 3a6a0469d..16868cfca 100644
--- a/ssh.0
+++ b/ssh.0
@@ -943,4 +943,4 @@ AUTHORS
943 created OpenSSH. Markus Friedl contributed the support for SSH protocol 943 created OpenSSH. Markus Friedl contributed the support for SSH protocol
944 versions 1.5 and 2.0. 944 versions 1.5 and 2.0.
945 945
946OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 946OpenBSD 5.5 December 7, 2013 OpenBSD 5.5
diff --git a/ssh.c b/ssh.c
index 5d5d4de4d..3e63708da 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.397 2013/12/29 05:42:16 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.401 2014/02/26 20:18:37 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
@@ -231,16 +231,26 @@ tilde_expand_paths(char **paths, u_int num_paths)
231 } 231 }
232} 232}
233 233
234/*
235 * Attempt to resolve a host name / port to a set of addresses and
236 * optionally return any CNAMEs encountered along the way.
237 * Returns NULL on failure.
238 * NB. this function must operate with a options having undefined members.
239 */
234static struct addrinfo * 240static struct addrinfo *
235resolve_host(const char *name, u_int port, int logerr, char *cname, size_t clen) 241resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
236{ 242{
237 char strport[NI_MAXSERV]; 243 char strport[NI_MAXSERV];
238 struct addrinfo hints, *res; 244 struct addrinfo hints, *res;
239 int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1; 245 int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1;
240 246
247 if (port <= 0)
248 port = default_ssh_port();
249
241 snprintf(strport, sizeof strport, "%u", port); 250 snprintf(strport, sizeof strport, "%u", port);
242 bzero(&hints, sizeof(hints)); 251 memset(&hints, 0, sizeof(hints));
243 hints.ai_family = options.address_family; 252 hints.ai_family = options.address_family == -1 ?
253 AF_UNSPEC : options.address_family;
244 hints.ai_socktype = SOCK_STREAM; 254 hints.ai_socktype = SOCK_STREAM;
245 if (cname != NULL) 255 if (cname != NULL)
246 hints.ai_flags = AI_CANONNAME; 256 hints.ai_flags = AI_CANONNAME;
@@ -265,6 +275,7 @@ resolve_host(const char *name, u_int port, int logerr, char *cname, size_t clen)
265/* 275/*
266 * Check whether the cname is a permitted replacement for the hostname 276 * Check whether the cname is a permitted replacement for the hostname
267 * and perform the replacement if it is. 277 * and perform the replacement if it is.
278 * NB. this function must operate with a options having undefined members.
268 */ 279 */
269static int 280static int
270check_follow_cname(char **namep, const char *cname) 281check_follow_cname(char **namep, const char *cname)
@@ -281,7 +292,7 @@ check_follow_cname(char **namep, const char *cname)
281 * Don't attempt to canonicalize names that will be interpreted by 292 * Don't attempt to canonicalize names that will be interpreted by
282 * a proxy unless the user specifically requests so. 293 * a proxy unless the user specifically requests so.
283 */ 294 */
284 if (options.proxy_command != NULL && 295 if (!option_clear_or_none(options.proxy_command) &&
285 options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) 296 options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
286 return 0; 297 return 0;
287 debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); 298 debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname);
@@ -305,9 +316,10 @@ check_follow_cname(char **namep, const char *cname)
305 * Attempt to resolve the supplied hostname after applying the user's 316 * Attempt to resolve the supplied hostname after applying the user's
306 * canonicalization rules. Returns the address list for the host or NULL 317 * canonicalization rules. Returns the address list for the host or NULL
307 * if no name was found after canonicalization. 318 * if no name was found after canonicalization.
319 * NB. this function must operate with a options having undefined members.
308 */ 320 */
309static struct addrinfo * 321static struct addrinfo *
310resolve_canonicalize(char **hostp, u_int port) 322resolve_canonicalize(char **hostp, int port)
311{ 323{
312 int i, ndots; 324 int i, ndots;
313 char *cp, *fullhost, cname_target[NI_MAXHOST]; 325 char *cp, *fullhost, cname_target[NI_MAXHOST];
@@ -315,13 +327,15 @@ resolve_canonicalize(char **hostp, u_int port)
315 327
316 if (options.canonicalize_hostname == SSH_CANONICALISE_NO) 328 if (options.canonicalize_hostname == SSH_CANONICALISE_NO)
317 return NULL; 329 return NULL;
330
318 /* 331 /*
319 * Don't attempt to canonicalize names that will be interpreted by 332 * Don't attempt to canonicalize names that will be interpreted by
320 * a proxy unless the user specifically requests so. 333 * a proxy unless the user specifically requests so.
321 */ 334 */
322 if (options.proxy_command != NULL && 335 if (!option_clear_or_none(options.proxy_command) &&
323 options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) 336 options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
324 return NULL; 337 return NULL;
338
325 /* Don't apply canonicalization to sufficiently-qualified hostnames */ 339 /* Don't apply canonicalization to sufficiently-qualified hostnames */
326 ndots = 0; 340 ndots = 0;
327 for (cp = *hostp; *cp != '\0'; cp++) { 341 for (cp = *hostp; *cp != '\0'; cp++) {
@@ -338,7 +352,9 @@ resolve_canonicalize(char **hostp, u_int port)
338 *cname_target = '\0'; 352 *cname_target = '\0';
339 xasprintf(&fullhost, "%s.%s.", *hostp, 353 xasprintf(&fullhost, "%s.%s.", *hostp,
340 options.canonical_domains[i]); 354 options.canonical_domains[i]);
341 if ((addrs = resolve_host(fullhost, options.port, 0, 355 debug3("%s: attempting \"%s\" => \"%s\"", __func__,
356 *hostp, fullhost);
357 if ((addrs = resolve_host(fullhost, port, 0,
342 cname_target, sizeof(cname_target))) == NULL) { 358 cname_target, sizeof(cname_target))) == NULL) {
343 free(fullhost); 359 free(fullhost);
344 continue; 360 continue;
@@ -355,11 +371,41 @@ resolve_canonicalize(char **hostp, u_int port)
355 return addrs; 371 return addrs;
356 } 372 }
357 if (!options.canonicalize_fallback_local) 373 if (!options.canonicalize_fallback_local)
358 fatal("%s: Could not resolve host \"%s\"", __progname, host); 374 fatal("%s: Could not resolve host \"%s\"", __progname, *hostp);
375 debug2("%s: host %s not found in any suffix", __func__, *hostp);
359 return NULL; 376 return NULL;
360} 377}
361 378
362/* 379/*
380 * Read per-user configuration file. Ignore the system wide config
381 * file if the user specifies a config file on the command line.
382 */
383static void
384process_config_files(struct passwd *pw)
385{
386 char buf[MAXPATHLEN];
387 int r;
388
389 if (config != NULL) {
390 if (strcasecmp(config, "none") != 0 &&
391 !read_config_file(config, pw, host, &options,
392 SSHCONF_USERCONF))
393 fatal("Can't open user config file %.100s: "
394 "%.100s", config, strerror(errno));
395 } else {
396 r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
397 _PATH_SSH_USER_CONFFILE);
398 if (r > 0 && (size_t)r < sizeof(buf))
399 (void)read_config_file(buf, pw, host, &options,
400 SSHCONF_CHECKPERM|SSHCONF_USERCONF);
401
402 /* Read systemwide configuration file after user config. */
403 (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host,
404 &options, 0);
405 }
406}
407
408/*
363 * Main program for the ssh client. 409 * Main program for the ssh client.
364 */ 410 */
365int 411int
@@ -832,31 +878,62 @@ main(int ac, char **av)
832 if (debug_flag) 878 if (debug_flag)
833 logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); 879 logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
834 880
881 /* Parse the configuration files */
882 process_config_files(pw);
883
884 /* Hostname canonicalisation needs a few options filled. */
885 fill_default_options_for_canonicalization(&options);
886
887 /* If the user has replaced the hostname then take it into use now */
888 if (options.hostname != NULL) {
889 /* NB. Please keep in sync with readconf.c:match_cfg_line() */
890 cp = percent_expand(options.hostname,
891 "h", host, (char *)NULL);
892 free(host);
893 host = cp;
894 }
895
896 /* If canonicalization requested then try to apply it */
897 lowercase(host);
898 if (options.canonicalize_hostname != SSH_CANONICALISE_NO)
899 addrs = resolve_canonicalize(&host, options.port);
900
835 /* 901 /*
836 * Read per-user configuration file. Ignore the system wide config 902 * If CanonicalizePermittedCNAMEs have been specified but
837 * file if the user specifies a config file on the command line. 903 * other canonicalization did not happen (by not being requested
904 * or by failing with fallback) then the hostname may still be changed
905 * as a result of CNAME following.
906 *
907 * Try to resolve the bare hostname name using the system resolver's
908 * usual search rules and then apply the CNAME follow rules.
909 *
910 * Skip the lookup if a ProxyCommand is being used unless the user
911 * has specifically requested canonicalisation for this case via
912 * CanonicalizeHostname=always
838 */ 913 */
839 if (config != NULL) { 914 if (addrs == NULL && options.num_permitted_cnames != 0 &&
840 if (strcasecmp(config, "none") != 0 && 915 (option_clear_or_none(options.proxy_command) ||
841 !read_config_file(config, pw, host, &options, 916 options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) {
842 SSHCONF_USERCONF)) 917 if ((addrs = resolve_host(host, options.port, 1,
843 fatal("Can't open user config file %.100s: " 918 cname, sizeof(cname))) == NULL)
844 "%.100s", config, strerror(errno)); 919 cleanup_exit(255); /* resolve_host logs the error */
845 } else { 920 check_follow_cname(&host, cname);
846 r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, 921 }
847 _PATH_SSH_USER_CONFFILE);
848 if (r > 0 && (size_t)r < sizeof(buf))
849 (void)read_config_file(buf, pw, host, &options,
850 SSHCONF_CHECKPERM|SSHCONF_USERCONF);
851 922
852 /* Read systemwide configuration file after user config. */ 923 /*
853 (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, 924 * If the target hostname has changed as a result of canonicalisation
854 &options, 0); 925 * then re-parse the configuration files as new stanzas may match.
926 */
927 if (strcasecmp(host_arg, host) != 0) {
928 debug("Hostname has changed; re-reading configuration");
929 process_config_files(pw);
855 } 930 }
856 931
857 /* Fill configuration defaults. */ 932 /* Fill configuration defaults. */
858 fill_default_options(&options); 933 fill_default_options(&options);
859 934
935 if (options.port == 0)
936 options.port = default_ssh_port();
860 channel_set_af(options.address_family); 937 channel_set_af(options.address_family);
861 938
862 /* Tidy and check options */ 939 /* Tidy and check options */
@@ -899,37 +976,6 @@ main(int ac, char **av)
899 if (options.user == NULL) 976 if (options.user == NULL)
900 options.user = xstrdup(pw->pw_name); 977 options.user = xstrdup(pw->pw_name);
901 978
902 /* Get default port if port has not been set. */
903 if (options.port == 0)
904 options.port = default_ssh_port();
905
906 /* preserve host name given on command line for %n expansion */
907 if (options.hostname != NULL) {
908 /* NB. Please keep in sync with readconf.c:match_cfg_line() */
909 cp = percent_expand(options.hostname,
910 "h", host, (char *)NULL);
911 free(host);
912 host = cp;
913 }
914
915 /* If canonicalization requested then try to apply it */
916 lowercase(host);
917 if (options.canonicalize_hostname != SSH_CANONICALISE_NO)
918 addrs = resolve_canonicalize(&host, options.port);
919 /*
920 * If canonicalization not requested, or if it failed then try to
921 * resolve the bare hostname name using the system resolver's usual
922 * search rules. Skip the lookup if a ProxyCommand is being used
923 * unless the user has specifically requested canonicalisation.
924 */
925 if (addrs == NULL && (options.proxy_command == NULL ||
926 options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) {
927 if ((addrs = resolve_host(host, options.port, 1,
928 cname, sizeof(cname))) == NULL)
929 cleanup_exit(255); /* resolve_host logs the error */
930 check_follow_cname(&host, cname);
931 }
932
933 if (gethostname(thishost, sizeof(thishost)) == -1) 979 if (gethostname(thishost, sizeof(thishost)) == -1)
934 fatal("gethostname: %s", strerror(errno)); 980 fatal("gethostname: %s", strerror(errno));
935 strlcpy(shorthost, thishost, sizeof(shorthost)); 981 strlcpy(shorthost, thishost, sizeof(shorthost));
@@ -962,6 +1008,16 @@ main(int ac, char **av)
962 if (options.control_path != NULL) 1008 if (options.control_path != NULL)
963 muxclient(options.control_path); 1009 muxclient(options.control_path);
964 1010
1011 /*
1012 * If hostname canonicalisation was not enabled, then we may not
1013 * have yet resolved the hostname. Do so now.
1014 */
1015 if (addrs == NULL && options.proxy_command == NULL) {
1016 if ((addrs = resolve_host(host, options.port, 1,
1017 cname, sizeof(cname))) == NULL)
1018 cleanup_exit(255); /* resolve_host logs the error */
1019 }
1020
965 timeout_ms = options.connection_timeout * 1000; 1021 timeout_ms = options.connection_timeout * 1000;
966 1022
967 /* Open a connection to the remote host. */ 1023 /* Open a connection to the remote host. */
@@ -1697,8 +1753,8 @@ load_public_identity_files(void)
1697#endif /* PKCS11 */ 1753#endif /* PKCS11 */
1698 1754
1699 n_ids = 0; 1755 n_ids = 0;
1700 bzero(identity_files, sizeof(identity_files)); 1756 memset(identity_files, 0, sizeof(identity_files));
1701 bzero(identity_keys, sizeof(identity_keys)); 1757 memset(identity_keys, 0, sizeof(identity_keys));
1702 1758
1703#ifdef ENABLE_PKCS11 1759#ifdef ENABLE_PKCS11
1704 if (options.pkcs11_provider != NULL && 1760 if (options.pkcs11_provider != NULL &&
@@ -1773,9 +1829,9 @@ load_public_identity_files(void)
1773 memcpy(options.identity_files, identity_files, sizeof(identity_files)); 1829 memcpy(options.identity_files, identity_files, sizeof(identity_files));
1774 memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); 1830 memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
1775 1831
1776 bzero(pwname, strlen(pwname)); 1832 explicit_bzero(pwname, strlen(pwname));
1777 free(pwname); 1833 free(pwname);
1778 bzero(pwdir, strlen(pwdir)); 1834 explicit_bzero(pwdir, strlen(pwdir));
1779 free(pwdir); 1835 free(pwdir);
1780} 1836}
1781 1837
diff --git a/ssh2.h b/ssh2.h
index 51a963cae..59417e612 100644
--- a/ssh2.h
+++ b/ssh2.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh2.h,v 1.14 2010/08/31 11:54:45 djm Exp $ */ 1/* $OpenBSD: ssh2.h,v 1.15 2014/01/29 06:18:35 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -115,12 +115,6 @@
115#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 115#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60
116#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 116#define SSH2_MSG_USERAUTH_INFO_REQUEST 60
117#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 117#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61
118#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1 60
119#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1 61
120#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2 62
121#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2 63
122#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM 64
123#define SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM 65
124 118
125/* connection protocol: generic */ 119/* connection protocol: generic */
126 120
diff --git a/ssh_config.0 b/ssh_config.0
index e9ac54bfc..6fbd10d61 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -128,6 +128,11 @@ DESCRIPTION
128 set to ``always'', then canonicalization is applied to proxied 128 set to ``always'', then canonicalization is applied to proxied
129 connections too. 129 connections too.
130 130
131 If this option is enabled and canonicalisation results in the
132 target hostname changing, then the configuration files are
133 processed again using the new target name to pick up any new
134 configuration in matching Host stanzas.
135
131 CanonicalizeMaxDots 136 CanonicalizeMaxDots
132 Specifies the maximum number of dot characters in a hostname 137 Specifies the maximum number of dot characters in a hostname
133 before canonicalization is disabled. The default, ``1'', allows 138 before canonicalization is disabled. The default, ``1'', allows
@@ -881,4 +886,4 @@ AUTHORS
881 created OpenSSH. Markus Friedl contributed the support for SSH protocol 886 created OpenSSH. Markus Friedl contributed the support for SSH protocol
882 versions 1.5 and 2.0. 887 versions 1.5 and 2.0.
883 888
884OpenBSD 5.4 January 19, 2014 OpenBSD 5.4 889OpenBSD 5.5 February 23, 2014 OpenBSD 5.5
diff --git a/ssh_config.5 b/ssh_config.5
index cc91a5c56..22e637265 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.184 2014/01/19 04:48:08 djm Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.185 2014/02/23 20:11:36 djm Exp $
37.Dd $Mdocdate: January 19 2014 $ 37.Dd $Mdocdate: February 23 2014 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -283,6 +283,12 @@ If
283is set to 283is set to
284.Dq always , 284.Dq always ,
285then canonicalization is applied to proxied connections too. 285then canonicalization is applied to proxied connections too.
286.Pp
287If this option is enabled and canonicalisation results in the target hostname
288changing, then the configuration files are processed again using the new
289target name to pick up any new configuration in matching
290.Cm Host
291stanzas.
286.It Cm CanonicalizeMaxDots 292.It Cm CanonicalizeMaxDots
287Specifies the maximum number of dot characters in a hostname before 293Specifies the maximum number of dot characters in a hostname before
288canonicalization is disabled. 294canonicalization is disabled.
diff --git a/sshconnect.c b/sshconnect.c
index a2fbf9e65..87c3770c0 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.244 2014/01/09 23:26:48 djm Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.246 2014/02/06 22:21:01 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
@@ -269,7 +269,7 @@ static int
269ssh_create_socket(int privileged, struct addrinfo *ai) 269ssh_create_socket(int privileged, struct addrinfo *ai)
270{ 270{
271 int sock, r, gaierr; 271 int sock, r, gaierr;
272 struct addrinfo hints, *res; 272 struct addrinfo hints, *res = NULL;
273 273
274 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 274 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
275 if (sock < 0) { 275 if (sock < 0) {
@@ -282,17 +282,19 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
282 if (options.bind_address == NULL && !privileged) 282 if (options.bind_address == NULL && !privileged)
283 return sock; 283 return sock;
284 284
285 memset(&hints, 0, sizeof(hints)); 285 if (options.bind_address) {
286 hints.ai_family = ai->ai_family; 286 memset(&hints, 0, sizeof(hints));
287 hints.ai_socktype = ai->ai_socktype; 287 hints.ai_family = ai->ai_family;
288 hints.ai_protocol = ai->ai_protocol; 288 hints.ai_socktype = ai->ai_socktype;
289 hints.ai_flags = AI_PASSIVE; 289 hints.ai_protocol = ai->ai_protocol;
290 gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); 290 hints.ai_flags = AI_PASSIVE;
291 if (gaierr) { 291 gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res);
292 error("getaddrinfo: %s: %s", options.bind_address, 292 if (gaierr) {
293 ssh_gai_strerror(gaierr)); 293 error("getaddrinfo: %s: %s", options.bind_address,
294 close(sock); 294 ssh_gai_strerror(gaierr));
295 return -1; 295 close(sock);
296 return -1;
297 }
296 } 298 }
297 /* 299 /*
298 * If we are running as root and want to connect to a privileged 300 * If we are running as root and want to connect to a privileged
@@ -300,7 +302,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
300 */ 302 */
301 if (privileged) { 303 if (privileged) {
302 PRIV_START; 304 PRIV_START;
303 r = bindresvport_sa(sock, res->ai_addr); 305 r = bindresvport_sa(sock, res ? res->ai_addr : NULL);
304 PRIV_END; 306 PRIV_END;
305 if (r < 0) { 307 if (r < 0) {
306 error("bindresvport_sa: af=%d %s", ai->ai_family, 308 error("bindresvport_sa: af=%d %s", ai->ai_family,
@@ -317,7 +319,8 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
317 return -1; 319 return -1;
318 } 320 }
319 } 321 }
320 freeaddrinfo(res); 322 if (res != NULL)
323 freeaddrinfo(res);
321 return sock; 324 return sock;
322} 325}
323 326
@@ -1304,7 +1307,7 @@ ssh_put_password(char *password)
1304 padded = xcalloc(1, size); 1307 padded = xcalloc(1, size);
1305 strlcpy(padded, password, size); 1308 strlcpy(padded, password, size);
1306 packet_put_string(padded, size); 1309 packet_put_string(padded, size);
1307 memset(padded, 0, size); 1310 explicit_bzero(padded, size);
1308 free(padded); 1311 free(padded);
1309} 1312}
1310 1313
diff --git a/sshconnect1.c b/sshconnect1.c
index 7bd6cb018..921408ec1 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect1.c,v 1.72 2013/09/02 22:00:34 deraadt Exp $ */ 1/* $OpenBSD: sshconnect1.c,v 1.74 2014/02/02 03:44:32 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
@@ -19,7 +19,6 @@
19#include <sys/socket.h> 19#include <sys/socket.h>
20 20
21#include <openssl/bn.h> 21#include <openssl/bn.h>
22#include <openssl/md5.h>
23 22
24#include <stdarg.h> 23#include <stdarg.h>
25#include <stdio.h> 24#include <stdio.h>
@@ -47,6 +46,7 @@
47#include "canohost.h" 46#include "canohost.h"
48#include "hostfile.h" 47#include "hostfile.h"
49#include "auth.h" 48#include "auth.h"
49#include "digest.h"
50 50
51/* Session id for the current session. */ 51/* Session id for the current session. */
52u_char session_id[16]; 52u_char session_id[16];
@@ -120,7 +120,7 @@ try_agent_authentication(void)
120 * return a wrong value. 120 * return a wrong value.
121 */ 121 */
122 logit("Authentication agent failed to decrypt challenge."); 122 logit("Authentication agent failed to decrypt challenge.");
123 memset(response, 0, sizeof(response)); 123 explicit_bzero(response, sizeof(response));
124 } 124 }
125 key_free(key); 125 key_free(key);
126 debug("Sending response to RSA challenge."); 126 debug("Sending response to RSA challenge.");
@@ -161,7 +161,7 @@ static void
161respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) 161respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
162{ 162{
163 u_char buf[32], response[16]; 163 u_char buf[32], response[16];
164 MD5_CTX md; 164 struct ssh_digest_ctx *md;
165 int i, len; 165 int i, len;
166 166
167 /* Decrypt the challenge using the private key. */ 167 /* Decrypt the challenge using the private key. */
@@ -179,10 +179,12 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
179 179
180 memset(buf, 0, sizeof(buf)); 180 memset(buf, 0, sizeof(buf));
181 BN_bn2bin(challenge, buf + sizeof(buf) - len); 181 BN_bn2bin(challenge, buf + sizeof(buf) - len);
182 MD5_Init(&md); 182 if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
183 MD5_Update(&md, buf, 32); 183 ssh_digest_update(md, buf, 32) < 0 ||
184 MD5_Update(&md, session_id, 16); 184 ssh_digest_update(md, session_id, 16) < 0 ||
185 MD5_Final(response, &md); 185 ssh_digest_final(md, response, sizeof(response)) < 0)
186 fatal("%s: md5 failed", __func__);
187 ssh_digest_free(md);
186 188
187 debug("Sending response to host key RSA challenge."); 189 debug("Sending response to host key RSA challenge.");
188 190
@@ -193,9 +195,9 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
193 packet_send(); 195 packet_send();
194 packet_write_wait(); 196 packet_write_wait();
195 197
196 memset(buf, 0, sizeof(buf)); 198 explicit_bzero(buf, sizeof(buf));
197 memset(response, 0, sizeof(response)); 199 explicit_bzero(response, sizeof(response));
198 memset(&md, 0, sizeof(md)); 200 explicit_bzero(&md, sizeof(md));
199} 201}
200 202
201/* 203/*
@@ -269,7 +271,7 @@ try_rsa_authentication(int idx)
269 debug2("no passphrase given, try next key"); 271 debug2("no passphrase given, try next key");
270 quit = 1; 272 quit = 1;
271 } 273 }
272 memset(passphrase, 0, strlen(passphrase)); 274 explicit_bzero(passphrase, strlen(passphrase));
273 free(passphrase); 275 free(passphrase);
274 if (private != NULL || quit) 276 if (private != NULL || quit)
275 break; 277 break;
@@ -425,7 +427,7 @@ try_challenge_response_authentication(void)
425 } 427 }
426 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); 428 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
427 ssh_put_password(response); 429 ssh_put_password(response);
428 memset(response, 0, strlen(response)); 430 explicit_bzero(response, strlen(response));
429 free(response); 431 free(response);
430 packet_send(); 432 packet_send();
431 packet_write_wait(); 433 packet_write_wait();
@@ -458,7 +460,7 @@ try_password_authentication(char *prompt)
458 password = read_passphrase(prompt, 0); 460 password = read_passphrase(prompt, 0);
459 packet_start(SSH_CMSG_AUTH_PASSWORD); 461 packet_start(SSH_CMSG_AUTH_PASSWORD);
460 ssh_put_password(password); 462 ssh_put_password(password);
461 memset(password, 0, strlen(password)); 463 explicit_bzero(password, strlen(password));
462 free(password); 464 free(password);
463 packet_send(); 465 packet_send();
464 packet_write_wait(); 466 packet_write_wait();
@@ -650,8 +652,11 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
650 /* Set the encryption key. */ 652 /* Set the encryption key. */
651 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); 653 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
652 654
653 /* We will no longer need the session key here. Destroy any extra copies. */ 655 /*
654 memset(session_key, 0, sizeof(session_key)); 656 * We will no longer need the session key here.
657 * Destroy any extra copies.
658 */
659 explicit_bzero(session_key, sizeof(session_key));
655 660
656 /* 661 /*
657 * Expect a success message from the server. Note that this message 662 * Expect a success message from the server. Note that this message
diff --git a/sshconnect2.c b/sshconnect2.c
index 21a269d3c..66cb03527 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.201 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.204 2014/02/02 03:44:32 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.
@@ -70,8 +70,6 @@
70#include "pathnames.h" 70#include "pathnames.h"
71#include "uidswap.h" 71#include "uidswap.h"
72#include "hostfile.h" 72#include "hostfile.h"
73#include "schnorr.h"
74#include "jpake.h"
75 73
76#ifdef GSSAPI 74#ifdef GSSAPI
77#include "ssh-gss.h" 75#include "ssh-gss.h"
@@ -345,18 +343,12 @@ void input_userauth_error(int, u_int32_t, void *);
345void input_userauth_info_req(int, u_int32_t, void *); 343void input_userauth_info_req(int, u_int32_t, void *);
346void input_userauth_pk_ok(int, u_int32_t, void *); 344void input_userauth_pk_ok(int, u_int32_t, void *);
347void input_userauth_passwd_changereq(int, u_int32_t, void *); 345void input_userauth_passwd_changereq(int, u_int32_t, void *);
348void input_userauth_jpake_server_step1(int, u_int32_t, void *);
349void input_userauth_jpake_server_step2(int, u_int32_t, void *);
350void input_userauth_jpake_server_confirm(int, u_int32_t, void *);
351 346
352int userauth_none(Authctxt *); 347int userauth_none(Authctxt *);
353int userauth_pubkey(Authctxt *); 348int userauth_pubkey(Authctxt *);
354int userauth_passwd(Authctxt *); 349int userauth_passwd(Authctxt *);
355int userauth_kbdint(Authctxt *); 350int userauth_kbdint(Authctxt *);
356int userauth_hostbased(Authctxt *); 351int userauth_hostbased(Authctxt *);
357int userauth_jpake(Authctxt *);
358
359void userauth_jpake_cleanup(Authctxt *);
360 352
361#ifdef GSSAPI 353#ifdef GSSAPI
362int userauth_gssapi(Authctxt *authctxt); 354int userauth_gssapi(Authctxt *authctxt);
@@ -402,13 +394,6 @@ Authmethod authmethods[] = {
402 NULL, 394 NULL,
403 &options.pubkey_authentication, 395 &options.pubkey_authentication,
404 NULL}, 396 NULL},
405#ifdef JPAKE
406 {"jpake-01@openssh.com",
407 userauth_jpake,
408 userauth_jpake_cleanup,
409 &options.zero_knowledge_password_authentication,
410 &options.batch_mode},
411#endif
412 {"keyboard-interactive", 397 {"keyboard-interactive",
413 userauth_kbdint, 398 userauth_kbdint,
414 NULL, 399 NULL,
@@ -1000,7 +985,7 @@ userauth_passwd(Authctxt *authctxt)
1000 packet_put_cstring(authctxt->method->name); 985 packet_put_cstring(authctxt->method->name);
1001 packet_put_char(0); 986 packet_put_char(0);
1002 packet_put_cstring(password); 987 packet_put_cstring(password);
1003 memset(password, 0, strlen(password)); 988 explicit_bzero(password, strlen(password));
1004 free(password); 989 free(password);
1005 packet_add_padding(64); 990 packet_add_padding(64);
1006 packet_send(); 991 packet_send();
@@ -1046,7 +1031,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
1046 authctxt->server_user, host); 1031 authctxt->server_user, host);
1047 password = read_passphrase(prompt, 0); 1032 password = read_passphrase(prompt, 0);
1048 packet_put_cstring(password); 1033 packet_put_cstring(password);
1049 memset(password, 0, strlen(password)); 1034 explicit_bzero(password, strlen(password));
1050 free(password); 1035 free(password);
1051 password = NULL; 1036 password = NULL;
1052 while (password == NULL) { 1037 while (password == NULL) {
@@ -1063,16 +1048,16 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
1063 authctxt->server_user, host); 1048 authctxt->server_user, host);
1064 retype = read_passphrase(prompt, 0); 1049 retype = read_passphrase(prompt, 0);
1065 if (strcmp(password, retype) != 0) { 1050 if (strcmp(password, retype) != 0) {
1066 memset(password, 0, strlen(password)); 1051 explicit_bzero(password, strlen(password));
1067 free(password); 1052 free(password);
1068 logit("Mismatch; try again, EOF to quit."); 1053 logit("Mismatch; try again, EOF to quit.");
1069 password = NULL; 1054 password = NULL;
1070 } 1055 }
1071 memset(retype, 0, strlen(retype)); 1056 explicit_bzero(retype, strlen(retype));
1072 free(retype); 1057 free(retype);
1073 } 1058 }
1074 packet_put_cstring(password); 1059 packet_put_cstring(password);
1075 memset(password, 0, strlen(password)); 1060 explicit_bzero(password, strlen(password));
1076 free(password); 1061 free(password);
1077 packet_add_padding(64); 1062 packet_add_padding(64);
1078 packet_send(); 1063 packet_send();
@@ -1081,209 +1066,6 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
1081 &input_userauth_passwd_changereq); 1066 &input_userauth_passwd_changereq);
1082} 1067}
1083 1068
1084#ifdef JPAKE
1085static char *
1086pw_encrypt(const char *password, const char *crypt_scheme, const char *salt)
1087{
1088 /* OpenBSD crypt(3) handles all of these */
1089 if (strcmp(crypt_scheme, "crypt") == 0 ||
1090 strcmp(crypt_scheme, "bcrypt") == 0 ||
1091 strcmp(crypt_scheme, "md5crypt") == 0 ||
1092 strcmp(crypt_scheme, "crypt-extended") == 0)
1093 return xstrdup(crypt(password, salt));
1094 error("%s: unsupported password encryption scheme \"%.100s\"",
1095 __func__, crypt_scheme);
1096 return NULL;
1097}
1098
1099static BIGNUM *
1100jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
1101 const char *salt)
1102{
1103 char prompt[256], *password, *crypted;
1104 u_char *secret;
1105 u_int secret_len;
1106 BIGNUM *ret;
1107
1108 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",
1109 authctxt->server_user, authctxt->host);
1110 password = read_passphrase(prompt, 0);
1111
1112 if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) {
1113 logit("Disabling %s authentication", authctxt->method->name);
1114 authctxt->method->enabled = NULL;
1115 /* Continue with an empty password to fail gracefully */
1116 crypted = xstrdup("");
1117 }
1118
1119#ifdef JPAKE_DEBUG
1120 debug3("%s: salt = %s", __func__, salt);
1121 debug3("%s: scheme = %s", __func__, crypt_scheme);
1122 debug3("%s: crypted = %s", __func__, crypted);
1123#endif
1124
1125 if (hash_buffer(crypted, strlen(crypted), SSH_DIGEST_SHA1,
1126 &secret, &secret_len) != 0)
1127 fatal("%s: hash_buffer", __func__);
1128
1129 bzero(password, strlen(password));
1130 bzero(crypted, strlen(crypted));
1131 free(password);
1132 free(crypted);
1133
1134 if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL)
1135 fatal("%s: BN_bin2bn (secret)", __func__);
1136 bzero(secret, secret_len);
1137 free(secret);
1138
1139 return ret;
1140}
1141
1142/* ARGSUSED */
1143void
1144input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt)
1145{
1146 Authctxt *authctxt = ctxt;
1147 struct jpake_ctx *pctx = authctxt->methoddata;
1148 u_char *x3_proof, *x4_proof, *x2_s_proof;
1149 u_int x3_proof_len, x4_proof_len, x2_s_proof_len;
1150 char *crypt_scheme, *salt;
1151
1152 /* Disable this message */
1153 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL);
1154
1155 if ((pctx->g_x3 = BN_new()) == NULL ||
1156 (pctx->g_x4 = BN_new()) == NULL)
1157 fatal("%s: BN_new", __func__);
1158
1159 /* Fetch step 1 values */
1160 crypt_scheme = packet_get_string(NULL);
1161 salt = packet_get_string(NULL);
1162 pctx->server_id = packet_get_string(&pctx->server_id_len);
1163 packet_get_bignum2(pctx->g_x3);
1164 packet_get_bignum2(pctx->g_x4);
1165 x3_proof = packet_get_string(&x3_proof_len);
1166 x4_proof = packet_get_string(&x4_proof_len);
1167 packet_check_eom();
1168
1169 JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));
1170
1171 /* Obtain password and derive secret */
1172 pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt);
1173 bzero(crypt_scheme, strlen(crypt_scheme));
1174 bzero(salt, strlen(salt));
1175 free(crypt_scheme);
1176 free(salt);
1177 JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__));
1178
1179 /* Calculate step 2 values */
1180 jpake_step2(pctx->grp, pctx->s, pctx->g_x1,
1181 pctx->g_x3, pctx->g_x4, pctx->x2,
1182 pctx->server_id, pctx->server_id_len,
1183 pctx->client_id, pctx->client_id_len,
1184 x3_proof, x3_proof_len,
1185 x4_proof, x4_proof_len,
1186 &pctx->a,
1187 &x2_s_proof, &x2_s_proof_len);
1188
1189 bzero(x3_proof, x3_proof_len);
1190 bzero(x4_proof, x4_proof_len);
1191 free(x3_proof);
1192 free(x4_proof);
1193
1194 JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));
1195
1196 /* Send values for step 2 */
1197 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2);
1198 packet_put_bignum2(pctx->a);
1199 packet_put_string(x2_s_proof, x2_s_proof_len);
1200 packet_send();
1201
1202 bzero(x2_s_proof, x2_s_proof_len);
1203 free(x2_s_proof);
1204
1205 /* Expect step 2 packet from peer */
1206 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2,
1207 input_userauth_jpake_server_step2);
1208}
1209
1210/* ARGSUSED */
1211void
1212input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt)
1213{
1214 Authctxt *authctxt = ctxt;
1215 struct jpake_ctx *pctx = authctxt->methoddata;
1216 u_char *x4_s_proof;
1217 u_int x4_s_proof_len;
1218
1219 /* Disable this message */
1220 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL);
1221
1222 if ((pctx->b = BN_new()) == NULL)
1223 fatal("%s: BN_new", __func__);
1224
1225 /* Fetch step 2 values */
1226 packet_get_bignum2(pctx->b);
1227 x4_s_proof = packet_get_string(&x4_s_proof_len);
1228 packet_check_eom();
1229
1230 JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));
1231
1232 /* Derive shared key and calculate confirmation hash */
1233 jpake_key_confirm(pctx->grp, pctx->s, pctx->b,
1234 pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4,
1235 pctx->client_id, pctx->client_id_len,
1236 pctx->server_id, pctx->server_id_len,
1237 session_id2, session_id2_len,
1238 x4_s_proof, x4_s_proof_len,
1239 &pctx->k,
1240 &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len);
1241
1242 bzero(x4_s_proof, x4_s_proof_len);
1243 free(x4_s_proof);
1244
1245 JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));
1246
1247 /* Send key confirmation proof */
1248 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM);
1249 packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
1250 packet_send();
1251
1252 /* Expect confirmation from peer */
1253 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM,
1254 input_userauth_jpake_server_confirm);
1255}
1256
1257/* ARGSUSED */
1258void
1259input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt)
1260{
1261 Authctxt *authctxt = ctxt;
1262 struct jpake_ctx *pctx = authctxt->methoddata;
1263
1264 /* Disable this message */
1265 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL);
1266
1267 pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len);
1268 packet_check_eom();
1269
1270 JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));
1271
1272 /* Verify expected confirmation hash */
1273 if (jpake_check_confirm(pctx->k,
1274 pctx->server_id, pctx->server_id_len,
1275 session_id2, session_id2_len,
1276 pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1)
1277 debug("%s: %s success", __func__, authctxt->method->name);
1278 else {
1279 debug("%s: confirmation mismatch", __func__);
1280 /* XXX stash this so if auth succeeds then we can warn/kill */
1281 }
1282
1283 userauth_jpake_cleanup(authctxt);
1284}
1285#endif /* JPAKE */
1286
1287static int 1069static int
1288identity_sign(Identity *id, u_char **sigp, u_int *lenp, 1070identity_sign(Identity *id, u_char **sigp, u_int *lenp,
1289 u_char *data, u_int datalen) 1071 u_char *data, u_int datalen)
@@ -1460,7 +1242,7 @@ load_identity_file(char *filename, int userprovided)
1460 debug2("no passphrase given, try next key"); 1242 debug2("no passphrase given, try next key");
1461 quit = 1; 1243 quit = 1;
1462 } 1244 }
1463 memset(passphrase, 0, strlen(passphrase)); 1245 explicit_bzero(passphrase, strlen(passphrase));
1464 free(passphrase); 1246 free(passphrase);
1465 if (private != NULL || quit) 1247 if (private != NULL || quit)
1466 break; 1248 break;
@@ -1524,7 +1306,7 @@ pubkey_prepare(Authctxt *authctxt)
1524 /* If IdentitiesOnly set and key not found then don't use it */ 1306 /* If IdentitiesOnly set and key not found then don't use it */
1525 if (!found && options.identities_only) { 1307 if (!found && options.identities_only) {
1526 TAILQ_REMOVE(&files, id, next); 1308 TAILQ_REMOVE(&files, id, next);
1527 bzero(id, sizeof(*id)); 1309 explicit_bzero(id, sizeof(*id));
1528 free(id); 1310 free(id);
1529 } 1311 }
1530 } 1312 }
@@ -1719,7 +1501,7 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
1719 response = read_passphrase(prompt, echo ? RP_ECHO : 0); 1501 response = read_passphrase(prompt, echo ? RP_ECHO : 0);
1720 1502
1721 packet_put_cstring(response); 1503 packet_put_cstring(response);
1722 memset(response, 0, strlen(response)); 1504 explicit_bzero(response, strlen(response));
1723 free(response); 1505 free(response);
1724 free(prompt); 1506 free(prompt);
1725 } 1507 }
@@ -1889,7 +1671,7 @@ userauth_hostbased(Authctxt *authctxt)
1889 packet_put_cstring(chost); 1671 packet_put_cstring(chost);
1890 packet_put_cstring(authctxt->local_user); 1672 packet_put_cstring(authctxt->local_user);
1891 packet_put_string(signature, slen); 1673 packet_put_string(signature, slen);
1892 memset(signature, 's', slen); 1674 explicit_bzero(signature, slen);
1893 free(signature); 1675 free(signature);
1894 free(chost); 1676 free(chost);
1895 free(pkalg); 1677 free(pkalg);
@@ -1899,79 +1681,6 @@ userauth_hostbased(Authctxt *authctxt)
1899 return 1; 1681 return 1;
1900} 1682}
1901 1683
1902#ifdef JPAKE
1903int
1904userauth_jpake(Authctxt *authctxt)
1905{
1906 struct jpake_ctx *pctx;
1907 u_char *x1_proof, *x2_proof;
1908 u_int x1_proof_len, x2_proof_len;
1909 static int attempt = 0; /* XXX share with userauth_password's? */
1910
1911 if (attempt++ >= options.number_of_password_prompts)
1912 return 0;
1913 if (attempt != 1)
1914 error("Permission denied, please try again.");
1915
1916 if (authctxt->methoddata != NULL)
1917 fatal("%s: authctxt->methoddata already set (%p)",
1918 __func__, authctxt->methoddata);
1919
1920 authctxt->methoddata = pctx = jpake_new();
1921
1922 /*
1923 * Send request immediately, to get the protocol going while
1924 * we do the initial computations.
1925 */
1926 packet_start(SSH2_MSG_USERAUTH_REQUEST);
1927 packet_put_cstring(authctxt->server_user);
1928 packet_put_cstring(authctxt->service);
1929 packet_put_cstring(authctxt->method->name);
1930 packet_send();
1931 packet_write_wait();
1932
1933 jpake_step1(pctx->grp,
1934 &pctx->client_id, &pctx->client_id_len,
1935 &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2,
1936 &x1_proof, &x1_proof_len,
1937 &x2_proof, &x2_proof_len);
1938
1939 JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));
1940
1941 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1);
1942 packet_put_string(pctx->client_id, pctx->client_id_len);
1943 packet_put_bignum2(pctx->g_x1);
1944 packet_put_bignum2(pctx->g_x2);
1945 packet_put_string(x1_proof, x1_proof_len);
1946 packet_put_string(x2_proof, x2_proof_len);
1947 packet_send();
1948
1949 bzero(x1_proof, x1_proof_len);
1950 bzero(x2_proof, x2_proof_len);
1951 free(x1_proof);
1952 free(x2_proof);
1953
1954 /* Expect step 1 packet from peer */
1955 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,
1956 input_userauth_jpake_server_step1);
1957 dispatch_set(SSH2_MSG_USERAUTH_SUCCESS,
1958 &input_userauth_success_unexpected);
1959
1960 return 1;
1961}
1962
1963void
1964userauth_jpake_cleanup(Authctxt *authctxt)
1965{
1966 debug3("%s: clean up", __func__);
1967 if (authctxt->methoddata != NULL) {
1968 jpake_free(authctxt->methoddata);
1969 authctxt->methoddata = NULL;
1970 }
1971 dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
1972}
1973#endif /* JPAKE */
1974
1975/* find auth method */ 1684/* find auth method */
1976 1685
1977/* 1686/*
diff --git a/sshd.0 b/sshd.0
index 154009c9f..c61d51535 100644
--- a/sshd.0
+++ b/sshd.0
@@ -640,4 +640,4 @@ CAVEATS
640 System security is not improved unless rshd, rlogind, and rexecd are 640 System security is not improved unless rshd, rlogind, and rexecd are
641 disabled (thus completely disabling rlogin and rsh into the machine). 641 disabled (thus completely disabling rlogin and rsh into the machine).
642 642
643OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 643OpenBSD 5.5 December 7, 2013 OpenBSD 5.5
diff --git a/sshd.c b/sshd.c
index 23e8c2de0..ffe360c62 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.414 2014/01/09 23:26:48 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.420 2014/02/26 21:53:37 markus 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
@@ -74,7 +74,6 @@
74 74
75#include <openssl/dh.h> 75#include <openssl/dh.h>
76#include <openssl/bn.h> 76#include <openssl/bn.h>
77#include <openssl/md5.h>
78#include <openssl/rand.h> 77#include <openssl/rand.h>
79#include "openbsd-compat/openssl-compat.h" 78#include "openbsd-compat/openssl-compat.h"
80 79
@@ -96,6 +95,7 @@
96#include "uidswap.h" 95#include "uidswap.h"
97#include "compat.h" 96#include "compat.h"
98#include "cipher.h" 97#include "cipher.h"
98#include "digest.h"
99#include "key.h" 99#include "key.h"
100#include "kex.h" 100#include "kex.h"
101#include "dh.h" 101#include "dh.h"
@@ -584,7 +584,7 @@ destroy_sensitive_data(void)
584 } 584 }
585 } 585 }
586 sensitive_data.ssh1_host_key = NULL; 586 sensitive_data.ssh1_host_key = NULL;
587 memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); 587 explicit_bzero(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
588} 588}
589 589
590/* Demote private to public keys for network child */ 590/* Demote private to public keys for network child */
@@ -623,10 +623,16 @@ privsep_preauth_child(void)
623 /* Enable challenge-response authentication for privilege separation */ 623 /* Enable challenge-response authentication for privilege separation */
624 privsep_challenge_enable(); 624 privsep_challenge_enable();
625 625
626#ifdef GSSAPI
627 /* Cache supported mechanism OIDs for later use */
628 if (options.gss_authentication)
629 ssh_gssapi_prepare_supported_oids();
630#endif
631
626 arc4random_stir(); 632 arc4random_stir();
627 arc4random_buf(rnd, sizeof(rnd)); 633 arc4random_buf(rnd, sizeof(rnd));
628 RAND_seed(rnd, sizeof(rnd)); 634 RAND_seed(rnd, sizeof(rnd));
629 bzero(rnd, sizeof(rnd)); 635 explicit_bzero(rnd, sizeof(rnd));
630 636
631 /* Demote the private keys to public keys. */ 637 /* Demote the private keys to public keys. */
632 demote_sensitive_data(); 638 demote_sensitive_data();
@@ -761,7 +767,7 @@ privsep_postauth(Authctxt *authctxt)
761 arc4random_stir(); 767 arc4random_stir();
762 arc4random_buf(rnd, sizeof(rnd)); 768 arc4random_buf(rnd, sizeof(rnd));
763 RAND_seed(rnd, sizeof(rnd)); 769 RAND_seed(rnd, sizeof(rnd));
764 bzero(rnd, sizeof(rnd)); 770 explicit_bzero(rnd, sizeof(rnd));
765 771
766 /* Drop privileges */ 772 /* Drop privileges */
767 do_setusercontext(authctxt->pw, authctxt->role); 773 do_setusercontext(authctxt->pw, authctxt->role);
@@ -1360,7 +1366,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1360 arc4random_stir(); 1366 arc4random_stir();
1361 arc4random_buf(rnd, sizeof(rnd)); 1367 arc4random_buf(rnd, sizeof(rnd));
1362 RAND_seed(rnd, sizeof(rnd)); 1368 RAND_seed(rnd, sizeof(rnd));
1363 bzero(rnd, sizeof(rnd)); 1369 explicit_bzero(rnd, sizeof(rnd));
1364 } 1370 }
1365 1371
1366 /* child process check (or debug mode) */ 1372 /* child process check (or debug mode) */
@@ -1662,7 +1668,8 @@ main(int ac, char **av)
1662 fatal("Privilege separation user %s does not exist", 1668 fatal("Privilege separation user %s does not exist",
1663 SSH_PRIVSEP_USER); 1669 SSH_PRIVSEP_USER);
1664 } else { 1670 } else {
1665 memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd)); 1671 explicit_bzero(privsep_pw->pw_passwd,
1672 strlen(privsep_pw->pw_passwd));
1666 privsep_pw = pwcopy(privsep_pw); 1673 privsep_pw = pwcopy(privsep_pw);
1667 free(privsep_pw->pw_passwd); 1674 free(privsep_pw->pw_passwd);
1668 privsep_pw->pw_passwd = xstrdup("*"); 1675 privsep_pw->pw_passwd = xstrdup("*");
@@ -2407,7 +2414,7 @@ do_ssh1_kex(void)
2407 get_remote_ipaddr(), len, (u_long)sizeof(session_key)); 2414 get_remote_ipaddr(), len, (u_long)sizeof(session_key));
2408 rsafail++; 2415 rsafail++;
2409 } else { 2416 } else {
2410 memset(session_key, 0, sizeof(session_key)); 2417 explicit_bzero(session_key, sizeof(session_key));
2411 BN_bn2bin(session_key_int, 2418 BN_bn2bin(session_key_int,
2412 session_key + sizeof(session_key) - len); 2419 session_key + sizeof(session_key) - len);
2413 2420
@@ -2426,20 +2433,26 @@ do_ssh1_kex(void)
2426 if (rsafail) { 2433 if (rsafail) {
2427 int bytes = BN_num_bytes(session_key_int); 2434 int bytes = BN_num_bytes(session_key_int);
2428 u_char *buf = xmalloc(bytes); 2435 u_char *buf = xmalloc(bytes);
2429 MD5_CTX md; 2436 struct ssh_digest_ctx *md;
2430 2437
2431 logit("do_connection: generating a fake encryption key"); 2438 logit("do_connection: generating a fake encryption key");
2432 BN_bn2bin(session_key_int, buf); 2439 BN_bn2bin(session_key_int, buf);
2433 MD5_Init(&md); 2440 if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
2434 MD5_Update(&md, buf, bytes); 2441 ssh_digest_update(md, buf, bytes) < 0 ||
2435 MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); 2442 ssh_digest_update(md, sensitive_data.ssh1_cookie,
2436 MD5_Final(session_key, &md); 2443 SSH_SESSION_KEY_LENGTH) < 0 ||
2437 MD5_Init(&md); 2444 ssh_digest_final(md, session_key, sizeof(session_key)) < 0)
2438 MD5_Update(&md, session_key, 16); 2445 fatal("%s: md5 failed", __func__);
2439 MD5_Update(&md, buf, bytes); 2446 ssh_digest_free(md);
2440 MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); 2447 if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
2441 MD5_Final(session_key + 16, &md); 2448 ssh_digest_update(md, session_key, 16) < 0 ||
2442 memset(buf, 0, bytes); 2449 ssh_digest_update(md, sensitive_data.ssh1_cookie,
2450 SSH_SESSION_KEY_LENGTH) < 0 ||
2451 ssh_digest_final(md, session_key + 16,
2452 sizeof(session_key) - 16) < 0)
2453 fatal("%s: md5 failed", __func__);
2454 ssh_digest_free(md);
2455 explicit_bzero(buf, bytes);
2443 free(buf); 2456 free(buf);
2444 for (i = 0; i < 16; i++) 2457 for (i = 0; i < 16; i++)
2445 session_id[i] = session_key[i] ^ session_key[i + 16]; 2458 session_id[i] = session_key[i] ^ session_key[i + 16];
@@ -2457,7 +2470,7 @@ do_ssh1_kex(void)
2457 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); 2470 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type);
2458 2471
2459 /* Destroy our copy of the session key. It is no longer needed. */ 2472 /* Destroy our copy of the session key. It is no longer needed. */
2460 memset(session_key, 0, sizeof(session_key)); 2473 explicit_bzero(session_key, sizeof(session_key));
2461 2474
2462 debug("Received session key; encryption turned on."); 2475 debug("Received session key; encryption turned on.");
2463 2476
diff --git a/sshd_config.0 b/sshd_config.0
index 5962b02b9..413c26008 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -374,6 +374,12 @@ DESCRIPTION
374 interactive sessions and ``throughput'' for non-interactive 374 interactive sessions and ``throughput'' for non-interactive
375 sessions. 375 sessions.
376 376
377 KbdInteractiveAuthentication
378 Specifies whether to allow keyboard-interactive authentication.
379 The argument to this keyword must be ``yes'' or ``no''. The
380 default is to use whatever value ChallengeResponseAuthentication
381 is set to (by default ``yes'').
382
377 KerberosAuthentication 383 KerberosAuthentication
378 Specifies whether the password provided by the user for 384 Specifies whether the password provided by the user for
379 PasswordAuthentication will be validated through the Kerberos 385 PasswordAuthentication will be validated through the Kerberos
@@ -460,7 +466,9 @@ DESCRIPTION
460 Match Introduces a conditional block. If all of the criteria on the 466 Match Introduces a conditional block. If all of the criteria on the
461 Match line are satisfied, the keywords on the following lines 467 Match line are satisfied, the keywords on the following lines
462 override those set in the global section of the config file, 468 override those set in the global section of the config file,
463 until either another Match line or the end of the file. 469 until either another Match line or the end of the file. If a
470 keyword appears in multiple Match blocks that are satisified,
471 only the first instance of the keyword is applied.
464 472
465 The arguments to Match are one or more criteria-pattern pairs or 473 The arguments to Match are one or more criteria-pattern pairs or
466 the single token All which matches all criteria. The available 474 the single token All which matches all criteria. The available
@@ -824,4 +832,4 @@ AUTHORS
824 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support 832 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
825 for privilege separation. 833 for privilege separation.
826 834
827OpenBSD 5.4 December 8, 2013 OpenBSD 5.4 835OpenBSD 5.5 February 27, 2014 OpenBSD 5.5
diff --git a/sshd_config.5 b/sshd_config.5
index 496530bf5..90fd3f4a8 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: sshd_config.5,v 1.170 2013/12/08 09:53:27 dtucker Exp $ 36.\" $OpenBSD: sshd_config.5,v 1.172 2014/02/27 22:47:07 djm Exp $
37.Dd $Mdocdate: December 8 2013 $ 37.Dd $Mdocdate: February 27 2014 $
38.Dt SSHD_CONFIG 5 38.Dt SSHD_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -690,6 +690,17 @@ The default is
690for interactive sessions and 690for interactive sessions and
691.Dq throughput 691.Dq throughput
692for non-interactive sessions. 692for non-interactive sessions.
693.It Cm KbdInteractiveAuthentication
694Specifies whether to allow keyboard-interactive authentication.
695The argument to this keyword must be
696.Dq yes
697or
698.Dq no .
699The default is to use whatever value
700.Cm ChallengeResponseAuthentication
701is set to
702(by default
703.Dq yes ) .
693.It Cm KerberosAuthentication 704.It Cm KerberosAuthentication
694Specifies whether the password provided by the user for 705Specifies whether the password provided by the user for
695.Cm PasswordAuthentication 706.Cm PasswordAuthentication
@@ -816,6 +827,10 @@ line are satisfied, the keywords on the following lines override those
816set in the global section of the config file, until either another 827set in the global section of the config file, until either another
817.Cm Match 828.Cm Match
818line or the end of the file. 829line or the end of the file.
830If a keyword appears in multiple
831.Cm Match
832blocks that are satisified, only the first instance of the keyword is
833applied.
819.Pp 834.Pp
820The arguments to 835The arguments to
821.Cm Match 836.Cm Match
diff --git a/sshlogin.c b/sshlogin.c
index 2688d8d7b..e79ca9b47 100644
--- a/sshlogin.c
+++ b/sshlogin.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshlogin.c,v 1.27 2011/01/11 06:06:09 djm Exp $ */ 1/* $OpenBSD: sshlogin.c,v 1.28 2014/01/31 16:39:19 tedu 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
diff --git a/version.h b/version.h
index 0c6ea0fc9..a97c337a3 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
1/* $OpenBSD: version.h,v 1.69 2014/01/16 07:32:00 djm Exp $ */ 1/* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */
2 2
3#define SSH_VERSION "OpenSSH_6.5" 3#define SSH_VERSION "OpenSSH_6.6"
4 4
5#define SSH_PORTABLE "p1" 5#define SSH_PORTABLE "p1"
6#define SSH_RELEASE_MINIMUM SSH_VERSION SSH_PORTABLE 6#define SSH_RELEASE_MINIMUM SSH_VERSION SSH_PORTABLE