summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1528
-rw-r--r--Makefile.in30
-rw-r--r--PROTOCOL243
-rw-r--r--PROTOCOL.agent516
-rw-r--r--README4
-rw-r--r--addrmatch.c421
-rw-r--r--atomicio.c20
-rw-r--r--audit-bsm.c57
-rw-r--r--auth-bsdauth.c2
-rw-r--r--auth-options.c35
-rw-r--r--auth-options.h3
-rw-r--r--auth-pam.c6
-rw-r--r--auth-passwd.c2
-rw-r--r--auth-rhosts.c26
-rw-r--r--auth-rsa.c23
-rw-r--r--auth-sia.c53
-rw-r--r--auth.c49
-rw-r--r--auth.h5
-rw-r--r--auth1.c9
-rw-r--r--auth2-chall.c2
-rw-r--r--auth2-gss.c2
-rw-r--r--auth2-hostbased.c11
-rw-r--r--auth2-none.c69
-rw-r--r--auth2-pubkey.c22
-rw-r--r--auth2.c84
-rw-r--r--bufaux.c20
-rw-r--r--buffer.h3
-rw-r--r--canohost.c9
-rw-r--r--channels.c347
-rw-r--r--channels.h52
-rw-r--r--clientloop.c755
-rw-r--r--clientloop.h19
-rw-r--r--config.h.in60
-rwxr-xr-xconfigure559
-rw-r--r--configure.ac133
-rw-r--r--contrib/caldera/openssh.spec7
-rw-r--r--contrib/cygwin/Makefile7
-rw-r--r--contrib/cygwin/ssh-host-config898
-rw-r--r--contrib/cygwin/ssh-user-config414
-rw-r--r--contrib/cygwin/sshd-inetd4
-rw-r--r--contrib/gnome-ssh-askpass2.c1
-rw-r--r--contrib/redhat/openssh.spec3
-rw-r--r--contrib/ssh-copy-id2
-rw-r--r--contrib/suse/openssh.spec5
-rw-r--r--defines.h32
-rw-r--r--dh.c25
-rw-r--r--dh.h26
-rw-r--r--dns.c13
-rw-r--r--groupaccess.c27
-rw-r--r--groupaccess.h3
-rw-r--r--gss-serv.c3
-rw-r--r--includes.h2
-rw-r--r--key.c117
-rw-r--r--key.h5
-rw-r--r--log.c24
-rw-r--r--log.h14
-rw-r--r--mac.c4
-rw-r--r--match.c12
-rw-r--r--match.h5
-rw-r--r--misc.c33
-rw-r--r--misc.h5
-rw-r--r--moduli358
-rw-r--r--moduli.072
-rw-r--r--moduli.5124
-rw-r--r--moduli.c49
-rw-r--r--monitor.c33
-rw-r--r--monitor_fdpass.c75
-rw-r--r--monitor_fdpass.h4
-rw-r--r--monitor_mm.h5
-rw-r--r--monitor_wrap.c41
-rw-r--r--mux.c728
-rw-r--r--nchan.c32
-rw-r--r--nchan2.ms6
-rw-r--r--openbsd-compat/Makefile.in6
-rw-r--r--openbsd-compat/base64.c12
-rw-r--r--openbsd-compat/bindresvport.c14
-rw-r--r--openbsd-compat/bsd-arc4random.c66
-rw-r--r--openbsd-compat/bsd-asprintf.c1
-rw-r--r--openbsd-compat/bsd-cygwin_util.c40
-rw-r--r--openbsd-compat/bsd-poll.c5
-rw-r--r--openbsd-compat/bsd-statvfs.c37
-rw-r--r--openbsd-compat/bsd-statvfs.h68
-rw-r--r--openbsd-compat/fake-rfc2553.c7
-rw-r--r--openbsd-compat/fake-rfc2553.h8
-rw-r--r--openbsd-compat/fmt_scaled.c274
-rw-r--r--openbsd-compat/getrrsetbyname.c6
-rw-r--r--openbsd-compat/getrrsetbyname.h4
-rw-r--r--openbsd-compat/glob.c15
-rw-r--r--openbsd-compat/glob.h20
-rw-r--r--openbsd-compat/openbsd-compat.h16
-rw-r--r--openbsd-compat/openssl-compat.c2
-rw-r--r--openbsd-compat/openssl-compat.h11
-rw-r--r--openbsd-compat/port-aix.c45
-rw-r--r--openbsd-compat/port-aix.h14
-rw-r--r--openbsd-compat/port-linux.c4
-rw-r--r--openbsd-compat/port-linux.h3
-rw-r--r--openbsd-compat/port-tun.c1
-rw-r--r--openbsd-compat/regress/closefromtest.c1
-rw-r--r--openbsd-compat/regress/strtonumtest.c14
-rw-r--r--openbsd-compat/rresvport.c1
-rw-r--r--openbsd-compat/setenv.c6
-rw-r--r--openbsd-compat/setproctitle.c12
-rw-r--r--openbsd-compat/sigact.c50
-rw-r--r--openbsd-compat/sys-queue.h31
-rw-r--r--openbsd-compat/sys-tree.h16
-rw-r--r--packet.c139
-rw-r--r--packet.h9
-rw-r--r--readconf.c27
-rw-r--r--readconf.h5
-rw-r--r--regress/Makefile26
-rw-r--r--regress/addrmatch.sh42
-rw-r--r--regress/agent-getpeereid.sh4
-rw-r--r--regress/agent.sh4
-rw-r--r--regress/cfgmatch.sh31
-rw-r--r--regress/cipher-speed.sh4
-rw-r--r--regress/conch-ciphers.sh30
-rw-r--r--regress/key-options.sh71
-rw-r--r--regress/localcommand.sh15
-rw-r--r--regress/putty-ciphers.sh28
-rw-r--r--regress/putty-kex.sh25
-rw-r--r--regress/putty-transfer.sh43
-rw-r--r--regress/sftp-badcmds.sh13
-rw-r--r--regress/sftp-cmds.sh60
-rw-r--r--regress/sftp-glob.sh72
-rwxr-xr-xregress/ssh2putty.sh33
-rw-r--r--regress/test-exec.sh75
-rw-r--r--regress/try-ciphers.sh4
-rw-r--r--scp.020
-rw-r--r--scp.123
-rw-r--r--scp.c116
-rw-r--r--servconf.c359
-rw-r--r--servconf.h11
-rw-r--r--serverloop.c60
-rw-r--r--session.c581
-rw-r--r--session.h4
-rw-r--r--sftp-client.c214
-rw-r--r--sftp-client.h29
-rw-r--r--sftp-server-main.c50
-rw-r--r--sftp-server.06
-rw-r--r--sftp-server.814
-rw-r--r--sftp-server.c220
-rw-r--r--sftp.016
-rw-r--r--sftp.127
-rw-r--r--sftp.c576
-rw-r--r--sftp.h11
-rw-r--r--ssh-add.02
-rw-r--r--ssh-add.c5
-rw-r--r--ssh-agent.014
-rw-r--r--ssh-agent.126
-rw-r--r--ssh-agent.c49
-rw-r--r--ssh-keygen.06
-rw-r--r--ssh-keygen.17
-rw-r--r--ssh-keygen.c97
-rw-r--r--ssh-keyscan.04
-rw-r--r--ssh-keyscan.16
-rw-r--r--ssh-keyscan.c8
-rw-r--r--ssh-keysign.02
-rw-r--r--ssh-keysign.82
-rw-r--r--ssh-rand-helper.02
-rw-r--r--ssh.048
-rw-r--r--ssh.158
-rw-r--r--ssh.c541
-rw-r--r--ssh_config.052
-rw-r--r--ssh_config.542
-rw-r--r--sshconnect.c154
-rw-r--r--sshconnect.h6
-rw-r--r--sshconnect2.c22
-rw-r--r--sshd.062
-rw-r--r--sshd.874
-rw-r--r--sshd.c158
-rw-r--r--sshd_config9
-rw-r--r--sshd_config.0101
-rw-r--r--sshd_config.5112
-rw-r--r--sshlogin.c5
-rw-r--r--sshpty.c2
-rw-r--r--sshpty.h4
-rw-r--r--sshtty.c6
-rw-r--r--ttymodes.c14
-rw-r--r--umac.c23
-rw-r--r--version.h4
180 files changed, 10781 insertions, 3250 deletions
diff --git a/ChangeLog b/ChangeLog
index 93555e518..3d08a80d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,1529 @@
120080721
2 - (djm) OpenBSD CVS Sync
3 - jmc@cvs.openbsd.org 2008/07/18 22:51:01
4 [sftp-server.8]
5 no need for .Pp before or after .Sh;
6 - djm@cvs.openbsd.org 2008/07/21 08:19:07
7 [version.h]
8 openssh-5.1
9 - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
10 [contrib/suse/openssh.spec] Update version number in README and RPM specs
11 - (djm) Release OpenSSH-5.1
12
1320080717
14 - (djm) OpenBSD CVS Sync
15 - djm@cvs.openbsd.org 2008/07/17 08:48:00
16 [sshconnect2.c]
17 strnvis preauth banner; pointed out by mpf@ ok markus@
18 - djm@cvs.openbsd.org 2008/07/17 08:51:07
19 [auth2-hostbased.c]
20 strip trailing '.' from hostname when HostbasedUsesNameFromPacketOnly=yes
21 report and patch from res AT qoxp.net (bz#1200); ok markus@
22 - (dtucker) [openbsd-compat/bsd-cygwin_util.c] Remove long-unneeded compat
23 code, replace with equivalent cygwin library call. Patch from vinschen
24 at redhat.com, ok djm@.
25 - (djm) [sshconnect2.c] vis.h isn't available everywhere
26
2720080716
28 - OpenBSD CVS Sync
29 - djm@cvs.openbsd.org 2008/07/15 02:23:14
30 [sftp.1]
31 number of pipelined requests is now 64;
32 prodded by Iain.Morgan AT nasa.gov
33 - djm@cvs.openbsd.org 2008/07/16 11:51:14
34 [clientloop.c]
35 rename variable first_gc -> last_gc (since it is actually the last
36 in the list).
37 - djm@cvs.openbsd.org 2008/07/16 11:52:19
38 [channels.c]
39 this loop index should be automatic, not static
40
4120080714
42 - (djm) OpenBSD CVS Sync
43 - sthen@cvs.openbsd.org 2008/07/13 21:22:52
44 [ssh-keygen.c]
45 Change "ssh-keygen -F [host] -l" to not display random art unless
46 -v is also specified, making it consistent with the manual and other
47 uses of -l.
48 ok grunk@
49 - djm@cvs.openbsd.org 2008/07/13 22:13:07
50 [channels.c]
51 use struct sockaddr_storage instead of struct sockaddr for accept(2)
52 address argument. from visibilis AT yahoo.com in bz#1485; ok markus@
53 - djm@cvs.openbsd.org 2008/07/13 22:16:03
54 [sftp.c]
55 increase number of piplelined requests so they properly fill the
56 (recently increased) channel window. prompted by rapier AT psc.edu;
57 ok markus@
58 - djm@cvs.openbsd.org 2008/07/14 01:55:56
59 [sftp-server.8]
60 mention requirement for /dev/log inside chroot when using sftp-server
61 with ChrootDirectory
62 - (djm) [openbsd-compat/bindresvport.c] Rename variables s/sin/in/ to
63 avoid clash with sin(3) function; reported by
64 cristian.ionescu-idbohrn AT axis.com
65 - (djm) [openbsd-compat/rresvport.c] Add unistd.h for missing close()
66 prototype; reported by cristian.ionescu-idbohrn AT axis.com
67 - (djm) [umac.c] Rename variable s/buffer_ptr/bufp/ to avoid clash;
68 reported by cristian.ionescu-idbohrn AT axis.com
69 - (djm) [contrib/cygwin/Makefile contrib/cygwin/ssh-host-config]
70 [contrib/cygwin/ssh-user-config contrib/cygwin/sshd-inetd]
71 Revamped and simplified Cygwin ssh-host-config script that uses
72 unified csih configuration tool. Requires recent Cygwin.
73 Patch from vinschen AT redhat.com
74
7520080712
76 - (djm) OpenBSD CVS Sync
77 - djm@cvs.openbsd.org 2008/07/12 04:52:50
78 [channels.c]
79 unbreak; move clearing of cctx struct to before first use
80 reported by dkrause@
81 - djm@cvs.openbsd.org 2008/07/12 05:33:41
82 [scp.1]
83 better description for -i flag:
84 s/RSA authentication/public key authentication/
85 - (djm) [openbsd-compat/fake-rfc2553.c openbsd-compat/fake-rfc2553.h]
86 return EAI_FAMILY when trying to lookup unsupported address family;
87 from vinschen AT redhat.com
88
8920080711
90 - (djm) OpenBSD CVS Sync
91 - stevesk@cvs.openbsd.org 2008/07/07 00:31:41
92 [ttymodes.c]
93 we don't need arg after the debug3() was removed. from lint.
94 ok djm@
95 - stevesk@cvs.openbsd.org 2008/07/07 23:32:51
96 [key.c]
97 /*NOTREACHED*/ for lint warning:
98 warning: function key_equal falls off bottom without returning value
99 ok djm@
100 - markus@cvs.openbsd.org 2008/07/10 18:05:58
101 [channels.c]
102 missing bzero; from mickey; ok djm@
103 - markus@cvs.openbsd.org 2008/07/10 18:08:11
104 [clientloop.c monitor.c monitor_wrap.c packet.c packet.h sshd.c]
105 sync v1 and v2 traffic accounting; add it to sshd, too;
106 ok djm@, dtucker@
107
10820080709
109 - (djm) [Makefile.in] Print "all tests passed" when all regress tests pass
110 - (djm) [auth1.c] Fix format string vulnerability in protocol 1 PAM
111 account check failure path. The vulnerable format buffer is supplied
112 from PAM and should not contain attacker-supplied data.
113 - (djm) [auth.c] Missing unistd.h for close()
114 - (djm) [configure.ac] Add -Wformat-security to CFLAGS for gcc 3.x and 4.x
115
11620080705
117 - (djm) [auth.c] Fixed test for locked account on HP/UX with shadowed
118 passwords disabled. bz#1083 report & patch from senthilkumar_sen AT
119 hotpop.com, w/ dtucker@
120 - (djm) [atomicio.c configure.ac] Disable poll() fallback in atomiciov for
121 Tru64. readv doesn't seem to be a comparable object there.
122 bz#1386, patch from dtucker@ ok me
123 - (djm) [Makefile.in] Pass though pass to conch for interop tests
124 - (djm) [configure.ac] unbreak: remove extra closing brace
125 - (djm) OpenBSD CVS Sync
126 - djm@cvs.openbsd.org 2008/07/04 23:08:25
127 [packet.c]
128 handle EINTR in packet_write_poll()l ok dtucker@
129 - djm@cvs.openbsd.org 2008/07/04 23:30:16
130 [auth1.c auth2.c]
131 Make protocol 1 MaxAuthTries logic match protocol 2's.
132 Do not treat the first protocol 2 authentication attempt as
133 a failure IFF it is for method "none".
134 Makes MaxAuthTries' user-visible behaviour identical for
135 protocol 1 vs 2.
136 ok dtucker@
137 - djm@cvs.openbsd.org 2008/07/05 05:16:01
138 [PROTOCOL]
139 grammar
140
14120080704
142 - (dtucker) OpenBSD CVS Sync
143 - djm@cvs.openbsd.org 2008/07/02 13:30:34
144 [auth2.c]
145 really really remove the freebie "none" auth try for protocol 2
146 - djm@cvs.openbsd.org 2008/07/02 13:47:39
147 [ssh.1 ssh.c]
148 When forking after authentication ("ssh -f") with ExitOnForwardFailure
149 enabled, delay the fork until after replies for any -R forwards have
150 been seen. Allows for robust detection of -R forward failure when
151 using -f (similar to bz#92); ok dtucker@
152 - otto@cvs.openbsd.org 2008/07/03 21:46:58
153 [auth2-pubkey.c]
154 avoid nasty double free; ok dtucker@ djm@
155 - djm@cvs.openbsd.org 2008/07/04 03:44:59
156 [servconf.c groupaccess.h groupaccess.c]
157 support negation of groups in "Match group" block (bz#1315); ok dtucker@
158 - dtucker@cvs.openbsd.org 2008/07/04 03:47:02
159 [monitor.c]
160 Make debug a little clearer. ok djm@
161 - djm@cvs.openbsd.org 2008/06/30 08:07:34
162 [regress/key-options.sh]
163 shell portability: use "=" instead of "==" in test(1) expressions,
164 double-quote string with backslash escaped /
165 - djm@cvs.openbsd.org 2008/06/30 10:31:11
166 [regress/{putty-transfer,putty-kex,putty-ciphers}.sh]
167 remove "set -e" left over from debugging
168 - djm@cvs.openbsd.org 2008/06/30 10:43:03
169 [regress/conch-ciphers.sh]
170 explicitly disable conch options that could interfere with the test
171 - (dtucker) [sftp-server.c] Bug #1447: fall back to racy rename if link
172 returns EXDEV. Patch from Mike Garrison, ok djm@
173 - (djm) [atomicio.c channels.c clientloop.c defines.h includes.h]
174 [packet.c scp.c serverloop.c sftp-client.c ssh-agent.c ssh-keyscan.c]
175 [sshd.c] Explicitly handle EWOULDBLOCK wherever we handle EAGAIN, on
176 some platforms (HP nonstop) it is a distinct errno;
177 bz#1467 reported by sconeu AT yahoo.com; ok dtucker@
178
17920080702
180 - (dtucker) OpenBSD CVS Sync
181 - djm@cvs.openbsd.org 2008/06/30 08:05:59
182 [PROTOCOL.agent]
183 typo: s/constraint_date/constraint_data/
184 - djm@cvs.openbsd.org 2008/06/30 12:15:39
185 [serverloop.c]
186 only pass channel requests on session channels through to the session
187 channel handler, avoiding spurious log messages; ok! markus@
188 - djm@cvs.openbsd.org 2008/06/30 12:16:02
189 [nchan.c]
190 only send eow@openssh.com notifications for session channels; ok! markus@
191 - djm@cvs.openbsd.org 2008/06/30 12:18:34
192 [PROTOCOL]
193 clarify that eow@openssh.com is only sent on session channels
194 - dtucker@cvs.openbsd.org 2008/07/01 07:20:52
195 [sshconnect.c]
196 Check ExitOnForwardFailure if forwardings are disabled due to a failed
197 host key check. ok djm@
198 - dtucker@cvs.openbsd.org 2008/07/01 07:24:22
199 [sshconnect.c sshd.c]
200 Send CR LF during protocol banner exchanges, but only for Protocol 2 only,
201 in order to comply with RFC 4253. bz #1443, ok djm@
202 - stevesk@cvs.openbsd.org 2008/07/01 23:12:47
203 [PROTOCOL.agent]
204 fix some typos; ok djm@
205 - djm@cvs.openbsd.org 2008/07/02 02:24:18
206 [sshd_config sshd_config.5 sshd.8 servconf.c]
207 increase default size of ssh protocol 1 ephemeral key from 768 to 1024
208 bits; prodded by & ok dtucker@ ok deraadt@
209 - dtucker@cvs.openbsd.org 2008/07/02 12:03:51
210 [auth-rsa.c auth.c auth2-pubkey.c auth.h]
211 Merge duplicate host key file checks, based in part on a patch from Rob
212 Holland via bz #1348 . Also checks for non-regular files during protocol
213 1 RSA auth. ok djm@
214 - djm@cvs.openbsd.org 2008/07/02 12:36:39
215 [auth2-none.c auth2.c]
216 Make protocol 2 MaxAuthTries behaviour a little more sensible:
217 Check whether client has exceeded MaxAuthTries before running
218 an authentication method and skip it if they have, previously it
219 would always allow one try (for "none" auth).
220 Preincrement failure count before post-auth test - previously this
221 checked and postincremented, also to allow one "none" try.
222 Together, these two changes always count the "none" auth method
223 which could be skipped by a malicious client (e.g. an SSH worm)
224 to get an extra attempt at a real auth method. They also make
225 MaxAuthTries=0 a useful way to block users entirely (esp. in a
226 sshd_config Match block).
227 Also, move sending of any preauth banner from "none" auth method
228 to the first call to input_userauth_request(), so worms that skip
229 the "none" method get to see it too.
230
23120080630
232 - (djm) OpenBSD CVS Sync
233 - dtucker@cvs.openbsd.org 2008/06/10 23:13:43
234 [regress/Makefile regress/key-options.sh]
235 Add regress test for key options. ok djm@
236 - dtucker@cvs.openbsd.org 2008/06/11 23:11:40
237 [regress/Makefile]
238 Don't run cipher-speed test by default; mistakenly enabled by me
239 - djm@cvs.openbsd.org 2008/06/28 13:57:25
240 [regress/Makefile regress/test-exec.sh regress/conch-ciphers.sh]
241 very basic regress test against Twisted Conch in "make interop"
242 target (conch is available in ports/devel/py-twisted/conch);
243 ok markus@
244 - (djm) [regress/Makefile] search for conch by path, like we do putty
245
24620080629
247 - (djm) OpenBSD CVS Sync
248 - martynas@cvs.openbsd.org 2008/06/21 07:46:46
249 [sftp.c]
250 use optopt to get invalid flag, instead of return value of getopt,
251 which is always '?'; ok djm@
252 - otto@cvs.openbsd.org 2008/06/25 11:13:43
253 [key.c]
254 add key length to visual fingerprint; zap magical constants;
255 ok grunk@ djm@
256 - djm@cvs.openbsd.org 2008/06/26 06:10:09
257 [sftp-client.c sftp-server.c]
258 allow the sftp chmod(2)-equivalent operation to set set[ug]id/sticky
259 bits. Note that this only affects explicit setting of modes (e.g. via
260 sftp(1)'s chmod command) and not file transfers. (bz#1310)
261 ok deraadt@ at c2k8
262 - djm@cvs.openbsd.org 2008/06/26 09:19:40
263 [dh.c dh.h moduli.c]
264 when loading moduli from /etc/moduli in sshd(8), check that they
265 are of the expected "safe prime" structure and have had
266 appropriate primality tests performed;
267 feedback and ok dtucker@
268 - grunk@cvs.openbsd.org 2008/06/26 11:46:31
269 [readconf.c readconf.h ssh.1 ssh_config.5 sshconnect.c]
270 Move SSH Fingerprint Visualization away from sharing the config option
271 CheckHostIP to an own config option named VisualHostKey.
272 While there, fix the behaviour that ssh would draw a random art picture
273 on every newly seen host even when the option was not enabled.
274 prodded by deraadt@, discussions,
275 help and ok markus@ djm@ dtucker@
276 - jmc@cvs.openbsd.org 2008/06/26 21:11:46
277 [ssh.1]
278 add VisualHostKey to the list of options listed in -o;
279 - djm@cvs.openbsd.org 2008/06/28 07:25:07
280 [PROTOCOL]
281 spelling fixes
282 - djm@cvs.openbsd.org 2008/06/28 13:58:23
283 [ssh-agent.c]
284 refuse to add a key that has unknown constraints specified;
285 ok markus
286 - djm@cvs.openbsd.org 2008/06/28 14:05:15
287 [ssh-agent.c]
288 reset global compat flag after processing a protocol 2 signature
289 request with the legacy DSA encoding flag set; ok markus
290 - djm@cvs.openbsd.org 2008/06/28 14:08:30
291 [PROTOCOL PROTOCOL.agent]
292 document the protocol used by ssh-agent; "looks ok" markus@
293
29420080628
295 - (djm) [RFC.nroff contrib/cygwin/Makefile contrib/suse/openssh.spec]
296 RFC.nroff lacks a license, remove it (it is long gone in OpenBSD).
297
29820080626
299 - (djm) [Makefile.in moduli.5] Include moduli(5) manpage from OpenBSD.
300 (bz#1372)
301 - (djm) [ contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
302 [contrib/suse/openssh.spec] Include moduli.5 in RPM spec files.
303
30420080616
305 - (dtucker) OpenBSD CVS Sync
306 - dtucker@cvs.openbsd.org 2008/06/16 13:22:53
307 [session.c channels.c]
308 Rename the isatty argument to is_tty so we don't shadow
309 isatty(3). ok markus@
310 - (dtucker) [channels.c] isatty -> is_tty here too.
311
31220080615
313 - (dtucker) [configure.ac] Enable -fno-builtin-memset when using gcc.
314 - OpenBSD CVS Sync
315 - dtucker@cvs.openbsd.org 2008/06/14 15:49:48
316 [sshd.c]
317 wrap long line at 80 chars
318 - dtucker@cvs.openbsd.org 2008/06/14 17:07:11
319 [sshd.c]
320 ensure default umask disallows at least group and world write; ok djm@
321 - djm@cvs.openbsd.org 2008/06/14 18:33:43
322 [session.c]
323 suppress the warning message from chdir(homedir) failures
324 when chrooted (bz#1461); ok dtucker
325 - dtucker@cvs.openbsd.org 2008/06/14 19:42:10
326 [scp.1]
327 Mention that scp follows symlinks during -r. bz #1466,
328 from nectar at apple
329 - dtucker@cvs.openbsd.org 2008/06/15 16:55:38
330 [sshd_config.5]
331 MaxSessions is allowed in a Match block too
332 - dtucker@cvs.openbsd.org 2008/06/15 16:58:40
333 [servconf.c sshd_config.5]
334 Allow MaxAuthTries within a Match block. ok djm@
335 - djm@cvs.openbsd.org 2008/06/15 20:06:26
336 [channels.c channels.h session.c]
337 don't call isatty() on a pty master, instead pass a flag down to
338 channel_set_fds() indicating that te fds refer to a tty. Fixes a
339 hang on exit on Solaris (bz#1463) in portable but is actually
340 a generic bug; ok dtucker deraadt markus
341
34220080614
343 - (djm) [openbsd-compat/sigact.c] Avoid NULL derefs in ancient sigaction
344 replacement code; patch from ighighi AT gmail.com in bz#1240;
345 ok dtucker
346
34720080613
348 - (dtucker) OpenBSD CVS Sync
349 - deraadt@cvs.openbsd.org 2008/06/13 09:44:36
350 [packet.c]
351 compile on older gcc; no decl after code
352 - dtucker@cvs.openbsd.org 2008/06/13 13:56:59
353 [monitor.c]
354 Clear key options in the monitor on failed authentication, prevents
355 applying additional restrictions to non-pubkey authentications in
356 the case where pubkey fails but another method subsequently succeeds.
357 bz #1472, found by Colin Watson, ok markus@ djm@
358 - dtucker@cvs.openbsd.org 2008/06/13 14:18:51
359 [auth2-pubkey.c auth-rhosts.c]
360 Include unistd.h for close(), prevents warnings in -portable
361 - dtucker@cvs.openbsd.org 2008/06/13 17:21:20
362 [mux.c]
363 Friendlier error messages for mux fallback. ok djm@
364 - dtucker@cvs.openbsd.org 2008/06/13 18:55:22
365 [scp.c]
366 Prevent -Wsign-compare warnings on LP64 systems. bz #1192, ok deraadt@
367 - grunk@cvs.openbsd.org 2008/06/13 20:13:26
368 [ssh.1]
369 Explain the use of SSH fpr visualization using random art, and cite the
370 original scientific paper inspiring that technique.
371 Much help with English and nroff by jmc@, thanks.
372 - (dtucker) [configure.ac] Bug #1276: avoid linking against libgssapi, which
373 despite its name doesn't seem to implement all of GSSAPI. Patch from
374 Jan Engelhardt, sanity checked by Simon Wilkinson.
375
37620080612
377 - (dtucker) OpenBSD CVS Sync
378 - jmc@cvs.openbsd.org 2008/06/11 07:30:37
379 [sshd.8]
380 kill trailing whitespace;
381 - grunk@cvs.openbsd.org 2008/06/11 21:01:35
382 [ssh_config.5 key.h readconf.c readconf.h ssh-keygen.1 ssh-keygen.c key.c
383 sshconnect.c]
384 Introduce SSH Fingerprint ASCII Visualization, a technique inspired by the
385 graphical hash visualization schemes known as "random art", and by
386 Dan Kaminsky's musings on the subject during a BlackOp talk at the
387 23C3 in Berlin.
388 Scientific publication (original paper):
389 "Hash Visualization: a New Technique to improve Real-World Security",
390 Perrig A. and Song D., 1999, International Workshop on Cryptographic
391 Techniques and E-Commerce (CrypTEC '99)
392 http://sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
393 The algorithm used here is a worm crawling over a discrete plane,
394 leaving a trace (augmenting the field) everywhere it goes.
395 Movement is taken from dgst_raw 2bit-wise. Bumping into walls
396 makes the respective movement vector be ignored for this turn,
397 thus switching to the other color of the chessboard.
398 Graphs are not unambiguous for now, because circles in graphs can be
399 walked in either direction.
400 discussions with several people,
401 help, corrections and ok markus@ djm@
402 - grunk@cvs.openbsd.org 2008/06/11 21:38:25
403 [ssh-keygen.c]
404 ssh-keygen -lv -f /etc/ssh/ssh_host_rsa_key.pub
405 would not display you the random art as intended, spotted by canacar@
406 - grunk@cvs.openbsd.org 2008/06/11 22:20:46
407 [ssh-keygen.c ssh-keygen.1]
408 ssh-keygen would write fingerprints to STDOUT, and random art to STDERR,
409 that is not how it was envisioned.
410 Also correct manpage saying that -v is needed along with -l for it to work.
411 spotted by naddy@
412 - otto@cvs.openbsd.org 2008/06/11 23:02:22
413 [key.c]
414 simpler way of computing the augmentations; ok grunk@
415 - grunk@cvs.openbsd.org 2008/06/11 23:03:56
416 [ssh_config.5]
417 CheckHostIP set to ``fingerprint'' will display both hex and random art
418 spotted by naddy@
419 - grunk@cvs.openbsd.org 2008/06/11 23:51:57
420 [key.c]
421 #define statements that are not atoms need braces around them, else they
422 will cause trouble in some cases.
423 Also do a computation of -1 once, and not in a loop several times.
424 spotted by otto@
425 - dtucker@cvs.openbsd.org 2008/06/12 00:03:49
426 [dns.c canohost.c sshconnect.c]
427 Do not pass "0" strings as ports to getaddrinfo because the lookups
428 can slow things down and we never use the service info anyway. bz
429 #859, patch from YOSHIFUJI Hideaki and John Devitofranceschi. ok
430 deraadt@ djm@
431 djm belives that the reason for the "0" strings is to ensure that
432 it's not possible to call getaddrinfo with both host and port being
433 NULL. In the case of canohost.c host is a local array. In the
434 case of sshconnect.c, it's checked for null immediately before use.
435 In dns.c it ultimately comes from ssh.c:main() and is guaranteed to
436 be non-null but it's not obvious, so I added a warning message in
437 case it is ever passed a null.
438 - grunk@cvs.openbsd.org 2008/06/12 00:13:55
439 [sshconnect.c]
440 Make ssh print the random art also when ssh'ing to a host using IP only.
441 spotted by naddy@, ok and help djm@ dtucker@
442 - otto@cvs.openbsd.org 2008/06/12 00:13:13
443 [key.c]
444 use an odd number of rows and columns and a separate start marker, looks
445 better; ok grunk@
446 - djm@cvs.openbsd.org 2008/06/12 03:40:52
447 [clientloop.h mux.c channels.c clientloop.c channels.h]
448 Enable ~ escapes for multiplex slave sessions; give each channel
449 its own escape state and hook the escape filters up to muxed
450 channels. bz #1331
451 Mux slaves do not currently support the ~^Z and ~& escapes.
452 NB. this change cranks the mux protocol version, so a new ssh
453 mux client will not be able to connect to a running old ssh
454 mux master.
455 ok dtucker@
456 - djm@cvs.openbsd.org 2008/06/12 04:06:00
457 [clientloop.h ssh.c clientloop.c]
458 maintain an ordered queue of outstanding global requests that we
459 expect replies to, similar to the per-channel confirmation queue.
460 Use this queue to verify success or failure for remote forward
461 establishment in a race free way.
462 ok dtucker@
463 - djm@cvs.openbsd.org 2008/06/12 04:17:47
464 [clientloop.c]
465 thall shalt not code past the eightieth column
466 - djm@cvs.openbsd.org 2008/06/12 04:24:06
467 [ssh.c]
468 thal shalt not code past the eightieth column
469 - djm@cvs.openbsd.org 2008/06/12 05:15:41
470 [PROTOCOL]
471 document tun@openssh.com forwarding method
472 - djm@cvs.openbsd.org 2008/06/12 05:32:30
473 [mux.c]
474 some more TODO for me
475 - grunk@cvs.openbsd.org 2008/06/12 05:42:46
476 [key.c]
477 supply the key type (rsa1, rsa, dsa) as a caption in the frame of the
478 random art. while there, stress the fact that the field base should at
479 least be 8 characters for the pictures to make sense.
480 comment and ok djm@
481 - grunk@cvs.openbsd.org 2008/06/12 06:32:59
482 [key.c]
483 We already mark the start of the worm, now also mark the end of the worm
484 in our random art drawings.
485 ok djm@
486 - djm@cvs.openbsd.org 2008/06/12 15:19:17
487 [clientloop.h channels.h clientloop.c channels.c mux.c]
488 The multiplexing escape char handler commit last night introduced a
489 small memory leak per session; plug it.
490 - dtucker@cvs.openbsd.org 2008/06/12 16:35:31
491 [ssh_config.5 ssh.c]
492 keyword expansion for localcommand. ok djm@
493 - jmc@cvs.openbsd.org 2008/06/12 19:10:09
494 [ssh_config.5 ssh-keygen.1]
495 tweak the ascii art text; ok grunk
496 - dtucker@cvs.openbsd.org 2008/06/12 20:38:28
497 [sshd.c sshconnect.c packet.h misc.c misc.h packet.c]
498 Make keepalive timeouts apply while waiting for a packet, particularly
499 during key renegotiation (bz #1363). With djm and Matt Day, ok djm@
500 - djm@cvs.openbsd.org 2008/06/12 20:47:04
501 [sftp-client.c]
502 print extension revisions for extensions that we understand
503 - djm@cvs.openbsd.org 2008/06/12 21:06:25
504 [clientloop.c]
505 I was coalescing expected global request confirmation replies at
506 the wrong end of the queue - fix; prompted by markus@
507 - grunk@cvs.openbsd.org 2008/06/12 21:14:46
508 [ssh-keygen.c]
509 make ssh-keygen -lf show the key type just as ssh-add -l would do it
510 ok djm@ markus@
511 - grunk@cvs.openbsd.org 2008/06/12 22:03:36
512 [key.c]
513 add my copyright, ok djm@
514 - ian@cvs.openbsd.org 2008/06/12 23:24:58
515 [sshconnect.c]
516 tweak wording in message, ok deraadt@ jmc@
517 - dtucker@cvs.openbsd.org 2008/06/13 00:12:02
518 [sftp.h log.h]
519 replace __dead with __attribute__((noreturn)), makes things
520 a little easier to port. Also, add it to sigdie(). ok djm@
521 - djm@cvs.openbsd.org 2008/06/13 00:16:49
522 [mux.c]
523 fall back to creating a new TCP connection on most multiplexing errors
524 (socket connect fail, invalid version, refused permittion, corrupted
525 messages, etc.); bz #1329 ok dtucker@
526 - dtucker@cvs.openbsd.org 2008/06/13 00:47:53
527 [mux.c]
528 upcast size_t to u_long to match format arg; ok djm@
529 - dtucker@cvs.openbsd.org 2008/06/13 00:51:47
530 [mac.c]
531 upcast another size_t to u_long to match format
532 - dtucker@cvs.openbsd.org 2008/06/13 01:38:23
533 [misc.c]
534 upcast uid to long with matching %ld, prevents warnings in portable
535 - djm@cvs.openbsd.org 2008/06/13 04:40:22
536 [auth2-pubkey.c auth-rhosts.c]
537 refuse to read ~/.shosts or ~/.ssh/authorized_keys that are not
538 regular files; report from Solar Designer via Colin Watson in bz#1471
539 ok dtucker@ deraadt
540 - (dtucker) [clientloop.c serverloop.c] channel_register_filter now
541 takes 2 more args. with djm@
542 - (dtucker) [defines.h] Bug #1112: __dead is, well dead. Based on a patch
543 from Todd Vierling.
544 - (dtucker) [auth-sia.c] Bug #1241: support password expiry on Tru64 SIA
545 systems. Patch from R. Scott Bailey.
546 - (dtucker) [umac.c] STORE_UINT32_REVERSED and endian_convert are never used
547 on big endian machines, so ifdef them for little-endian only to prevent
548 unused function warnings on big-endians.
549 - (dtucker) [openbsd-compat/setenv.c] Make offsets size_t to prevent
550 compiler warnings on some platforms. Based on a discussion with otto@
551
55220080611
553 - (djm) [channels.c configure.ac]
554 Do not set SO_REUSEADDR on wildcard X11 listeners (X11UseLocalhost=no)
555 bz#1464; ok dtucker
556
55720080610
558 - (dtucker) OpenBSD CVS Sync
559 - djm@cvs.openbsd.org 2008/06/10 03:57:27
560 [servconf.c match.h sshd_config.5]
561 support CIDR address matching in sshd_config "Match address" blocks, with
562 full support for negation and fall-back to classic wildcard matching.
563 For example:
564 Match address 192.0.2.0/24,3ffe:ffff::/32,!10.*
565 PasswordAuthentication yes
566 addrmatch.c code mostly lifted from flowd's addr.c
567 feedback and ok dtucker@
568 - djm@cvs.openbsd.org 2008/06/10 04:17:46
569 [sshd_config.5]
570 better reference for pattern-list
571 - dtucker@cvs.openbsd.org 2008/06/10 04:50:25
572 [sshd.c channels.h channels.c log.c servconf.c log.h servconf.h sshd.8]
573 Add extended test mode (-T) and connection parameters for test mode (-C).
574 -T causes sshd to write its effective configuration to stdout and exit.
575 -C causes any relevant Match rules to be applied before output. The
576 combination allows tesing of the parser and config files. ok deraadt djm
577 - jmc@cvs.openbsd.org 2008/06/10 07:12:00
578 [sshd_config.5]
579 tweak previous;
580 - jmc@cvs.openbsd.org 2008/06/10 08:17:40
581 [sshd.8 sshd.c]
582 - update usage()
583 - fix SYNOPSIS, and sort options
584 - some minor additional fixes
585 - dtucker@cvs.openbsd.org 2008/06/09 18:06:32
586 [regress/test-exec.sh]
587 Don't generate putty keys if we're not going to use them. ok djm
588 - dtucker@cvs.openbsd.org 2008/06/10 05:23:32
589 [regress/addrmatch.sh regress/Makefile]
590 Regress test for Match CIDR rules. ok djm@
591 - dtucker@cvs.openbsd.org 2008/06/10 15:21:41
592 [test-exec.sh]
593 Use a more portable construct for checking if we're running a putty test
594 - dtucker@cvs.openbsd.org 2008/06/10 15:28:49
595 [test-exec.sh]
596 Add quotes
597 - dtucker@cvs.openbsd.org 2008/06/10 18:21:24
598 [ssh_config.5]
599 clarify that Host patterns are space-separated. ok deraadt
600 - djm@cvs.openbsd.org 2008/06/10 22:15:23
601 [PROTOCOL ssh.c serverloop.c]
602 Add a no-more-sessions@openssh.com global request extension that the
603 client sends when it knows that it will never request another session
604 (i.e. when session multiplexing is disabled). This allows a server to
605 disallow further session requests and terminate the session.
606 Why would a non-multiplexing client ever issue additional session
607 requests? It could have been attacked with something like SSH'jack:
608 http://www.storm.net.nz/projects/7
609 feedback & ok markus
610 - djm@cvs.openbsd.org 2008/06/10 23:06:19
611 [auth-options.c match.c servconf.c addrmatch.c sshd.8]
612 support CIDR address matching in .ssh/authorized_keys from="..." stanzas
613 ok and extensive testing dtucker@
614 - dtucker@cvs.openbsd.org 2008/06/10 23:21:34
615 [bufaux.c]
616 Use '\0' for a nul byte rather than unadorned 0. ok djm@
617 - dtucker@cvs.openbsd.org 2008/06/10 23:13:43
618 [Makefile regress/key-options.sh]
619 Add regress test for key options. ok djm@
620 - (dtucker) [openbsd-compat/fake-rfc2553.h] Add sin6_scope_id to sockaddr_in6
621 since the new CIDR code in addmatch.c references it.
622 - (dtucker) [Makefile.in configure.ac regress/addrmatch.sh] Skip IPv6
623 specific tests on platforms that don't do IPv6.
624 - (dtucker) [Makefile.in] Define TEST_SSH_IPV6 in make's arguments as well
625 as environment.
626 - (dtucker) [Makefile.in] Move addrmatch.o to libssh.a where it's needed now.
627
62820080609
629 - (dtucker) OpenBSD CVS Sync
630 - dtucker@cvs.openbsd.org 2008/06/08 17:04:41
631 [sftp-server.c]
632 Add case for ENOSYS in errno_to_portable; ok deraadt
633 - dtucker@cvs.openbsd.org 2008/06/08 20:15:29
634 [sftp.c sftp-client.c sftp-client.h]
635 Have the sftp client store the statvfs replies in wire format,
636 which prevents problems when the server's native sizes exceed the
637 client's.
638 Also extends the sizes of the remaining 32bit wire format to 64bit,
639 they're specified as unsigned long in the standard.
640 - dtucker@cvs.openbsd.org 2008/06/09 13:02:39
641 [sftp-server.c]
642 Extend 32bit -> 64bit values for statvfs extension missed in previous
643 commit.
644 - dtucker@cvs.openbsd.org 2008/06/09 13:38:46
645 [PROTOCOL]
646 Use a $OpenBSD tag so our scripts will sync changes.
647
64820080608
649 - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c
650 openbsd-compat/Makefile.in openbsd-compat/openbsd-compat.h
651 openbsd-compat/bsd-statvfs.{c,h}] Add a null implementation of statvfs and
652 fstatvfs and remove #defines around statvfs code. ok djm@
653 - (dtucker) [configure.ac defines.h sftp-client.c M sftp-server.c] Add a
654 macro to convert fsid to unsigned long for platforms where fsid is a
655 2-member array.
656
65720080607
658 - (dtucker) [mux.c] Include paths.h inside ifdef HAVE_PATHS_H.
659 - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c]
660 Do not enable statvfs extensions on platforms that do not have statvfs.
661 - (dtucker) OpenBSD CVS Sync
662 - djm@cvs.openbsd.org 2008/05/19 06:14:02
663 [packet.c] unbreak protocol keepalive timeouts bz#1465; ok dtucker@
664 - djm@cvs.openbsd.org 2008/05/19 15:45:07
665 [sshtty.c ttymodes.c sshpty.h]
666 Fix sending tty modes when stdin is not a tty (bz#1199). Previously
667 we would send the modes corresponding to a zeroed struct termios,
668 whereas we should have been sending an empty list of modes.
669 Based on patch from daniel.ritz AT alcatel.ch; ok dtucker@ markus@
670 - djm@cvs.openbsd.org 2008/05/19 15:46:31
671 [ssh-keygen.c]
672 support -l (print fingerprint) in combination with -F (find host) to
673 search for a host in ~/.ssh/known_hosts and display its fingerprint;
674 ok markus@
675 - djm@cvs.openbsd.org 2008/05/19 20:53:52
676 [clientloop.c]
677 unbreak tree by committing this bit that I missed from:
678 Fix sending tty modes when stdin is not a tty (bz#1199). Previously
679 we would send the modes corresponding to a zeroed struct termios,
680 whereas we should have been sending an empty list of modes.
681 Based on patch from daniel.ritz AT alcatel.ch; ok dtucker@ markus@
682
68320080604
684 - (djm) [openbsd-compat/bsd-arc4random.c] Fix math bug that caused bias
685 in arc4random_uniform with upper_bound in (2^30,2*31). Note that
686 OpenSSH did not make requests with upper bounds in this range.
687
68820080519
689 - (djm) [configure.ac mux.c sftp.c openbsd-compat/Makefile.in]
690 [openbsd-compat/fmt_scaled.c openbsd-compat/openbsd-compat.h]
691 Fix compilation on Linux, including pulling in fmt_scaled(3)
692 implementation from OpenBSD's libutil.
693
69420080518
695 - (djm) OpenBSD CVS Sync
696 - djm@cvs.openbsd.org 2008/04/04 05:14:38
697 [sshd_config.5]
698 ChrootDirectory is supported in Match blocks (in fact, it is most useful
699 there). Spotted by Minstrel AT minstrel.org.uk
700 - djm@cvs.openbsd.org 2008/04/04 06:44:26
701 [sshd_config.5]
702 oops, some unrelated stuff crept into that commit - backout.
703 spotted by jmc@
704 - djm@cvs.openbsd.org 2008/04/05 02:46:02
705 [sshd_config.5]
706 HostbasedAuthentication is supported under Match too
707 - (djm) [openbsd-compat/bsd-arc4random.c openbsd-compat/openbsd-compat.c]
708 [configure.ac] Implement arc4random_buf(), import implementation of
709 arc4random_uniform() from OpenBSD
710 - (djm) [openbsd-compat/bsd-arc4random.c] Warning fixes
711 - (djm) [openbsd-compat/port-tun.c] needs sys/queue.h
712 - (djm) OpenBSD CVS Sync
713 - djm@cvs.openbsd.org 2008/04/13 00:22:17
714 [dh.c sshd.c]
715 Use arc4random_buf() when requesting more than a single word of output
716 Use arc4random_uniform() when the desired random number upper bound
717 is not a power of two
718 ok deraadt@ millert@
719 - djm@cvs.openbsd.org 2008/04/18 12:32:11
720 [sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c sftp.h]
721 introduce sftp extension methods statvfs@openssh.com and
722 fstatvfs@openssh.com that implement statvfs(2)-like operations,
723 based on a patch from miklos AT szeredi.hu (bz#1399)
724 also add a "df" command to the sftp client that uses the
725 statvfs@openssh.com to produce a df(1)-like display of filesystem
726 space and inode utilisation
727 ok markus@
728 - jmc@cvs.openbsd.org 2008/04/18 17:15:47
729 [sftp.1]
730 macro fixage;
731 - djm@cvs.openbsd.org 2008/04/18 22:01:33
732 [session.c]
733 remove unneccessary parentheses
734 - otto@cvs.openbsd.org 2008/04/29 11:20:31
735 [monitor_mm.h]
736 garbage collect two unused fields in struct mm_master; ok markus@
737 - djm@cvs.openbsd.org 2008/04/30 10:14:03
738 [ssh-keyscan.1 ssh-keyscan.c]
739 default to rsa (protocol 2) keys, instead of rsa1 keys; spotted by
740 larsnooden AT openoffice.org
741 - pyr@cvs.openbsd.org 2008/05/07 05:49:37
742 [servconf.c servconf.h session.c sshd_config.5]
743 Enable the AllowAgentForwarding option in sshd_config (global and match
744 context), to specify if agents should be permitted on the server.
745 As the man page states:
746 ``Note that disabling Agent forwarding does not improve security
747 unless users are also denied shell access, as they can always install
748 their own forwarders.''
749 ok djm@, ok and a mild frown markus@
750 - pyr@cvs.openbsd.org 2008/05/07 06:43:35
751 [sshd_config]
752 push the sshd_config bits in, spotted by ajacoutot@
753 - jmc@cvs.openbsd.org 2008/05/07 08:00:14
754 [sshd_config.5]
755 sort;
756 - markus@cvs.openbsd.org 2008/05/08 06:59:01
757 [bufaux.c buffer.h channels.c packet.c packet.h]
758 avoid extra malloc/copy/free when receiving data over the net;
759 ~10% speedup for localhost-scp; ok djm@
760 - djm@cvs.openbsd.org 2008/05/08 12:02:23
761 [auth-options.c auth1.c channels.c channels.h clientloop.c gss-serv.c]
762 [monitor.c monitor_wrap.c nchan.c servconf.c serverloop.c session.c]
763 [ssh.c sshd.c]
764 Implement a channel success/failure status confirmation callback
765 mechanism. Each channel maintains a queue of callbacks, which will
766 be drained in order (RFC4253 guarantees confirm messages are not
767 reordered within an channel).
768 Also includes a abandonment callback to clean up if a channel is
769 closed without sending confirmation messages. This probably
770 shouldn't happen in compliant implementations, but it could be
771 abused to leak memory.
772 ok markus@ (as part of a larger diff)
773 - djm@cvs.openbsd.org 2008/05/08 12:21:16
774 [monitor.c monitor_wrap.c session.h servconf.c servconf.h session.c]
775 [sshd_config sshd_config.5]
776 Make the maximum number of sessions run-time controllable via
777 a sshd_config MaxSessions knob. This is useful for disabling
778 login/shell/subsystem access while leaving port-forwarding working
779 (MaxSessions 0), disabling connection multiplexing (MaxSessions 1) or
780 simply increasing the number of allows multiplexed sessions.
781 Because some bozos are sure to configure MaxSessions in excess of the
782 number of available file descriptors in sshd (which, at peak, might be
783 as many as 9*MaxSessions), audit sshd to ensure that it doesn't leak fds
784 on error paths, and make it fail gracefully on out-of-fd conditions -
785 sending channel errors instead of than exiting with fatal().
786 bz#1090; MaxSessions config bits and manpage from junyer AT gmail.com
787 ok markus@
788 - djm@cvs.openbsd.org 2008/05/08 13:06:11
789 [clientloop.c clientloop.h ssh.c]
790 Use new channel status confirmation callback system to properly deal
791 with "important" channel requests that fail, in particular command exec,
792 shell and subsystem requests. Previously we would optimistically assume
793 that the requests would always succeed, which could cause hangs if they
794 did not (e.g. when the server runs out of fds) or were unimplemented by
795 the server (bz #1384)
796 Also, properly report failing multiplex channel requests via the mux
797 client stderr (subject to LogLevel in the mux master) - better than
798 silently failing.
799 most bits ok markus@ (as part of a larger diff)
800 - djm@cvs.openbsd.org 2008/05/09 04:55:56
801 [channels.c channels.h clientloop.c serverloop.c]
802 Try additional addresses when connecting to a port forward destination
803 whose DNS name resolves to more than one address. The previous behaviour
804 was to try the first address and give up.
805 Reported by stig AT venaas.com in bz#343
806 great feedback and ok markus@
807 - djm@cvs.openbsd.org 2008/05/09 14:18:44
808 [clientloop.c clientloop.h ssh.c mux.c]
809 tidy up session multiplexing code, moving it into its own file and
810 making the function names more consistent - making ssh.c and
811 clientloop.c a fair bit more readable.
812 ok markus@
813 - djm@cvs.openbsd.org 2008/05/09 14:26:08
814 [ssh.c]
815 dingo stole my diff hunk
816 - markus@cvs.openbsd.org 2008/05/09 16:16:06
817 [session.c]
818 re-add the USE_PIPES code and enable it.
819 without pipes shutdown-read from the sshd does not trigger
820 a SIGPIPE when the forked program does a write.
821 ok djm@
822 (Id sync only, USE_PIPES never left portable OpenSSH)
823 - markus@cvs.openbsd.org 2008/05/09 16:17:51
824 [channels.c]
825 error-fd race: don't enable the error fd in the select bitmask
826 for channels with both in- and output closed, since the channel
827 will go away before we call select();
828 report, lots of debugging help and ok djm@
829 - markus@cvs.openbsd.org 2008/05/09 16:21:13
830 [channels.h clientloop.c nchan.c serverloop.c]
831 unbreak
832 ssh -2 localhost od /bin/ls | true
833 ignoring SIGPIPE by adding a new channel message (EOW) that signals
834 the peer that we're not interested in any data it might send.
835 fixes bz #85; discussion, debugging and ok djm@
836 - pvalchev@cvs.openbsd.org 2008/05/12 20:52:20
837 [umac.c]
838 Ensure nh_result lies on a 64-bit boundary (fixes warnings observed
839 on Itanium on Linux); from Dale Talcott (bug #1462); ok djm@
840 - djm@cvs.openbsd.org 2008/05/15 23:52:24
841 [nchan2.ms]
842 document eow message in ssh protocol 2 channel state machine;
843 feedback and ok markus@
844 - djm@cvs.openbsd.org 2008/05/18 21:29:05
845 [sftp-server.c]
846 comment extension announcement
847 - djm@cvs.openbsd.org 2008/05/16 08:30:42
848 [PROTOCOL]
849 document our protocol extensions and deviations; ok markus@
850 - djm@cvs.openbsd.org 2008/05/17 01:31:56
851 [PROTOCOL]
852 grammar and correctness fixes from stevesk@
853
85420080403
855 - (djm) [openbsd-compat/bsd-poll.c] Include stdlib.h to avoid compile-
856 time warnings on LynxOS. Patch from ops AT iki.fi
857 - (djm) Force string arguments to replacement setproctitle() though
858 strnvis first. Ok dtucker@
859
86020080403
861 - (djm) OpenBSD CVS sync:
862 - markus@cvs.openbsd.org 2008/04/02 15:36:51
863 [channels.c]
864 avoid possible hijacking of x11-forwarded connections (back out 1.183)
865 CVE-2008-1483; ok djm@
866 - jmc@cvs.openbsd.org 2008/03/27 22:37:57
867 [sshd.8]
868 remove trailing whitespace;
869 - djm@cvs.openbsd.org 2008/04/03 09:50:14
870 [version.h]
871 openssh-5.0
872 - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
873 [contrib/suse/openssh.spec] Crank version numbers in RPM spec files
874 - (djm) [README] Update link to release notes
875 - (djm) Release 5.0p1
876
87720080315
878 - (djm) [regress/test-exec.sh] Quote putty-related variables in case they are
879 empty; report and patch from Peter Stuge
880 - (djm) [regress/test-exec.sh] Silence noise from detection of putty
881 commands; report from Peter Stuge
882 - (djm) [session.c] Relocate incorrectly-placed closefrom() that was causing
883 crashes when used with ChrootDirectory
884
885
88620080327
887 - (dtucker) Cache selinux status earlier so we know if it's enabled after a
888 chroot. Allows ChrootDirectory to work with selinux support compiled in
889 but not enabled. Using it with selinux enabled will require some selinux
890 support inside the chroot. "looks sane" djm@
891 - (djm) Fix RCS ident in sftp-server-main.c
892 - (djm) OpenBSD CVS sync:
893 - jmc@cvs.openbsd.org 2008/02/11 07:58:28
894 [ssh.1 sshd.8 sshd_config.5]
895 bump Mdocdate for pages committed in "febuary", necessary because
896 of a typo in rcs.c;
897 - deraadt@cvs.openbsd.org 2008/03/13 01:49:53
898 [monitor_fdpass.c]
899 Correct CMSG_SPACE and CMSG_LEN usage everywhere in the tree. Due to
900 an extensive discussion with otto, kettenis, millert, and hshoexer
901 - deraadt@cvs.openbsd.org 2008/03/15 16:19:02
902 [monitor_fdpass.c]
903 Repair the simple cases for msg_controllen where it should just be
904 CMSG_SIZE(sizeof(int)), not sizeof(buffer) which may be larger because
905 of alignment; ok kettenis hshoexer
906 - djm@cvs.openbsd.org 2008/03/23 12:54:01
907 [sftp-client.c]
908 prefer POSIX-style file renaming over filexfer rename behaviour if the
909 server supports the posix-rename@openssh.com extension.
910 Note that the old (filexfer) behaviour would refuse to clobber an
911 existing file. Users who depended on this should adjust their sftp(1)
912 usage.
913 ok deraadt@ markus@
914 - deraadt@cvs.openbsd.org 2008/03/24 16:11:07
915 [monitor_fdpass.c]
916 msg_controllen has to be CMSG_SPACE so that the kernel can account for
917 each cmsg_len (ie. msg_controllen = sum of CMSG_ALIGN(cmsg_len). This
918 works now that kernel fd passing has been fixed to accept a bit of
919 sloppiness because of this ABI repair.
920 lots of discussion with kettenis
921 - djm@cvs.openbsd.org 2008/03/25 11:58:02
922 [session.c sshd_config.5]
923 ignore ~/.ssh/rc if a sshd_config ForceCommand is specified;
924 from dtucker@ ok deraadt@ djm@
925 - djm@cvs.openbsd.org 2008/03/25 23:01:41
926 [session.c]
927 last patch had backwards test; spotted by termim AT gmail.com
928 - djm@cvs.openbsd.org 2008/03/26 21:28:14
929 [auth-options.c auth-options.h session.c sshd.8]
930 add no-user-rc authorized_keys option to disable execution of ~/.ssh/rc
931 - djm@cvs.openbsd.org 2008/03/27 00:16:49
932 [version.h]
933 openssh-4.9
934 - djm@cvs.openbsd.org 2008/03/24 21:46:54
935 [regress/sftp-badcmds.sh]
936 disable no-replace rename test now that we prefer a POSIX rename; spotted
937 by dkrause@
938 - (djm) [configure.ac] fix alignment of --without-stackprotect description
939 - (djm) [configure.ac] --with-selinux too
940 - (djm) [regress/Makefile] cleanup PuTTY interop test droppings
941 - (djm) [README] Update link to release notes
942 - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
943 [contrib/suse/openssh.spec] Crank version numbers in RPM spec files
944 - (djm) Release 4.9p1
945
94620080315
947 - (djm) [regress/test-exec.sh] Quote putty-related variables in case they are
948 empty; report and patch from Peter Stuge
949 - (djm) [regress/test-exec.sh] Silence noise from detection of putty
950 commands; report from Peter Stuge
951 - (djm) [session.c] Relocate incorrectly-placed closefrom() that was causing
952 crashes when used with ChrootDirectory
953
95420080314
955 - (tim) [regress/sftp-cmds.sh] s/cd/lcd/ in lls test. Reported by
956 vinschen at redhat.com. Add () to put echo commands in subshell for lls test
957 I mistakenly left out of last commit.
958 - (tim) [regress/localcommand.sh] Shell portability fix. Reported by imorgan at
959 nas.nasa.gov
960
96120080313
962 - (djm) [Makefile.in regress/Makefile] Fix interop-tests target (note to
963 self: make changes to Makefile.in next time, not the generated Makefile).
964 - (djm) [Makefile.in regress/test-exec.sh] Find installed plink(1) and
965 puttygen(1) by $PATH
966 - (tim) [scp.c] Use poll.h if available, fall back to sys/poll.h if not. Patch
967 by vinschen at redhat.com.
968 - (tim) [regress/sftp-cmds.sh regress/ssh2putty.sh] Shell portability fixes
969 from vinschen at redhat.com and imorgan at nas.nasa.gov
970
97120080312
972 - (djm) OpenBSD CVS Sync
973 - dtucker@cvs.openbsd.org 2007/10/29 06:57:13
974 [regress/Makefile regress/localcommand.sh]
975 Add simple regress test for LocalCommand; ok djm@
976 - jmc@cvs.openbsd.org 2007/11/25 15:35:09
977 [regress/agent-getpeereid.sh regress/agent.sh]
978 more existant -> existent, from Martynas Venckus;
979 pfctl changes: ok henning
980 ssh changes: ok deraadt
981 - djm@cvs.openbsd.org 2007/12/12 05:04:03
982 [regress/sftp-cmds.sh]
983 unbreak lls command and add a regress test that would have caught the
984 breakage; spotted by mouring@
985 NB. sftp code change already committed.
986 - djm@cvs.openbsd.org 2007/12/21 04:13:53
987 [regress/Makefile regress/test-exec.sh regress/putty-ciphers.sh]
988 [regress/putty-kex.sh regress/putty-transfer.sh regress/ssh2putty.sh]
989 basic (crypto, kex and transfer) interop regression tests against putty
990 To run these, install putty and run "make interop-tests" from the build
991 directory - the tests aren't run by default yet.
992
99320080311
994 - (dtucker) [auth-pam.c monitor.c session.c sshd.c] Bug #926: Move
995 pam_open_session and pam_close_session into the privsep monitor, which
996 will ensure that pam_session_close is called as root. Patch from Tomas
997 Mraz.
998
99920080309
1000 - (dtucker) [configure.ac] It turns out gcc's -fstack-protector-all doesn't
1001 always work for all platforms and versions, so test what we can and
1002 add a configure flag to turn it of if needed. ok djm@
1003 - (dtucker) [openbsd-compat/port-aix.{c,h}] Remove AIX specific initgroups
1004 implementation. It's not needed to fix bug #1081 and breaks the build
1005 on some AIX configurations.
1006 - (dtucker) [openbsd-compat/regress/strtonumtest.c] Bug #1347: Use platform's
1007 equivalent of LLONG_MAX for the compat regression tests, which makes them
1008 run on AIX and HP-UX. Patch from David Leonard.
1009 - (dtucker) [configure.ac] Run stack-protector tests with -Werror to catch
1010 platforms where gcc understands the option but it's not supported (and
1011 thus generates a warning).
1012
101320080307
1014 - (djm) OpenBSD CVS Sync
1015 - jmc@cvs.openbsd.org 2008/02/11 07:58:28
1016 [ssh.1 sshd.8 sshd_config.5]
1017 bump Mdocdate for pages committed in "febuary", necessary because
1018 of a typo in rcs.c;
1019 - djm@cvs.openbsd.org 2008/02/13 22:38:17
1020 [servconf.h session.c sshd.c]
1021 rekey arc4random and OpenSSL RNG in postauth child
1022 closefrom fds > 2 before shell/command execution
1023 ok markus@
1024 - mbalmer@cvs.openbsd.org 2008/02/14 13:10:31
1025 [sshd.c]
1026 When started in configuration test mode (-t) do not check that sshd is
1027 being started with an absolute path.
1028 ok djm
1029 - markus@cvs.openbsd.org 2008/02/20 15:25:26
1030 [session.c]
1031 correct boolean encoding for coredump; der Mouse via dugsong
1032 - djm@cvs.openbsd.org 2008/02/22 05:58:56
1033 [session.c]
1034 closefrom() call was too early, delay it until just before we execute
1035 the user's rc files (if any).
1036 - dtucker@cvs.openbsd.org 2008/02/22 20:44:02
1037 [clientloop.c packet.c packet.h serverloop.c]
1038 Allow all SSH2 packet types, including UNIMPLEMENTED to reset the
1039 keepalive timer (bz #1307). ok markus@
1040 - djm@cvs.openbsd.org 2008/02/27 20:21:15
1041 [sftp-server.c]
1042 add an extension method "posix-rename@openssh.com" to perform POSIX atomic
1043 rename() operations. based on patch from miklos AT szeredi.hu in bz#1400;
1044 ok dtucker@ markus@
1045 - deraadt@cvs.openbsd.org 2008/03/02 18:19:35
1046 [monitor_fdpass.c]
1047 use a union to ensure alignment of the cmsg (pay attention: various other
1048 parts of the tree need this treatment too); ok djm
1049 - deraadt@cvs.openbsd.org 2008/03/04 21:15:42
1050 [version.h]
1051 crank version; from djm
1052 - (tim) [regress/sftp-glob.sh] Shell portability fix.
1053
105420080302
1055 - (dtucker) [configure.ac] FreeBSD's glob() doesn't behave the way we expect
1056 either, so use our own.
1057
105820080229
1059 - (dtucker) [openbsd-compat/bsd-poll.c] We don't check for select(2) in
1060 configure (and there's not much point, as openssh won't work without it)
1061 so HAVE_SELECT is not defined and the poll(2) compat code doesn't get
1062 built in. Remove HAVE_SELECT so we can build on platforms without poll.
1063 - (dtucker) [scp.c] Include sys/poll.h inside HAVE_SYS_POLL_H.
1064 - (djm) [contrib/gnome-ssh-askpass2.h] Keep askpass windown on top. From
1065 Debian patch via bernd AT openbsd.org
1066
106720080228
1068 - (dtucker) [configure.ac] Add -fstack-protector to LDFLAGS too, fixes
1069 linking problems on AIX with gcc 4.1.x.
1070 - (dtucker) [includes.h ssh-add.c ssh-agent.c ssh-keygen.c ssh.c sshd.c
1071 openbsd-compat/openssl-compat.{c,h}] Bug #1437 Move the OpenSSL compat
1072 header to after OpenSSL headers, since some versions of OpenSSL have
1073 SSLeay_add_all_algorithms as a macro already.
1074 - (dtucker) [key.c defines.h openbsd-compat/openssl-compat.h] Move old OpenSSL
1075 compat glue into openssl-compat.h.
1076 - (dtucker) [configure.ac openbsd-compat/port-aix.{c,h}] Bug #1081: Implement
1077 getgrouplist via getgrset on AIX, rather than iterating over getgrent.
1078 This allows, eg, Match and AllowGroups directives to work with NIS and
1079 LDAP groups.
1080 - (dtucker) [sshd.c] Bug #1042: make log messages for tcpwrappers use the
1081 same SyslogFacility as the rest of sshd. Patch from William Knox,
1082 ok djm@.
1083
108420080225
1085 - (dtucker) [openbsd-compat/fake-rfc2553.h] rename ssh_gai_strerror hack
1086 since it now conflicts with the helper function in misc.c. From
1087 vinschen AT redhat.com.
1088 - (dtucker) [configure.ac audit-bsm.c] Bug #1420: Add a local implementation
1089 of aug_get_machine for systems that don't have their own (eg OS X, FreeBSD).
1090 Help and testing from csjp at FreeBSD org, vgiffin at apple com. ok djm@
1091 - (dtucker) [includes.h openbsd-compat/openssl-compat.c] Bug #1437: reshuffle
1092 headers so ./configure --with-ssl-engine actually works. Patch from
1093 Ian Lister.
1094
109520080224
1096 - (tim) [contrib/cygwin/ssh-host-config]
1097 Grammar changes on SYSCONFDIR LOCALSTATEDIR messages.
1098 Check more thoroughly that it's possible to create the /var/empty directory.
1099 Patch by vinschen AT redhat.com
1100
110120080210
1102 - OpenBSD CVS Sync
1103 - chl@cvs.openbsd.org 2008/01/11 07:22:28
1104 [sftp-client.c sftp-client.h]
1105 disable unused functions
1106 initially from tobias@, but disabled them by placing them in
1107 "#ifdef notyet" which was asked by djm@
1108 ok djm@ tobias@
1109 - djm@cvs.openbsd.org 2008/01/19 19:13:28
1110 [ssh.1]
1111 satisfy the pedants: -q does not suppress all diagnostic messages (e.g.
1112 some commandline parsing warnings go unconditionally to stdout).
1113 - djm@cvs.openbsd.org 2008/01/19 20:48:53
1114 [clientloop.c]
1115 fd leak on session multiplexing error path. Report and patch from
1116 gregory_shively AT fanniemae.com
1117 - djm@cvs.openbsd.org 2008/01/19 20:51:26
1118 [ssh.c]
1119 ignore SIGPIPE in multiplex client mode - we can receive this if the
1120 server runs out of fds on us midway. Report and patch from
1121 gregory_shively AT fanniemae.com
1122 - djm@cvs.openbsd.org 2008/01/19 22:04:57
1123 [sftp-client.c]
1124 fix remote handle leak in do_download() local file open error path;
1125 report and fix from sworley AT chkno.net
1126 - djm@cvs.openbsd.org 2008/01/19 22:22:58
1127 [ssh-keygen.c]
1128 when hashing individual hosts (ssh-keygen -Hf hostname), make sure we
1129 hash just the specified hostname and not the entire hostspec from the
1130 keyfile. It may be of the form "hostname,ipaddr", which would lead to
1131 a hash that never matches. report and fix from jp AT devnull.cz
1132 - djm@cvs.openbsd.org 2008/01/19 22:37:19
1133 [ssh-keygen.c]
1134 unbreak line numbering (broken in revision 1.164), fix error message
1135 - djm@cvs.openbsd.org 2008/01/19 23:02:40
1136 [channels.c]
1137 When we added support for specified bind addresses for port forwards, we
1138 added a quirk SSH_OLD_FORWARD_ADDR. There is a bug in our handling of
1139 this for -L port forwards that causes the client to listen on both v4
1140 and v6 addresses when connected to a server with this quirk, despite
1141 having set 0.0.0.0 as a bind_address.
1142 report and patch from Jan.Pechanec AT Sun.COM; ok dtucker@
1143 - djm@cvs.openbsd.org 2008/01/19 23:09:49
1144 [readconf.c readconf.h sshconnect2.c]
1145 promote rekeylimit to a int64 so it can hold the maximum useful limit
1146 of 2^32; report and patch from Jan.Pechanec AT Sun.COM, ok dtucker@
1147 - djm@cvs.openbsd.org 2008/01/20 00:38:30
1148 [sftp.c]
1149 When uploading, correctly handle the case of an unquoted filename with
1150 glob metacharacters that match a file exactly but not as a glob, e.g. a
1151 file called "[abcd]". report and test cases from duncan2nd AT gmx.de
1152 - djm@cvs.openbsd.org 2008/01/21 17:24:30
1153 [sftp-server.c]
1154 Remove the fixed 100 handle limit in sftp-server and allocate as many
1155 as we have available file descriptors. Patch from miklos AT szeredi.hu;
1156 ok dtucker@ markus@
1157 - djm@cvs.openbsd.org 2008/01/21 19:20:17
1158 [sftp-client.c]
1159 when a remote write error occurs during an upload, ensure that ACKs for
1160 all issued requests are properly drained. patch from t8m AT centrum.cz
1161 - dtucker@cvs.openbsd.org 2008/01/23 01:56:54
1162 [clientloop.c packet.c serverloop.c]
1163 Revert the change for bz #1307 as it causes connection aborts if an IGNORE
1164 packet arrives while we're waiting in packet_read_expect (and possibly
1165 elsewhere).
1166 - jmc@cvs.openbsd.org 2008/01/31 20:06:50
1167 [scp.1]
1168 explain how to handle local file names containing colons;
1169 requested by Tamas TEVESZ
1170 ok dtucker
1171 - markus@cvs.openbsd.org 2008/02/04 21:53:00
1172 [session.c sftp-server.c sftp.h]
1173 link sftp-server into sshd; feedback and ok djm@
1174 - mcbride@cvs.openbsd.org 2008/02/09 12:15:43
1175 [ssh.1 sshd.8]
1176 Document the correct permissions for the ~/.ssh/ directory.
1177 ok jmc
1178 - djm@cvs.openbsd.org 2008/02/10 09:55:37
1179 [sshd_config.5]
1180 mantion that "internal-sftp" is useful with ForceCommand too
1181 - djm@cvs.openbsd.org 2008/02/10 10:54:29
1182 [servconf.c session.c]
1183 delay ~ expansion for ChrootDirectory so it expands to the logged-in user's
1184 home, rather than the user who starts sshd (probably root)
1185
118620080119
1187 - (djm) Silence noice from expr in ssh-copy-id; patch from
1188 mikel AT mikelward.com
1189 - (djm) Only listen for IPv6 connections on AF_INET6 sockets; patch from
1190 tsr2600 AT gmail.com
1191
119220080102
1193 - (dtucker) [configure.ac] Fix message for -fstack-protector-all test.
1194
119520080101
1196 - (dtucker) OpenBSD CVS Sync
1197 - dtucker@cvs.openbsd.org 2007/12/31 10:41:31
1198 [readconf.c servconf.c]
1199 Prevent strict-aliasing warnings on newer gcc versions. bz #1355, patch
1200 from Dmitry V. Levin, ok djm@
1201 - dtucker@cvs.openbsd.org 2007/12/31 15:27:04
1202 [sshd.c]
1203 When in inetd mode, have sshd generate a Protocol 1 ephemeral server
1204 key only for connections where the client chooses Protocol 1 as opposed
1205 to when it's enabled in the server's config. Speeds up Protocol 2
1206 connections to inetd-mode servers that also allow Protocol 1. bz #440,
1207 based on a patch from bruno at wolff.to, ok markus@
1208 - dtucker@cvs.openbsd.org 2008/01/01 08:47:04
1209 [misc.c]
1210 spaces -> tabs from my previous commit
1211 - dtucker@cvs.openbsd.org 2008/01/01 09:06:39
1212 [scp.c]
1213 If scp -p encounters a pre-epoch timestamp, use the epoch which is
1214 as close as we can get given that it's used unsigned. Add a little
1215 debugging while there. bz #828, ok djm@
1216 - dtucker@cvs.openbsd.org 2008/01/01 09:27:33
1217 [sshd_config.5 servconf.c]
1218 Allow PermitRootLogin in a Match block. Allows for, eg, permitting root
1219 only from the local network. ok markus@, man page bit ok jmc@
1220 - dtucker@cvs.openbsd.org 2008/01/01 08:51:20
1221 [moduli]
1222 Updated moduli file; ok djm@
1223
122420071231
1225 - (dtucker) [configure.ac openbsd-compat/glob.{c,h}] Bug #1407: force use of
1226 builtin glob implementation on Mac OS X. Based on a patch from
1227 vgiffin at apple.
1228
122920071229
1230 - (dtucker) OpenBSD CVS Sync
1231 - djm@cvs.openbsd.org 2007/12/12 05:04:03
1232 [sftp.c]
1233 unbreak lls command and add a regress test that would have caught the
1234 breakage; spotted by mouring@
1235 - dtucker@cvs.openbsd.org 2007/12/27 14:22:08
1236 [servconf.c canohost.c misc.c channels.c sshconnect.c misc.h ssh-keyscan.c
1237 sshd.c]
1238 Add a small helper function to consistently handle the EAI_SYSTEM error
1239 code of getaddrinfo. Prompted by vgiffin at apple com via bz #1417.
1240 ok markus@ stevesk@
1241 - dtucker@cvs.openbsd.org 2007/12/28 15:32:24
1242 [clientloop.c serverloop.c packet.c]
1243 Make SSH2_MSG_UNIMPLEMENTED and SSH2_MSG_IGNORE messages reset the
1244 ServerAlive and ClientAlive timers. Prevents dropping a connection
1245 when these are enabled but the peer does not support our keepalives.
1246 bz #1307, ok djm@.
1247 - dtucker@cvs.openbsd.org 2007/12/28 22:34:47
1248 [clientloop.c]
1249 Use the correct packet maximum sizes for remote port and agent forwarding.
1250 Prevents the server from killing the connection if too much data is queued
1251 and an excessively large packet gets sent. bz #1360, ok djm@.
1252
125320071202
1254 - (dtucker) [configure.ac] Enable -fstack-protector-all on systems where
1255 gcc supports it. ok djm@
1256 - (dtucker) [scp.c] Update $OpenBSD tag missing from rev 1.175 and remove
1257 leftover debug code.
1258 - (dtucker) OpenBSD CVS Sync
1259 - dtucker@cvs.openbsd.org 2007/10/29 00:52:45
1260 [auth2-gss.c]
1261 Allow build without -DGSSAPI; ok deraadt@
1262 (Id sync only, Portable already has the ifdefs)
1263 - dtucker@cvs.openbsd.org 2007/10/29 01:55:04
1264 [ssh.c]
1265 Plug tiny mem leaks in ControlPath and ProxyCommand option processing;
1266 ok djm@
1267 - dtucker@cvs.openbsd.org 2007/10/29 04:08:08
1268 [monitor_wrap.c monitor.c]
1269 Send config block back to slave for invalid users too so options
1270 set by a Match block (eg Banner) behave the same for non-existent
1271 users. Found by and ok djm@
1272 - dtucker@cvs.openbsd.org 2007/10/29 06:51:59
1273 [ssh_config.5]
1274 ProxyCommand and LocalCommand use the user's shell, not /bin/sh; ok djm@
1275 - dtucker@cvs.openbsd.org 2007/10/29 06:54:50
1276 [ssh.c]
1277 Make LocalCommand work for Protocol 1 too; ok djm@
1278 - jmc@cvs.openbsd.org 2007/10/29 07:48:19
1279 [ssh_config.5]
1280 clean up after previous macro removal;
1281 - djm@cvs.openbsd.org 2007/11/03 00:36:14
1282 [clientloop.c]
1283 fix memory leak in process_cmdline(), patch from Jan.Pechanec AT Sun.COM;
1284 ok dtucker@
1285 - deraadt@cvs.openbsd.org 2007/11/03 01:24:06
1286 [ssh.c]
1287 bz #1377: getpwuid results were being clobbered by another getpw* call
1288 inside tilde_expand_filename(); save the data we need carefully
1289 ok djm
1290 - dtucker@cvs.openbsd.org 2007/11/03 02:00:32
1291 [ssh.c]
1292 Use xstrdup/xfree when saving pwname and pwdir; ok deraadt@
1293 - deraadt@cvs.openbsd.org 2007/11/03 02:03:49
1294 [ssh.c]
1295 avoid errno trashing in signal handler; ok dtucker
1296
129720071030
1298 - (djm) OpenBSD CVS Sync
1299 - djm@cvs.openbsd.org 2007/10/29 23:49:41
1300 [openbsd-compat/sys-tree.h]
1301 remove extra backslash at the end of RB_PROTOTYPE, report from
1302 Jan.Pechanec AT Sun.COM; ok deraadt@
1303
130420071026
1305 - (djm) OpenBSD CVS Sync
1306 - stevesk@cvs.openbsd.org 2007/09/11 23:49:09
1307 [sshpty.c]
1308 remove #if defined block not needed; ok markus@ dtucker@
1309 (NB. RCD ID sync only for portable)
1310 - djm@cvs.openbsd.org 2007/09/21 03:05:23
1311 [ssh_config.5]
1312 document KbdInteractiveAuthentication in ssh_config.5;
1313 patch from dkg AT fifthhorseman.net
1314 - djm@cvs.openbsd.org 2007/09/21 08:15:29
1315 [auth-bsdauth.c auth-passwd.c auth.c auth.h auth1.c auth2-chall.c]
1316 [monitor.c monitor_wrap.c]
1317 unifdef -DBSD_AUTH
1318 unifdef -USKEY
1319 These options have been in use for some years;
1320 ok markus@ "no objection" millert@
1321 (NB. RCD ID sync only for portable)
1322 - canacar@cvs.openbsd.org 2007/09/25 23:48:57
1323 [ssh-agent.c]
1324 When adding a key that already exists, update the properties
1325 (time, confirm, comment) instead of discarding them. ok djm@ markus@
1326 - ray@cvs.openbsd.org 2007/09/27 00:15:57
1327 [dh.c]
1328 Don't return -1 on error in dh_pub_is_valid(), since it evaluates
1329 to true.
1330 Also fix a typo.
1331 Initial diff from Matthew Dempsky, input from djm.
1332 OK djm, markus.
1333 - dtucker@cvs.openbsd.org 2007/09/29 00:25:51
1334 [auth2.c]
1335 Remove unused prototype. ok djm@
1336 - chl@cvs.openbsd.org 2007/10/02 17:49:58
1337 [ssh-keygen.c]
1338 handles zero-sized strings that fgets can return
1339 properly removes trailing newline
1340 removes an unused variable
1341 correctly counts line number
1342 "looks ok" ray@ markus@
1343 - markus@cvs.openbsd.org 2007/10/22 19:10:24
1344 [readconf.c]
1345 make sure that both the local and remote port are correct when
1346 parsing -L; Jan Pechanec (bz #1378)
1347 - djm@cvs.openbsd.org 2007/10/24 03:30:02
1348 [sftp.c]
1349 rework argument splitting and parsing to cope correctly with common
1350 shell escapes and make handling of escaped characters consistent
1351 with sh(1) and between sftp commands (especially between ones that
1352 glob their arguments and ones that don't).
1353 parse command flags using getopt(3) rather than hand-rolled parsers.
1354 ok dtucker@
1355 - djm@cvs.openbsd.org 2007/10/24 03:44:02
1356 [scp.c]
1357 factor out network read/write into an atomicio()-like function, and
1358 use it to handle short reads, apply bandwidth limits and update
1359 counters. make network IO non-blocking, so a small trickle of
1360 reads/writes has a chance of updating the progress meter; bz #799
1361 ok dtucker@
1362 - djm@cvs.openbsd.org 2006/08/29 09:44:00
1363 [regress/sftp-cmds.sh]
1364 clean up our mess
1365 - markus@cvs.openbsd.org 2006/11/06 09:27:43
1366 [regress/cfgmatch.sh]
1367 fix quoting for non-(c)sh login shells.
1368 - dtucker@cvs.openbsd.org 2006/12/13 08:36:36
1369 [regress/cfgmatch.sh]
1370 Additional test for multiple PermitOpen entries. ok djm@
1371 - pvalchev@cvs.openbsd.org 2007/06/07 19:41:46
1372 [regress/cipher-speed.sh regress/try-ciphers.sh]
1373 test umac-64@openssh.com
1374 ok djm@
1375 - djm@cvs.openbsd.org 2007/10/24 03:32:35
1376 [regress/sftp-cmds.sh regress/sftp-glob.sh regress/test-exec.sh]
1377 comprehensive tests for sftp escaping its interaction with globbing;
1378 ok dtucker@
1379 - djm@cvs.openbsd.org 2007/10/26 05:30:01
1380 [regress/sftp-glob.sh regress/test-exec.sh]
1381 remove "echo -E" crap that I added in last commit and use printf(1) for
1382 cases where we strictly require echo not to reprocess escape characters.
1383 - deraadt@cvs.openbsd.org 2005/11/28 17:50:12
1384 [openbsd-compat/glob.c]
1385 unused arg in internal static API
1386 - jakob@cvs.openbsd.org 2007/10/11 18:36:41
1387 [openbsd-compat/getrrsetbyname.c openbsd-compat/getrrsetbyname.h]
1388 use RRSIG instead of SIG for DNSSEC. ok djm@
1389 - otto@cvs.openbsd.org 2006/10/21 09:55:03
1390 [openbsd-compat/base64.c]
1391 remove calls to abort(3) that can't happen anyway; from
1392 <bret dot lambert at gmail.com>; ok millert@ deraadt@
1393 - frantzen@cvs.openbsd.org 2004/04/24 18:11:46
1394 [openbsd-compat/sys-tree.h]
1395 sync to Niels Provos' version. avoid unused variable warning in
1396 RB_NEXT()
1397 - tdeval@cvs.openbsd.org 2004/11/24 18:10:42
1398 [openbsd-compat/sys-tree.h]
1399 typo
1400 - grange@cvs.openbsd.org 2004/05/04 16:59:32
1401 [openbsd-compat/sys-queue.h]
1402 Remove useless ``elm'' argument from the SIMPLEQ_REMOVE_HEAD macro.
1403 This matches our SLIST behaviour and NetBSD's SIMPLEQ as well.
1404 ok millert krw deraadt
1405 - deraadt@cvs.openbsd.org 2005/02/25 13:29:30
1406 [openbsd-compat/sys-queue.h]
1407 minor white spacing
1408 - otto@cvs.openbsd.org 2005/10/17 20:19:42
1409 [openbsd-compat/sys-queue.h]
1410 Performing certain operations on queue.h data structurs produced
1411 funny results. An example is calling LIST_REMOVE on the same
1412 element twice. This will not fail, but result in a data structure
1413 referencing who knows what. Prevent these accidents by NULLing some
1414 fields on remove and replace. This way, either a panic or segfault
1415 will be produced on the faulty operation.
1416 - otto@cvs.openbsd.org 2005/10/24 20:25:14
1417 [openbsd-compat/sys-queue.h]
1418 Partly backout. NOLIST, used in LISTs is probably interfering.
1419 requested by deraadt@
1420 - otto@cvs.openbsd.org 2005/10/25 06:37:47
1421 [openbsd-compat/sys-queue.h]
1422 Some uvm problem is being exposed with the more strict macros.
1423 Revert until we've found out what's causing the panics.
1424 - otto@cvs.openbsd.org 2005/11/25 08:06:25
1425 [openbsd-compat/sys-queue.h]
1426 Introduce debugging aid for queue macros. Disabled by default; but
1427 developers are encouraged to run with this enabled.
1428 ok krw@ fgsch@ deraadt@
1429 - otto@cvs.openbsd.org 2007/04/30 18:42:34
1430 [openbsd-compat/sys-queue.h]
1431 Enable QUEUE_MACRO_DEBUG on DIAGNOSTIC kernels.
1432 Input and okays from krw@, millert@, otto@, deraadt@, miod@.
1433 - millert@cvs.openbsd.org 2004/10/07 16:56:11
1434 GLOB_NOESCAPE is POSIX so move it out of the #ifndef _POSIX_SOURCE
1435 block.
1436 (NB. mostly an RCS ID sync, as portable strips out the conditionals)
1437 - (djm) [regress/sftp-cmds.sh]
1438 Use more restrictive glob to pick up test files from /bin - some platforms
1439 ship broken symlinks there which could spoil the test.
1440 - (djm) [openbsd-compat/bindresvport.c]
1441 Sync RCS ID after irrelevant (for portable OpenSSH) header shuffling
1442
144320070927
1444 - (dtucker) [configure.ac atomicio.c] Fall back to including <sys/poll.h> if
1445 we don't have <poll.h> (eq QNX). From bacon at cs nyu edu.
1446 - (dtucker) [configure.ac defines.h] Shadow expiry does not work on QNX6
1447 so disable it for that platform. From bacon at cs nyu edu.
1448
144920070921
1450 - (djm) [atomicio.c] Fix spin avoidance for platforms that define
1451 EWOULDBLOCK; patch from ben AT psc.edu
1452
145320070917
1454 - (djm) OpenBSD CVS Sync
1455 - djm@cvs.openbsd.org 2007/08/23 02:49:43
1456 [auth-passwd.c auth.c session.c]
1457 unifdef HAVE_LOGIN_CAP; ok deraadt@ millert@
1458 NB. RCS ID sync only for portable
1459 - djm@cvs.openbsd.org 2007/08/23 02:55:51
1460 [auth-passwd.c auth.c session.c]
1461 missed include bits from last commit
1462 NB. RCS ID sync only for portable
1463 - djm@cvs.openbsd.org 2007/08/23 03:06:10
1464 [auth.h]
1465 login_cap.h doesn't belong here
1466 NB. RCS ID sync only for portable
1467 - djm@cvs.openbsd.org 2007/08/23 03:22:16
1468 [auth2-none.c sshd_config sshd_config.5]
1469 Support "Banner=none" to disable displaying of the pre-login banner;
1470 ok dtucker@ deraadt@
1471 - djm@cvs.openbsd.org 2007/08/23 03:23:26
1472 [sshconnect.c]
1473 Execute ProxyCommands with $SHELL rather than /bin/sh unconditionally
1474 - djm@cvs.openbsd.org 2007/09/04 03:21:03
1475 [clientloop.c monitor.c monitor_fdpass.c monitor_fdpass.h]
1476 [monitor_wrap.c ssh.c]
1477 make file descriptor passing code return an error rather than call fatal()
1478 when it encounters problems, and use this to make session multiplexing
1479 masters survive slaves failing to pass all stdio FDs; ok markus@
1480 - djm@cvs.openbsd.org 2007/09/04 11:15:56
1481 [ssh.c sshconnect.c sshconnect.h]
1482 make ssh(1)'s ConnectTimeout option apply to both the TCP connection and
1483 SSH banner exchange (previously it just covered the TCP connection).
1484 This allows callers of ssh(1) to better detect and deal with stuck servers
1485 that accept a TCP connection but don't progress the protocol, and also
1486 makes ConnectTimeout useful for connections via a ProxyCommand;
1487 feedback and "looks ok" markus@
1488 - sobrado@cvs.openbsd.org 2007/09/09 11:38:01
1489 [ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.c]
1490 sort synopsis and options in ssh-agent(1); usage is lowercase
1491 ok jmc@
1492 - stevesk@cvs.openbsd.org 2007/09/11 04:36:29
1493 [sshpty.c]
1494 sort #include
1495 NB. RCS ID sync only
1496 - gilles@cvs.openbsd.org 2007/09/11 15:47:17
1497 [session.c ssh-keygen.c sshlogin.c]
1498 use strcspn to properly overwrite '\n' in fgets returned buffer
1499 ok pyr@, ray@, millert@, moritz@, chl@
1500 - stevesk@cvs.openbsd.org 2007/09/11 23:49:09
1501 [sshpty.c]
1502 remove #if defined block not needed; ok markus@ dtucker@
1503 NB. RCS ID sync only
1504 - stevesk@cvs.openbsd.org 2007/09/12 19:39:19
1505 [umac.c]
1506 use xmalloc() and xfree(); ok markus@ pvalchev@
1507 - djm@cvs.openbsd.org 2007/09/13 04:39:04
1508 [sftp-server.c]
1509 fix incorrect test when setting syslog facility; from Jan Pechanec
1510 - djm@cvs.openbsd.org 2007/09/16 00:55:52
1511 [sftp-client.c]
1512 use off_t instead of u_int64_t for file offsets, matching what the
1513 progressmeter code expects; bz #842
1514 - (tim) [defines.h] Fix regression in long password support on OpenServer 6.
1515 Problem report and additional testing rac AT tenzing.org.
1516
151720070914
1518 - (dtucker) [openbsd-compat/bsd-asprintf.c] Plug mem leak in error path.
1519 Patch from Jan.Pechanec at sun com.
1520
152120070910
1522 - (dtucker) [openbsd-compat/regress/closefromtest.c] Bug #1358: Always
1523 return 0 on successful test. From David.Leonard at quest com.
1524 - (tim) [configure.ac] Autoconf didn't define HAVE_LIBIAF because we
1525 did a AC_CHECK_FUNCS within the AC_CHECK_LIB test.
1526
120070817 152720070817
2 - (dtucker) [sshd.8] Many Linux variants use a single "!" to denote locked 1528 - (dtucker) [sshd.8] Many Linux variants use a single "!" to denote locked
3 accounts and that's what the code looks for, so make man page and code 1529 accounts and that's what the code looks for, so make man page and code
@@ -3184,4 +4710,4 @@
3184 OpenServer 6 and add osr5bigcrypt support so when someone migrates 4710 OpenServer 6 and add osr5bigcrypt support so when someone migrates
3185 passwords between UnixWare and OpenServer they will still work. OK dtucker@ 4711 passwords between UnixWare and OpenServer they will still work. OK dtucker@
3186 4712
3187$Id: ChangeLog,v 1.4738.2.1 2007/09/04 06:49:09 djm Exp $ 4713$Id: ChangeLog,v 1.5095 2008/07/21 08:22:25 djm Exp $
diff --git a/Makefile.in b/Makefile.in
index 2486edc95..c1b7ab5a6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.285 2007/06/11 04:01:42 djm Exp $ 1# $Id: Makefile.in,v 1.297 2008/07/08 14:21:12 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@
@@ -67,14 +67,14 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
67 cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ 67 cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
68 compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ 68 compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
69 log.o match.o md-sha256.o moduli.o nchan.o packet.o \ 69 log.o match.o md-sha256.o moduli.o nchan.o packet.o \
70 readpass.o rsa.o ttymodes.o xmalloc.o \ 70 readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
71 atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ 71 atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
72 monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ 72 monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
73 kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ 73 kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
74 entropy.o scard-opensc.o gss-genr.o umac.o 74 entropy.o scard-opensc.o gss-genr.o umac.o
75 75
76SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 76SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
77 sshconnect.o sshconnect1.o sshconnect2.o 77 sshconnect.o sshconnect1.o sshconnect2.o mux.o
78 78
79SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ 79SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
80 sshpty.o sshlogin.o servconf.o serverloop.o \ 80 sshpty.o sshlogin.o servconf.o serverloop.o \
@@ -86,10 +86,10 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
86 auth-krb5.o \ 86 auth-krb5.o \
87 auth2-gss.o gss-serv.o gss-serv-krb5.o \ 87 auth2-gss.o gss-serv.o gss-serv-krb5.o \
88 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ 88 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
89 audit.o audit-bsm.o platform.o 89 audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
90 90
91MANPAGES = 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-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out 91MANPAGES = 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-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
92MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 92MANPAGES_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-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
93MANTYPE = @MANTYPE@ 93MANTYPE = @MANTYPE@
94 94
95CONFIGFILES=sshd_config.out ssh_config.out moduli.out 95CONFIGFILES=sshd_config.out ssh_config.out moduli.out
@@ -106,6 +106,7 @@ PATHSUBS = \
106 -e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \ 106 -e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \
107 -e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \ 107 -e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \
108 -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \ 108 -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \
109 -e 's|/etc/moduli|$(sysconfdir)/moduli|g' \
109 -e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \ 110 -e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \
110 -e 's|/etc/ssh/sshrc|$(sysconfdir)/sshrc|g' \ 111 -e 's|/etc/ssh/sshrc|$(sysconfdir)/sshrc|g' \
111 -e 's|/usr/X11R6/bin/xauth|$(XAUTH_PATH)|g' \ 112 -e 's|/usr/X11R6/bin/xauth|$(XAUTH_PATH)|g' \
@@ -156,8 +157,8 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
156ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o 157ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
157 $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) 158 $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
158 159
159sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o 160sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
160 $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 161 $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
161 162
162sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o 163sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
163 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) 164 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
@@ -270,6 +271,7 @@ install-files: scard-install
270 $(INSTALL) -m 644 ssh-agent.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 271 $(INSTALL) -m 644 ssh-agent.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
271 $(INSTALL) -m 644 ssh-keygen.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 272 $(INSTALL) -m 644 ssh-keygen.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
272 $(INSTALL) -m 644 ssh-keyscan.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1 273 $(INSTALL) -m 644 ssh-keyscan.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
274 $(INSTALL) -m 644 moduli.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/moduli.5
273 $(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5 275 $(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
274 $(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5 276 $(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5
275 $(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 277 $(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
@@ -378,7 +380,7 @@ uninstall:
378 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 380 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
379 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 381 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
380 382
381tests: $(TARGETS) 383tests interop-tests: $(TARGETS)
382 BUILDDIR=`pwd`; \ 384 BUILDDIR=`pwd`; \
383 [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ 385 [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \
384 [ -f `pwd`/regress/Makefile ] || \ 386 [ -f `pwd`/regress/Makefile ] || \
@@ -392,6 +394,10 @@ tests: $(TARGETS)
392 TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \ 394 TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \
393 TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \ 395 TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \
394 TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \ 396 TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \
397 TEST_SSH_PLINK="plink"; \
398 TEST_SSH_PUTTYGEN="puttygen"; \
399 TEST_SSH_CONCH="conch"; \
400 TEST_SSH_IPV6="@TEST_SSH_IPV6@" ; \
395 cd $(srcdir)/regress || exit $$?; \ 401 cd $(srcdir)/regress || exit $$?; \
396 $(MAKE) \ 402 $(MAKE) \
397 .OBJDIR="$${BUILDDIR}/regress" \ 403 .OBJDIR="$${BUILDDIR}/regress" \
@@ -408,8 +414,12 @@ tests: $(TARGETS)
408 TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \ 414 TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \
409 TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \ 415 TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \
410 TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \ 416 TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \
417 TEST_SSH_PLINK="$${TEST_SSH_PLINK}" \
418 TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \
419 TEST_SSH_CONCH="$${TEST_SSH_CONCH}" \
420 TEST_SSH_IPV6="@TEST_SSH_IPV6@" \
411 EXEEXT="$(EXEEXT)" \ 421 EXEEXT="$(EXEEXT)" \
412 $@ 422 $@ && echo all tests passed
413 423
414compat-tests: $(LIBCOMPAT) 424compat-tests: $(LIBCOMPAT)
415 (cd openbsd-compat/regress && $(MAKE)) 425 (cd openbsd-compat/regress && $(MAKE))
diff --git a/PROTOCOL b/PROTOCOL
new file mode 100644
index 000000000..37fd536d9
--- /dev/null
+++ b/PROTOCOL
@@ -0,0 +1,243 @@
1This documents OpenSSH's deviations and extensions to the published SSH
2protocol.
3
4Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH
5filexfer protocol described in:
6
7http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt
8
9Features from newer versions of the draft are not supported, unless
10explicitly implemented as extensions described below.
11
12The protocol used by OpenSSH's ssh-agent is described in the file
13PROTOCOL.agent
14
151. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
16
17This is a new transport-layer MAC method using the UMAC algorithm
18(rfc4418). This method is identical to the "umac-64" method documented
19in:
20
21http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
22
232. transport: Protocol 2 compression algorithm "zlib@openssh.com"
24
25This transport-layer compression method uses the zlib compression
26algorithm (identical to the "zlib" method in rfc4253), but delays the
27start of compression until after authentication has completed. This
28avoids exposing compression code to attacks from unauthenticated users.
29
30The method is documented in:
31
32http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
33
343. connection: Channel write close extension "eow@openssh.com"
35
36The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
37message to allow an endpoint to signal its peer that it will send no
38more data over a channel. Unfortunately, there is no symmetric way for
39an endpoint to request that its peer should cease sending data to it
40while still keeping the channel open for the endpoint to send data to
41the peer.
42
43This is desirable, since it saves the transmission of data that would
44otherwise need to be discarded and it allows an endpoint to signal local
45processes of the condition, e.g. by closing the corresponding file
46descriptor.
47
48OpenSSH implements a channel extension message to perform this
49signalling: "eow@openssh.com" (End Of Write). This message is sent by
50an endpoint when the local output of a session channel is closed or
51experiences a write error. The message is formatted as follows:
52
53 byte SSH_MSG_CHANNEL_REQUEST
54 uint32 recipient channel
55 string "eow@openssh.com"
56 boolean FALSE
57
58On receiving this message, the peer SHOULD cease sending data of
59the channel and MAY signal the process from which the channel data
60originates (e.g. by closing its read file descriptor).
61
62As with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does
63remain open after a "eow@openssh.com" has been sent and more data may
64still be sent in the other direction. This message does not consume
65window space and may be sent even if no window space is available.
66
674. connection: disallow additional sessions extension
68 "no-more-sessions@openssh.com"
69
70Most SSH connections will only ever request a single session, but a
71attacker may abuse a running ssh client to surreptitiously open
72additional sessions under their control. OpenSSH provides a global
73request "no-more-sessions@openssh.com" to mitigate this attack.
74
75When an OpenSSH client expects that it will never open another session
76(i.e. it has been started with connection multiplexing disabled), it
77will send the following global request:
78
79 byte SSH_MSG_GLOBAL_REQUEST
80 string "no-more-sessions@openssh.com"
81 char want-reply
82
83On receipt of such a message, an OpenSSH server will refuse to open
84future channels of type "session" and instead immediately abort the
85connection.
86
87Note that this is not a general defence against compromised clients
88(that is impossible), but it thwarts a simple attack.
89
905. connection: Tunnel forward extension "tun@openssh.com"
91
92OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
93channel type. This channel type supports forwarding of network packets
94with datagram boundaries intact between endpoints equipped with
95interfaces like the BSD tun(4) device. Tunnel forwarding channels are
96requested by the client with the following packet:
97
98 byte SSH_MSG_CHANNEL_OPEN
99 string "tun@openssh.com"
100 uint32 sender channel
101 uint32 initial window size
102 uint32 maximum packet size
103 uint32 tunnel mode
104 uint32 remote unit number
105
106The "tunnel mode" parameter specifies whether the tunnel should forward
107layer 2 frames or layer 3 packets. It may take one of the following values:
108
109 SSH_TUNMODE_POINTOPOINT 1 /* layer 3 packets */
110 SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */
111
112The "tunnel unit number" specifies the remote interface number, or may
113be zero to allow the server to automatically chose an interface. A server
114that is not willing to open a client-specified unit should refuse the
115request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful open,
116the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
117
118Once established the client and server may exchange packet or frames
119over the tunnel channel by encapsulating them in SSH protocol strings
120and sending them as channel data. This ensures that packet boundaries
121are kept intact. Specifically, packets are transmitted using normal
122SSH_MSG_CHANNEL_DATA packets:
123
124 byte SSH_MSG_CHANNEL_DATA
125 uint32 recipient channel
126 string data
127
128The contents of the "data" field for layer 3 packets is:
129
130 uint32 packet length
131 uint32 address family
132 byte[packet length - 4] packet data
133
134The "address family" field identifies the type of packet in the message.
135It may be one of:
136
137 SSH_TUN_AF_INET 2 /* IPv4 */
138 SSH_TUN_AF_INET6 24 /* IPv6 */
139
140The "packet data" field consists of the IPv4/IPv6 datagram itself
141without any link layer header.
142
143The contents of the "data" field for layer 3 packets is:
144
145 uint32 packet length
146 byte[packet length] frame
147
148The "frame" field contains an IEEE 802.3 Ethernet frame, including
149header.
150
1516. sftp: Reversal of arguments to SSH_FXP_SYMLINK
152
153When OpenSSH's sftp-server was implemented, the order of the arguments
154to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
155the reversal was not noticed until the server was widely deployed. Since
156fixing this to follow the specification would cause incompatibility, the
157current order was retained. For correct operation, clients should send
158SSH_FXP_SYMLINK as follows:
159
160 uint32 id
161 string targetpath
162 string linkpath
163
1647. sftp: Server extension announcement in SSH_FXP_VERSION
165
166OpenSSH's sftp-server lists the extensions it supports using the
167standard extension announcement mechanism in the SSH_FXP_VERSION server
168hello packet:
169
170 uint32 3 /* protocol version */
171 string ext1-name
172 string ext1-version
173 string ext2-name
174 string ext2-version
175 ...
176 string extN-name
177 string extN-version
178
179Each extension reports its integer version number as an ASCII encoded
180string, e.g. "1". The version will be incremented if the extension is
181ever changed in an incompatible way. The server MAY advertise the same
182extension with multiple versions (though this is unlikely). Clients MUST
183check the version number before attempting to use the extension.
184
1858. sftp: Extension request "posix-rename@openssh.com"
186
187This operation provides a rename operation with POSIX semantics, which
188are different to those provided by the standard SSH_FXP_RENAME in
189draft-ietf-secsh-filexfer-02.txt. This request is implemented as a
190SSH_FXP_EXTENDED request with the following format:
191
192 uint32 id
193 string "posix-rename@openssh.com"
194 string oldpath
195 string newpath
196
197On receiving this request the server will perform the POSIX operation
198rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
199This extension is advertised in the SSH_FXP_VERSION hello with version
200"1".
201
2029. sftp: Extension requests "statvfs@openssh.com" and
203 "fstatvfs@openssh.com"
204
205These requests correspond to the statvfs and fstatvfs POSIX system
206interfaces. The "statvfs@openssh.com" request operates on an explicit
207pathname, and is formatted as follows:
208
209 uint32 id
210 string "statvfs@openssh.com"
211 string path
212
213The "fstatvfs@openssh.com" operates on an open file handle:
214
215 uint32 id
216 string "fstatvfs@openssh.com"
217 string handle
218
219These requests return a SSH_FXP_STATUS reply on failure. On success they
220return the following SSH_FXP_EXTENDED_REPLY reply:
221
222 uint32 id
223 uint64 f_bsize /* file system block size */
224 uint64 f_frsize /* fundamental fs block size */
225 uint64 f_blocks /* number of blocks (unit f_frsize) */
226 uint64 f_bfree /* free blocks in file system */
227 uint64 f_bavail /* free blocks for non-root */
228 uint64 f_files /* total file inodes */
229 uint64 f_ffree /* free file inodes */
230 uint64 f_favail /* free file inodes for to non-root */
231 uint64 f_fsid /* file system id */
232 uint64 f_flag /* bit mask of f_flag values */
233 uint64 f_namemax /* maximum filename length */
234
235The values of the f_flag bitmask are as follows:
236
237 #define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */
238 #define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */
239
240Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
241advertised in the SSH_FXP_VERSION hello with version "2".
242
243$OpenBSD: PROTOCOL,v 1.11 2008/07/05 05:16:01 djm Exp $
diff --git a/PROTOCOL.agent b/PROTOCOL.agent
new file mode 100644
index 000000000..49adbdd5c
--- /dev/null
+++ b/PROTOCOL.agent
@@ -0,0 +1,516 @@
1This describes the protocol used by OpenSSH's ssh-agent.
2
3OpenSSH's agent supports managing keys for the standard SSH protocol
42 as well as the legacy SSH protocol 1. Support for these key types
5is almost completely disjoint - in all but a few cases, operations on
6protocol 2 keys cannot see or affect protocol 1 keys and vice-versa.
7
8Protocol 1 and protocol 2 keys are separated because of the differing
9cryptographic usage: protocol 1 private RSA keys are used to decrypt
10challenges that were encrypted with the corresponding public key,
11whereas protocol 2 RSA private keys are used to sign challenges with
12a private key for verification with the corresponding public key. It
13is considered unsound practice to use the same key for signing and
14encryption.
15
16With a couple of exceptions, the protocol message names used in this
17document indicate which type of key the message relates to. SSH_*
18messages refer to protocol 1 keys only. SSH2_* messages refer to
19protocol 2 keys. Furthermore, the names also indicate whether the
20message is a request to the agent (*_AGENTC_*) or a reply from the
21agent (*_AGENT_*). Section 3 below contains the mapping of the
22protocol message names to their integer values.
23
241. Data types
25
26Because of support for legacy SSH protocol 1 keys, OpenSSH's agent
27protocol makes use of some data types not defined in RFC 4251.
28
291.1 uint16
30
31The "uint16" data type is a simple MSB-first 16 bit unsigned integer
32encoded in two bytes.
33
341.2 mpint1
35
36The "mpint1" type represents an arbitrary precision integer (bignum).
37Its format is as follows:
38
39 uint16 bits
40 byte[(bits + 7) / 8] bignum
41
42"bignum" contains an unsigned arbitrary precision integer encoded as
43eight bits per byte in big-endian (MSB first) format.
44
45Note the difference between the "mpint1" encoding and the "mpint"
46encoding defined in RFC 4251. Also note that the length of the encoded
47integer is specified in bits, not bytes and that the byte length of
48the integer must be calculated by rounding up the number of bits to the
49nearest eight.
50
512. Protocol Messages
52
53All protocol messages are prefixed with their length in bytes, encoded
54as a 32 bit unsigned integer. Specifically:
55
56 uint32 message_length
57 byte[message_length] message
58
59The following message descriptions refer only to the content the
60"message" field.
61
622.1 Generic server responses
63
64The following generic messages may be sent by the server in response to
65requests from the client. On success the agent may reply either with:
66
67 byte SSH_AGENT_SUCCESS
68
69or a request-specific success message.
70
71On failure, the agent may reply with:
72
73 byte SSH_AGENT_FAILURE
74
75SSH_AGENT_FAILURE messages are also sent in reply to unknown request
76types.
77
782.2 Adding keys to the agent
79
80Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and
81SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys
82respectively.
83
84Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
85and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional
86"constraints" on their usage.
87
88OpenSSH may be built with support for keys hosted on a smartcard
89or other hardware security module. These keys may be added
90to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and
91SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests.
92
932.2.1 Key constraints
94
95The OpenSSH agent supports some basic optional constraints on key usage.
96At present there are two constraints defined.
97
98The first constraint limits the validity duration of a key. It is
99encoded as:
100
101 byte SSH_AGENT_CONSTRAIN_LIFETIME
102 uint32 seconds
103
104Where "seconds" contains the number of seconds that the key shall remain
105valid measured from the moment that the agent receives it. After the
106validity period has expired, OpenSSH's agent will erase these keys from
107memory.
108
109The second constraint requires the agent to seek explicit user
110confirmation before performing private key operations with the loaded
111key. This constraint is encoded as:
112
113 byte SSH_AGENT_CONSTRAIN_CONFIRM
114
115Zero or more constraints may be specified when adding a key with one
116of the *_CONSTRAINED requests. Multiple constraints are appended
117consecutively to the end of the request:
118
119 byte constraint1_type
120 .... constraint1_data
121 byte constraint2_type
122 .... constraint2_data
123 ....
124 byte constraintN_type
125 .... constraintN_data
126
127Such a sequence of zero or more constraints will be referred to below
128as "constraint[]". Agents may determine whether there are constraints
129by checking whether additional data exists in the "add key" request
130after the key data itself. OpenSSH will refuse to add a key if it
131contains unknown constraints.
132
1332.2.2 Add protocol 1 key
134
135A client may add a protocol 1 key to an agent with the following
136request:
137
138 byte SSH_AGENTC_ADD_RSA_IDENTITY or
139 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
140 uint32 ignored
141 mpint1 rsa_n
142 mpint1 rsa_e
143 mpint1 rsa_d
144 mpint1 rsa_iqmp
145 mpint1 rsa_q
146 mpint1 rsa_p
147 string key_comment
148 constraint[] key_constraints
149
150Note that there is some redundancy in the key parameters; a key could be
151fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra
152computation.
153
154"key_constraints" may only be present if the request type is
155SSH_AGENTC_ADD_RSA_IDENTITY.
156
157The agent will reply with a SSH_AGENT_SUCCESS if the key has been
158successfully added or a SSH_AGENT_FAILURE if an error occurred.
159
1602.2.3 Add protocol 2 key
161
162The OpenSSH agent supports DSA and RSA keys for protocol 2. DSA keys may
163be added using the following request
164
165 byte SSH2_AGENTC_ADD_IDENTITY or
166 SSH2_AGENTC_ADD_ID_CONSTRAINED
167 string "ssh-dss"
168 mpint dsa_p
169 mpint dsa_q
170 mpint dsa_g
171 mpint dsa_public_key
172 mpint dsa_private_key
173 string key_comment
174 constraint[] key_constraints
175
176RSA keys may be added with this request:
177
178 byte SSH2_AGENTC_ADD_IDENTITY or
179 SSH2_AGENTC_ADD_ID_CONSTRAINED
180 string "ssh-rsa"
181 mpint rsa_n
182 mpint rsa_e
183 mpint rsa_d
184 mpint rsa_iqmp
185 mpint rsa_p
186 mpint rsa_q
187 string key_comment
188 constraint[] key_constraints
189
190Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
191order to the protocol 1 add keys message. As with the corresponding
192protocol 1 "add key" request, the private key is overspecified to avoid
193redundant processing.
194
195For both DSA and RSA key add requests, "key_constraints" may only be
196present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED.
197
198The agent will reply with a SSH_AGENT_SUCCESS if the key has been
199successfully added or a SSH_AGENT_FAILURE if an error occurred.
200
2012.2.4 Loading keys from a smartcard
202
203The OpenSSH agent may have optional smartcard support built in to it. If
204so, it supports an operation to load keys from a smartcard. Technically,
205only the public components of the keys are loaded into the agent so
206this operation really arranges for future private key operations to be
207delegated to the smartcard.
208
209 byte SSH_AGENTC_ADD_SMARTCARD_KEY or
210 SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
211 string reader_id
212 string pin
213 constraint[] key_constraints
214
215"reader_id" is an identifier to a smartcard reader and "pin"
216is a PIN or passphrase used to unlock the private key(s) on the
217device. "key_constraints" may only be present if the request type is
218SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED.
219
220This operation may load all SSH keys that are unlocked using the
221"pin" on the specified reader. The type of key loaded (protocol 1
222or protocol 2) will be specified by the smartcard itself, it is not
223client-specified.
224
225The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
226been successfully loaded or a SSH_AGENT_FAILURE if an error occurred.
227The agent will also return SSH_AGENT_FAILURE if it does not support
228smartcards.
229
2302.3 Removing multiple keys
231
232A client may request that an agent delete all protocol 1 keys using the
233following request:
234
235 byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES
236
237This message requests the deletion of all protocol 2 keys:
238
239 byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES
240
241On success, the agent will delete all keys of the requested type and
242reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent
243will reply with SSH_AGENT_FAILURE.
244
245Note that, to delete all keys (both protocol 1 and 2), a client
246must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a
247SSH2_AGENTC_REMOVE_ALL_IDENTITIES request.
248
2492.4 Removing specific keys
250
2512.4.1 Removing a protocol 1 key
252
253Removal of a protocol 1 key may be requested with the following message:
254
255 byte SSH_AGENTC_REMOVE_RSA_IDENTITY
256 uint32 key_bits
257 mpint1 rsa_e
258 mpint1 rsa_n
259
260Note that key_bits is strictly redundant, as it may be inferred by the
261length of rsa_n.
262
263The agent will delete any private key matching the specified public key
264and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
265return SSH_AGENT_FAILURE.
266
2672.4.2 Removing a protocol 2 key
268
269Protocol 2 keys may be removed with the following request:
270
271 byte SSH2_AGENTC_REMOVE_IDENTITY
272 string key_blob
273
274Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
275Algorithms" for either of the supported key types: "ssh-dss" or
276"ssh-rsa".
277
278The agent will delete any private key matching the specified public key
279and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
280return SSH_AGENT_FAILURE.
281
2822.4.3 Removing keys loaded from a smartcard
283
284A client may request that a server remove one or more smartcard-hosted
285keys using this message:
286
287 byte SSH_AGENTC_REMOVE_SMARTCARD_KEY
288 string reader_id
289 string pin
290
291"reader_id" the an identifier to a smartcard reader and "pin" is a PIN
292or passphrase used to unlock the private key(s) on the device.
293
294When this message is received, and if the agent supports
295smartcard-hosted keys, it will delete all keys that are hosted on the
296specified smartcard that may be accessed with the given "pin".
297
298The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
299been successfully removed or a SSH_AGENT_FAILURE if an error occurred.
300The agent will also return SSH_AGENT_FAILURE if it does not support
301smartcards.
302
3032.5 Requesting a list of known keys
304
305An agent may be requested to list which keys it holds. Different
306requests exist for protocol 1 and protocol 2 keys.
307
3082.5.1 Requesting a list of protocol 1 keys
309
310To request a list of protocol 1 keys that are held in the agent, a
311client may send the following message:
312
313 byte SSH_AGENTC_REQUEST_RSA_IDENTITIES
314
315The agent will reply with the following message:
316
317 byte SSH_AGENT_RSA_IDENTITIES_ANSWER
318 uint32 num_keys
319
320Followed by zero or more consecutive keys, encoded as:
321
322 uint32 bits
323 mpint1 rsa_e
324 mpint1 rsa_n
325 string key_comment
326
3272.5.2 Requesting a list of protocol 2 keys
328
329A client may send the following message to request a list of
330protocol 2 keys that are stored in the agent:
331
332 byte SSH2_AGENTC_REQUEST_IDENTITIES
333
334The agent will reply with the following message header:
335
336 byte SSH2_AGENT_IDENTITIES_ANSWER
337 uint32 num_keys
338
339Followed by zero or more consecutive keys, encoded as:
340
341 string key_blob
342 string key_comment
343
344Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
345Algorithms" for either of the supported key types: "ssh-dss" or
346"ssh-rsa".
347
3482.6 Private key operations
349
350The purpose of the agent is to perform private key operations, such as
351signing and encryption without requiring a passphrase to unlock the
352key and without allowing the private key itself to be exposed. There
353are separate requests for the protocol 1 and protocol 2 private key
354operations.
355
3562.6.1 Protocol 1 private key challenge
357
358The private key operation used in version 1 of the SSH protocol is
359decrypting a challenge that has been encrypted with a public key.
360It may be requested using this message:
361
362 byte SSH_AGENTC_RSA_CHALLENGE
363 uint32 ignored
364 mpint1 rsa_e
365 mpint1 rsa_n
366 mpint1 encrypted_challenge
367 byte[16] session_id
368 uint32 response_type /* must be 1 */
369
370"rsa_e" and "rsa_n" are used to identify which private key to use.
371"encrypted_challenge" is a challenge blob that has (presumably)
372been encrypted with the public key and must be in the range
3731 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1
374session ID (computed from the server host key, the server semi-ephemeral
375key and the session cookie).
376
377"ignored" and "response_type" exist for compatibility with legacy
378implementations. "response_type" must be equal to 1; other response
379types are not supported.
380
381On receiving this request, the server decrypts the "encrypted_challenge"
382using the private key matching the supplied (rsa_e, rsa_n) values. For
383the response derivation, the decrypted challenge is represented as an
384unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values
385smaller than 2^248 will have leading 0 bytes).
386
387The response value is then calculated as:
388
389 response = MD5(decrypted_challenge || session_id)
390
391and returned in the following message
392
393 byte SSH_AGENT_RSA_RESPONSE
394 byte[16] response
395
396If the agent cannot find the key specified by the supplied (rsa_e,
397rsa_n) then it will return SSH_AGENT_FAILURE.
398
3992.6.2 Protocol 2 private key signature request
400
401A client may use the following message to request signing of data using
402a protocol 2 key:
403
404 byte SSH2_AGENTC_SIGN_REQUEST
405 string key_blob
406 string data
407 uint32 flags
408
409Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
410Algorithms" for either of the supported key types: "ssh-dss" or
411"ssh-rsa". "flags" is a bit-mask, but at present only one possible value
412is defined (see below for its meaning):
413
414 SSH_AGENT_OLD_SIGNATURE 1
415
416Upon receiving this request, the agent will look up the private key that
417corresponds to the public key contained in key_blob. It will use this
418private key to sign the "data" and produce a signature blob using the
419key type-specific method described in RFC 4253 section 6.6 "Public Key
420Algorithms".
421
422An exception to this is for "ssh-dss" keys where the "flags" word
423contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy
424signature encoding is used in lieu of the standard one. In this case,
425the DSA signature blob is encoded as:
426
427 byte[40] signature
428
429The signature will be returned in the response message:
430
431 byte SSH2_AGENT_SIGN_RESPONSE
432 string signature_blob
433
434If the agent cannot find the key specified by the supplied key_blob then
435it will return SSH_AGENT_FAILURE.
436
4372.7 Locking or unlocking an agent
438
439The agent supports temporary locking with a passphrase to suspend
440processing of sensitive operations until it has been unlocked with the
441same passphrase. To lock an agent, a client send the following request:
442
443 byte SSH_AGENTC_LOCK
444 string passphrase
445
446Upon receipt of this message and if the agent is not already locked,
447it will suspend processing requests and return a SSH_AGENT_SUCCESS
448reply. If the agent is already locked, it will return SSH_AGENT_FAILURE.
449
450While locked, the agent will refuse all requests except
451SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and
452SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are
453treated specially by a locked agent: it will always return an empty list
454of keys.
455
456To unlock an agent, a client may request:
457
458 byte SSH_AGENTC_UNLOCK
459 string passphrase
460
461If the passphrase matches and the agent is locked, then it will resume
462processing all requests and return SSH_AGENT_SUCCESS. If the agent
463is not locked or the passphrase does not match then it will return
464SSH_AGENT_FAILURE.
465
466Locking and unlocking affects both protocol 1 and protocol 2 keys.
467
4683. Protocol message numbers
469
4703.1 Requests from client to agent for protocol 1 key operations
471
472 SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
473 SSH_AGENTC_RSA_CHALLENGE 3
474 SSH_AGENTC_ADD_RSA_IDENTITY 7
475 SSH_AGENTC_REMOVE_RSA_IDENTITY 8
476 SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
477 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
478
4793.2 Requests from client to agent for protocol 2 key operations
480
481 SSH2_AGENTC_REQUEST_IDENTITIES 11
482 SSH2_AGENTC_SIGN_REQUEST 13
483 SSH2_AGENTC_ADD_IDENTITY 17
484 SSH2_AGENTC_REMOVE_IDENTITY 18
485 SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
486 SSH2_AGENTC_ADD_ID_CONSTRAINED 25
487
4883.3 Key-type independent requests from client to agent
489
490 SSH_AGENTC_ADD_SMARTCARD_KEY 20
491 SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
492 SSH_AGENTC_LOCK 22
493 SSH_AGENTC_UNLOCK 23
494 SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
495
4963.4 Generic replies from agent to client
497
498 SSH_AGENT_FAILURE 5
499 SSH_AGENT_SUCCESS 6
500
5013.5 Replies from agent to client for protocol 1 key operations
502
503 SSH_AGENT_RSA_IDENTITIES_ANSWER 2
504 SSH_AGENT_RSA_RESPONSE 4
505
5063.6 Replies from agent to client for protocol 2 key operations
507
508 SSH2_AGENT_IDENTITIES_ANSWER 12
509 SSH2_AGENT_SIGN_RESPONSE 14
510
5113.7 Key constraint identifiers
512
513 SSH_AGENT_CONSTRAIN_LIFETIME 1
514 SSH_AGENT_CONSTRAIN_CONFIRM 2
515
516$OpenBSD: PROTOCOL.agent,v 1.4 2008/07/01 23:12:47 stevesk Exp $
diff --git a/README b/README
index a76127439..183d92f70 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
1See http://www.openssh.com/txt/release-4.7 for the release notes. 1See http://www.openssh.com/txt/release-5.1 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.66 2007/08/15 09:22:20 dtucker Exp $ 65$Id: README,v 1.69 2008/07/21 08:21:52 djm Exp $
diff --git a/addrmatch.c b/addrmatch.c
new file mode 100644
index 000000000..2086afe84
--- /dev/null
+++ b/addrmatch.c
@@ -0,0 +1,421 @@
1/* $OpenBSD: addrmatch.c,v 1.3 2008/06/10 23:06:19 djm Exp $ */
2
3/*
4 * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
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 <sys/socket.h>
23#include <netinet/in.h>
24#include <arpa/inet.h>
25
26#include <netdb.h>
27#include <string.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <stdarg.h>
31
32#include "match.h"
33#include "log.h"
34
35struct xaddr {
36 sa_family_t af;
37 union {
38 struct in_addr v4;
39 struct in6_addr v6;
40 u_int8_t addr8[16];
41 u_int32_t addr32[4];
42 } xa; /* 128-bit address */
43 u_int32_t scope_id; /* iface scope id for v6 */
44#define v4 xa.v4
45#define v6 xa.v6
46#define addr8 xa.addr8
47#define addr32 xa.addr32
48};
49
50static int
51addr_unicast_masklen(int af)
52{
53 switch (af) {
54 case AF_INET:
55 return 32;
56 case AF_INET6:
57 return 128;
58 default:
59 return -1;
60 }
61}
62
63static inline int
64masklen_valid(int af, u_int masklen)
65{
66 switch (af) {
67 case AF_INET:
68 return masklen <= 32 ? 0 : -1;
69 case AF_INET6:
70 return masklen <= 128 ? 0 : -1;
71 default:
72 return -1;
73 }
74}
75
76/*
77 * Convert struct sockaddr to struct xaddr
78 * Returns 0 on success, -1 on failure.
79 */
80static int
81addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa)
82{
83 struct sockaddr_in *in4 = (struct sockaddr_in *)sa;
84 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
85
86 memset(xa, '\0', sizeof(*xa));
87
88 switch (sa->sa_family) {
89 case AF_INET:
90 if (slen < sizeof(*in4))
91 return -1;
92 xa->af = AF_INET;
93 memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4));
94 break;
95 case AF_INET6:
96 if (slen < sizeof(*in6))
97 return -1;
98 xa->af = AF_INET6;
99 memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6));
100 xa->scope_id = in6->sin6_scope_id;
101 break;
102 default:
103 return -1;
104 }
105
106 return 0;
107}
108
109/*
110 * Calculate a netmask of length 'l' for address family 'af' and
111 * store it in 'n'.
112 * Returns 0 on success, -1 on failure.
113 */
114static int
115addr_netmask(int af, u_int l, struct xaddr *n)
116{
117 int i;
118
119 if (masklen_valid(af, l) != 0 || n == NULL)
120 return -1;
121
122 memset(n, '\0', sizeof(*n));
123 switch (af) {
124 case AF_INET:
125 n->af = AF_INET;
126 n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff);
127 return 0;
128 case AF_INET6:
129 n->af = AF_INET6;
130 for (i = 0; i < 4 && l >= 32; i++, l -= 32)
131 n->addr32[i] = 0xffffffffU;
132 if (i < 4 && l != 0)
133 n->addr32[i] = htonl((0xffffffff << (32 - l)) &
134 0xffffffff);
135 return 0;
136 default:
137 return -1;
138 }
139}
140
141/*
142 * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'.
143 * Returns 0 on success, -1 on failure.
144 */
145static int
146addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b)
147{
148 int i;
149
150 if (dst == NULL || a == NULL || b == NULL || a->af != b->af)
151 return -1;
152
153 memcpy(dst, a, sizeof(*dst));
154 switch (a->af) {
155 case AF_INET:
156 dst->v4.s_addr &= b->v4.s_addr;
157 return 0;
158 case AF_INET6:
159 dst->scope_id = a->scope_id;
160 for (i = 0; i < 4; i++)
161 dst->addr32[i] &= b->addr32[i];
162 return 0;
163 default:
164 return -1;
165 }
166}
167
168/*
169 * Compare addresses 'a' and 'b'
170 * Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b)
171 */
172static int
173addr_cmp(const struct xaddr *a, const struct xaddr *b)
174{
175 int i;
176
177 if (a->af != b->af)
178 return a->af == AF_INET6 ? 1 : -1;
179
180 switch (a->af) {
181 case AF_INET:
182 if (a->v4.s_addr == b->v4.s_addr)
183 return 0;
184 return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1;
185 case AF_INET6:
186 for (i = 0; i < 16; i++)
187 if (a->addr8[i] - b->addr8[i] != 0)
188 return a->addr8[i] > b->addr8[i] ? 1 : -1;
189 if (a->scope_id == b->scope_id)
190 return 0;
191 return a->scope_id > b->scope_id ? 1 : -1;
192 default:
193 return -1;
194 }
195}
196
197/*
198 * Parse string address 'p' into 'n'
199 * Returns 0 on success, -1 on failure.
200 */
201static int
202addr_pton(const char *p, struct xaddr *n)
203{
204 struct addrinfo hints, *ai;
205
206 memset(&hints, '\0', sizeof(hints));
207 hints.ai_flags = AI_NUMERICHOST;
208
209 if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
210 return -1;
211
212 if (ai == NULL || ai->ai_addr == NULL)
213 return -1;
214
215 if (n != NULL &&
216 addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1) {
217 freeaddrinfo(ai);
218 return -1;
219 }
220
221 freeaddrinfo(ai);
222 return 0;
223}
224
225/*
226 * Perform bitwise negation of address
227 * Returns 0 on success, -1 on failure.
228 */
229static int
230addr_invert(struct xaddr *n)
231{
232 int i;
233
234 if (n == NULL)
235 return (-1);
236
237 switch (n->af) {
238 case AF_INET:
239 n->v4.s_addr = ~n->v4.s_addr;
240 return (0);
241 case AF_INET6:
242 for (i = 0; i < 4; i++)
243 n->addr32[i] = ~n->addr32[i];
244 return (0);
245 default:
246 return (-1);
247 }
248}
249
250/*
251 * Calculate a netmask of length 'l' for address family 'af' and
252 * store it in 'n'.
253 * Returns 0 on success, -1 on failure.
254 */
255static int
256addr_hostmask(int af, u_int l, struct xaddr *n)
257{
258 if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1)
259 return (-1);
260 return (0);
261}
262
263/*
264 * Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::)
265 * Returns 0 on if address is all-zeros, -1 if not all zeros or on failure.
266 */
267static int
268addr_is_all0s(const struct xaddr *a)
269{
270 int i;
271
272 switch (a->af) {
273 case AF_INET:
274 return (a->v4.s_addr == 0 ? 0 : -1);
275 case AF_INET6:;
276 for (i = 0; i < 4; i++)
277 if (a->addr32[i] != 0)
278 return (-1);
279 return (0);
280 default:
281 return (-1);
282 }
283}
284
285/*
286 * Test whether host portion of address 'a', as determined by 'masklen'
287 * is all zeros.
288 * Returns 0 on if host portion of address is all-zeros,
289 * -1 if not all zeros or on failure.
290 */
291static int
292addr_host_is_all0s(const struct xaddr *a, u_int masklen)
293{
294 struct xaddr tmp_addr, tmp_mask, tmp_result;
295
296 memcpy(&tmp_addr, a, sizeof(tmp_addr));
297 if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
298 return (-1);
299 if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1)
300 return (-1);
301 return (addr_is_all0s(&tmp_result));
302}
303
304/*
305 * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z).
306 * Return -1 on parse error, -2 on inconsistency or 0 on success.
307 */
308static int
309addr_pton_cidr(const char *p, struct xaddr *n, u_int *l)
310{
311 struct xaddr tmp;
312 long unsigned int masklen = 999;
313 char addrbuf[64], *mp, *cp;
314
315 /* Don't modify argument */
316 if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) > sizeof(addrbuf))
317 return -1;
318
319 if ((mp = strchr(addrbuf, '/')) != NULL) {
320 *mp = '\0';
321 mp++;
322 masklen = strtoul(mp, &cp, 10);
323 if (*mp == '\0' || *cp != '\0' || masklen > 128)
324 return -1;
325 }
326
327 if (addr_pton(addrbuf, &tmp) == -1)
328 return -1;
329
330 if (mp == NULL)
331 masklen = addr_unicast_masklen(tmp.af);
332 if (masklen_valid(tmp.af, masklen) == -1)
333 return -2;
334 if (addr_host_is_all0s(&tmp, masklen) != 0)
335 return -2;
336
337 if (n != NULL)
338 memcpy(n, &tmp, sizeof(*n));
339 if (l != NULL)
340 *l = masklen;
341
342 return 0;
343}
344
345static int
346addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen)
347{
348 struct xaddr tmp_mask, tmp_result;
349
350 if (host->af != net->af)
351 return -1;
352
353 if (addr_netmask(host->af, masklen, &tmp_mask) == -1)
354 return -1;
355 if (addr_and(&tmp_result, host, &tmp_mask) == -1)
356 return -1;
357 return addr_cmp(&tmp_result, net);
358}
359
360/*
361 * Match "addr" against list pattern list "_list", which may contain a
362 * mix of CIDR addresses and old-school wildcards.
363 *
364 * If addr is NULL, then no matching is performed, but _list is parsed
365 * and checked for well-formedness.
366 *
367 * Returns 1 on match found (never returned when addr == NULL).
368 * Returns 0 on if no match found, or no errors found when addr == NULL.
369 * Returns -1 on negated match found (never returned when addr == NULL).
370 * Returns -2 on invalid list entry.
371 */
372int
373addr_match_list(const char *addr, const char *_list)
374{
375 char *list, *cp, *o;
376 struct xaddr try_addr, match_addr;
377 u_int masklen, neg;
378 int ret = 0, r;
379
380 if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
381 debug2("%s: couldn't parse address %.100s", __func__, addr);
382 return 0;
383 }
384 if ((o = list = strdup(_list)) == NULL)
385 return -1;
386 while ((cp = strsep(&list, ",")) != NULL) {
387 neg = *cp == '!';
388 if (neg)
389 cp++;
390 if (*cp == '\0') {
391 ret = -2;
392 break;
393 }
394 /* Prefer CIDR address matching */
395 r = addr_pton_cidr(cp, &match_addr, &masklen);
396 if (r == -2) {
397 error("Inconsistent mask length for "
398 "network \"%.100s\"", cp);
399 ret = -2;
400 break;
401 } else if (r == 0) {
402 if (addr != NULL && addr_netmatch(&try_addr,
403 &match_addr, masklen) == 0) {
404 foundit:
405 if (neg) {
406 ret = -1;
407 break;
408 }
409 ret = 1;
410 }
411 continue;
412 } else {
413 /* If CIDR parse failed, try wildcard string match */
414 if (addr != NULL && match_pattern(addr, cp) == 1)
415 goto foundit;
416 }
417 }
418 free(o);
419
420 return ret;
421}
diff --git a/atomicio.c b/atomicio.c
index f32ff85ba..a6b2d127a 100644
--- a/atomicio.c
+++ b/atomicio.c
@@ -34,6 +34,10 @@
34#include <errno.h> 34#include <errno.h>
35#ifdef HAVE_POLL_H 35#ifdef HAVE_POLL_H
36#include <poll.h> 36#include <poll.h>
37#else
38# ifdef HAVE_SYS_POLL_H
39# include <sys/poll.h>
40# endif
37#endif 41#endif
38#include <string.h> 42#include <string.h>
39#include <unistd.h> 43#include <unistd.h>
@@ -57,13 +61,9 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
57 res = (f) (fd, s + pos, n - pos); 61 res = (f) (fd, s + pos, n - pos);
58 switch (res) { 62 switch (res) {
59 case -1: 63 case -1:
60#ifdef EWOULDBLOCK
61 if (errno == EINTR || errno == EWOULDBLOCK)
62#else
63 if (errno == EINTR) 64 if (errno == EINTR)
64#endif
65 continue; 65 continue;
66 if (errno == EAGAIN) { 66 if (errno == EAGAIN || errno == EWOULDBLOCK) {
67 (void)poll(&pfd, 1, -1); 67 (void)poll(&pfd, 1, -1);
68 continue; 68 continue;
69 } 69 }
@@ -97,20 +97,20 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
97 /* Make a copy of the iov array because we may modify it below */ 97 /* Make a copy of the iov array because we may modify it below */
98 memcpy(iov, _iov, iovcnt * sizeof(*_iov)); 98 memcpy(iov, _iov, iovcnt * sizeof(*_iov));
99 99
100#ifndef BROKEN_READV_COMPARISON
100 pfd.fd = fd; 101 pfd.fd = fd;
101 pfd.events = f == readv ? POLLIN : POLLOUT; 102 pfd.events = f == readv ? POLLIN : POLLOUT;
103#endif
102 for (; iovcnt > 0 && iov[0].iov_len > 0;) { 104 for (; iovcnt > 0 && iov[0].iov_len > 0;) {
103 res = (f) (fd, iov, iovcnt); 105 res = (f) (fd, iov, iovcnt);
104 switch (res) { 106 switch (res) {
105 case -1: 107 case -1:
106#ifdef EWOULDBLOCK
107 if (errno == EINTR || errno == EWOULDBLOCK)
108#else
109 if (errno == EINTR) 108 if (errno == EINTR)
110#endif
111 continue; 109 continue;
112 if (errno == EAGAIN) { 110 if (errno == EAGAIN || errno == EWOULDBLOCK) {
111#ifndef BROKEN_READV_COMPARISON
113 (void)poll(&pfd, 1, -1); 112 (void)poll(&pfd, 1, -1);
113#endif
114 continue; 114 continue;
115 } 115 }
116 return 0; 116 return 0;
diff --git a/audit-bsm.c b/audit-bsm.c
index c26b4caed..2c417bc27 100644
--- a/audit-bsm.c
+++ b/audit-bsm.c
@@ -1,4 +1,4 @@
1/* $Id: audit-bsm.c,v 1.5 2006/09/30 22:09:50 dtucker Exp $ */ 1/* $Id: audit-bsm.c,v 1.6 2008/02/25 10:05:04 dtucker Exp $ */
2 2
3/* 3/*
4 * TODO 4 * TODO
@@ -40,7 +40,9 @@
40#include <sys/types.h> 40#include <sys/types.h>
41 41
42#include <errno.h> 42#include <errno.h>
43#include <netdb.h>
43#include <stdarg.h> 44#include <stdarg.h>
45#include <string.h>
44#include <unistd.h> 46#include <unistd.h>
45 47
46#include "ssh.h" 48#include "ssh.h"
@@ -62,8 +64,6 @@
62#if defined(HAVE_GETAUDIT_ADDR) 64#if defined(HAVE_GETAUDIT_ADDR)
63#define AuditInfoStruct auditinfo_addr 65#define AuditInfoStruct auditinfo_addr
64#define AuditInfoTermID au_tid_addr_t 66#define AuditInfoTermID au_tid_addr_t
65#define GetAuditFunc(a,b) getaudit_addr((a),(b))
66#define GetAuditFuncText "getaudit_addr"
67#define SetAuditFunc(a,b) setaudit_addr((a),(b)) 67#define SetAuditFunc(a,b) setaudit_addr((a),(b))
68#define SetAuditFuncText "setaudit_addr" 68#define SetAuditFuncText "setaudit_addr"
69#define AUToSubjectFunc au_to_subject_ex 69#define AUToSubjectFunc au_to_subject_ex
@@ -71,18 +71,16 @@
71#else 71#else
72#define AuditInfoStruct auditinfo 72#define AuditInfoStruct auditinfo
73#define AuditInfoTermID au_tid_t 73#define AuditInfoTermID au_tid_t
74#define GetAuditFunc(a,b) getaudit(a)
75#define GetAuditFuncText "getaudit"
76#define SetAuditFunc(a,b) setaudit(a) 74#define SetAuditFunc(a,b) setaudit(a)
77#define SetAuditFuncText "setaudit" 75#define SetAuditFuncText "setaudit"
78#define AUToSubjectFunc au_to_subject 76#define AUToSubjectFunc au_to_subject
79#define AUToReturnFunc(a,b) au_to_return((a), (u_int)(b)) 77#define AUToReturnFunc(a,b) au_to_return((a), (u_int)(b))
80#endif 78#endif
81 79
80#ifndef cannot_audit
82extern int cannot_audit(int); 81extern int cannot_audit(int);
82#endif
83extern void aug_init(void); 83extern void aug_init(void);
84extern dev_t aug_get_port(void);
85extern int aug_get_machine(char *, u_int32_t *, u_int32_t *);
86extern void aug_save_auid(au_id_t); 84extern void aug_save_auid(au_id_t);
87extern void aug_save_uid(uid_t); 85extern void aug_save_uid(uid_t);
88extern void aug_save_euid(uid_t); 86extern void aug_save_euid(uid_t);
@@ -119,6 +117,51 @@ static AuditInfoTermID ssh_bsm_tid;
119/* Below is the low-level BSM interface code */ 117/* Below is the low-level BSM interface code */
120 118
121/* 119/*
120 * aug_get_machine is only required on IPv6 capable machines, we use a
121 * different mechanism in audit_connection_from() for IPv4-only machines.
122 * getaudit_addr() is only present on IPv6 capable machines.
123 */
124#if defined(HAVE_AUG_GET_MACHINE) || !defined(HAVE_GETAUDIT_ADDR)
125extern int aug_get_machine(char *, u_int32_t *, u_int32_t *);
126#else
127static int
128aug_get_machine(char *host, u_int32_t *addr, u_int32_t *type)
129{
130 struct addrinfo *ai;
131 struct sockaddr_in *in4;
132 struct sockaddr_in6 *in6;
133 int ret = 0, r;
134
135 if ((r = getaddrinfo(host, NULL, NULL, &ai)) != 0) {
136 error("BSM audit: getaddrinfo failed for %.100s: %.100s", host,
137 r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
138 return -1;
139 }
140
141 switch (ai->ai_family) {
142 case AF_INET:
143 in4 = (struct sockaddr_in *)ai->ai_addr;
144 *type = AU_IPv4;
145 memcpy(addr, &in4->sin_addr, sizeof(struct in_addr));
146 break;
147#ifdef AU_IPv6
148 case AF_INET6:
149 in6 = (struct sockaddr_in6 *)ai->ai_addr;
150 *type = AU_IPv6;
151 memcpy(addr, &in6->sin6_addr, sizeof(struct in6_addr));
152 break;
153#endif
154 default:
155 error("BSM audit: unknown address family for %.100s: %d",
156 host, ai->ai_family);
157 ret = -1;
158 }
159 freeaddrinfo(ai);
160 return ret;
161}
162#endif
163
164/*
122 * Check if the specified event is selected (enabled) for auditing. 165 * Check if the specified event is selected (enabled) for auditing.
123 * Returns 1 if the event is selected, 0 if not and -1 on failure. 166 * Returns 1 if the event is selected, 0 if not and -1 on failure.
124 */ 167 */
diff --git a/auth-bsdauth.c b/auth-bsdauth.c
index 37d527d11..0b3262b49 100644
--- a/auth-bsdauth.c
+++ b/auth-bsdauth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-bsdauth.c,v 1.10 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth-bsdauth.c,v 1.11 2007/09/21 08:15:29 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
diff --git a/auth-options.c b/auth-options.c
index ca5e1c931..25361455e 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.43 2008/06/10 23:06:19 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
@@ -20,6 +20,7 @@
20#include <stdio.h> 20#include <stdio.h>
21#include <stdarg.h> 21#include <stdarg.h>
22 22
23#include "openbsd-compat/sys-queue.h"
23#include "xmalloc.h" 24#include "xmalloc.h"
24#include "match.h" 25#include "match.h"
25#include "log.h" 26#include "log.h"
@@ -42,6 +43,7 @@ int no_port_forwarding_flag = 0;
42int no_agent_forwarding_flag = 0; 43int no_agent_forwarding_flag = 0;
43int no_x11_forwarding_flag = 0; 44int no_x11_forwarding_flag = 0;
44int no_pty_flag = 0; 45int no_pty_flag = 0;
46int no_user_rc = 0;
45 47
46/* "command=" option. */ 48/* "command=" option. */
47char *forced_command = NULL; 49char *forced_command = NULL;
@@ -61,6 +63,7 @@ auth_clear_options(void)
61 no_port_forwarding_flag = 0; 63 no_port_forwarding_flag = 0;
62 no_pty_flag = 0; 64 no_pty_flag = 0;
63 no_x11_forwarding_flag = 0; 65 no_x11_forwarding_flag = 0;
66 no_user_rc = 0;
64 while (custom_environment) { 67 while (custom_environment) {
65 struct envstring *ce = custom_environment; 68 struct envstring *ce = custom_environment;
66 custom_environment = ce->next; 69 custom_environment = ce->next;
@@ -121,6 +124,13 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
121 opts += strlen(cp); 124 opts += strlen(cp);
122 goto next_option; 125 goto next_option;
123 } 126 }
127 cp = "no-user-rc";
128 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
129 auth_debug_add("User rc file execution disabled.");
130 no_user_rc = 1;
131 opts += strlen(cp);
132 goto next_option;
133 }
124 cp = "command=\""; 134 cp = "command=\"";
125 if (strncasecmp(opts, cp, strlen(cp)) == 0) { 135 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
126 opts += strlen(cp); 136 opts += strlen(cp);
@@ -216,8 +226,19 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
216 } 226 }
217 patterns[i] = '\0'; 227 patterns[i] = '\0';
218 opts++; 228 opts++;
219 if (match_host_and_ip(remote_host, remote_ip, 229 switch (match_host_and_ip(remote_host, remote_ip,
220 patterns) != 1) { 230 patterns)) {
231 case 1:
232 xfree(patterns);
233 /* Host name matches. */
234 goto next_option;
235 case -1:
236 debug("%.100s, line %lu: invalid criteria",
237 file, linenum);
238 auth_debug_add("%.100s, line %lu: "
239 "invalid criteria", file, linenum);
240 /* FALLTHROUGH */
241 case 0:
221 xfree(patterns); 242 xfree(patterns);
222 logit("Authentication tried for %.100s with " 243 logit("Authentication tried for %.100s with "
223 "correct key but not from a permitted " 244 "correct key but not from a permitted "
@@ -226,12 +247,10 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
226 auth_debug_add("Your host '%.200s' is not " 247 auth_debug_add("Your host '%.200s' is not "
227 "permitted to use this key for login.", 248 "permitted to use this key for login.",
228 remote_host); 249 remote_host);
229 /* deny access */ 250 break;
230 return 0;
231 } 251 }
232 xfree(patterns); 252 /* deny access */
233 /* Host name matches. */ 253 return 0;
234 goto next_option;
235 } 254 }
236 cp = "permitopen=\""; 255 cp = "permitopen=\"";
237 if (strncasecmp(opts, cp, strlen(cp)) == 0) { 256 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
diff --git a/auth-options.h b/auth-options.h
index 853f8b517..14488f72d 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.h,v 1.16 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth-options.h,v 1.17 2008/03/26 21:28:14 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -26,6 +26,7 @@ extern int no_port_forwarding_flag;
26extern int no_agent_forwarding_flag; 26extern int no_agent_forwarding_flag;
27extern int no_x11_forwarding_flag; 27extern int no_x11_forwarding_flag;
28extern int no_pty_flag; 28extern int no_pty_flag;
29extern int no_user_rc;
29extern char *forced_command; 30extern char *forced_command;
30extern struct envstring *custom_environment; 31extern struct envstring *custom_environment;
31extern int forced_tun_device; 32extern int forced_tun_device;
diff --git a/auth-pam.c b/auth-pam.c
index a07f1fe77..ccdb9937e 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -598,15 +598,17 @@ static struct pam_conv store_conv = { sshpam_store_conv, NULL };
598void 598void
599sshpam_cleanup(void) 599sshpam_cleanup(void)
600{ 600{
601 debug("PAM: cleanup"); 601 if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor()))
602 if (sshpam_handle == NULL)
603 return; 602 return;
603 debug("PAM: cleanup");
604 pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); 604 pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
605 if (sshpam_cred_established) { 605 if (sshpam_cred_established) {
606 debug("PAM: deleting credentials");
606 pam_setcred(sshpam_handle, PAM_DELETE_CRED); 607 pam_setcred(sshpam_handle, PAM_DELETE_CRED);
607 sshpam_cred_established = 0; 608 sshpam_cred_established = 0;
608 } 609 }
609 if (sshpam_session_open) { 610 if (sshpam_session_open) {
611 debug("PAM: closing session");
610 pam_close_session(sshpam_handle, PAM_SILENT); 612 pam_close_session(sshpam_handle, PAM_SILENT);
611 sshpam_session_open = 0; 613 sshpam_session_open = 0;
612 } 614 }
diff --git a/auth-passwd.c b/auth-passwd.c
index be6283796..bdfced023 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-passwd.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth-passwd.c,v 1.43 2007/09/21 08:15: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
diff --git a/auth-rhosts.c b/auth-rhosts.c
index cd0a7967a..5c1296701 100644
--- a/auth-rhosts.c
+++ b/auth-rhosts.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-rhosts.c,v 1.41 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth-rhosts.c,v 1.43 2008/06/13 14:18:51 dtucker 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
@@ -26,6 +26,8 @@
26#include <stdio.h> 26#include <stdio.h>
27#include <string.h> 27#include <string.h>
28#include <stdarg.h> 28#include <stdarg.h>
29#include <fcntl.h>
30#include <unistd.h>
29 31
30#include "packet.h" 32#include "packet.h"
31#include "buffer.h" 33#include "buffer.h"
@@ -37,6 +39,7 @@
37#include "key.h" 39#include "key.h"
38#include "hostfile.h" 40#include "hostfile.h"
39#include "auth.h" 41#include "auth.h"
42#include "misc.h"
40 43
41/* import */ 44/* import */
42extern ServerOptions options; 45extern ServerOptions options;
@@ -55,12 +58,27 @@ check_rhosts_file(const char *filename, const char *hostname,
55{ 58{
56 FILE *f; 59 FILE *f;
57 char buf[1024]; /* Must not be larger than host, user, dummy below. */ 60 char buf[1024]; /* Must not be larger than host, user, dummy below. */
61 int fd;
62 struct stat st;
58 63
59 /* Open the .rhosts file, deny if unreadable */ 64 /* Open the .rhosts file, deny if unreadable */
60 f = fopen(filename, "r"); 65 if ((fd = open(filename, O_RDONLY|O_NONBLOCK)) == -1)
61 if (!f)
62 return 0; 66 return 0;
63 67 if (fstat(fd, &st) == -1) {
68 close(fd);
69 return 0;
70 }
71 if (!S_ISREG(st.st_mode)) {
72 logit("User %s hosts file %s is not a regular file",
73 server_user, filename);
74 close(fd);
75 return 0;
76 }
77 unset_nonblock(fd);
78 if ((f = fdopen(fd, "r")) == NULL) {
79 close(fd);
80 return 0;
81 }
64 while (fgets(buf, sizeof(buf), f)) { 82 while (fgets(buf, sizeof(buf), f)) {
65 /* All three must be at least as big as buf to avoid overflows. */ 83 /* All three must be at least as big as buf to avoid overflows. */
66 char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; 84 char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp;
diff --git a/auth-rsa.c b/auth-rsa.c
index 69f9a5896..bf5462076 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-rsa.c,v 1.72 2006/11/06 21:25:27 markus Exp $ */ 1/* $OpenBSD: auth-rsa.c,v 1.73 2008/07/02 12:03:51 dtucker 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
@@ -173,7 +173,6 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
173 u_int bits; 173 u_int bits;
174 FILE *f; 174 FILE *f;
175 u_long linenum = 0; 175 u_long linenum = 0;
176 struct stat st;
177 Key *key; 176 Key *key;
178 177
179 /* Temporarily use the user's uid. */ 178 /* Temporarily use the user's uid. */
@@ -182,27 +181,9 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
182 /* The authorized keys. */ 181 /* The authorized keys. */
183 file = authorized_keys_file(pw); 182 file = authorized_keys_file(pw);
184 debug("trying public RSA key file %s", file); 183 debug("trying public RSA key file %s", file);
185 184 f = auth_openkeyfile(file, pw, options.strict_modes);
186 /* Fail quietly if file does not exist */
187 if (stat(file, &st) < 0) {
188 /* Restore the privileged uid. */
189 restore_uid();
190 xfree(file);
191 return (0);
192 }
193 /* Open the file containing the authorized keys. */
194 f = fopen(file, "r");
195 if (!f) { 185 if (!f) {
196 /* Restore the privileged uid. */
197 restore_uid();
198 xfree(file);
199 return (0);
200 }
201 if (options.strict_modes &&
202 secure_filename(f, file, pw, line, sizeof(line)) != 0) {
203 xfree(file); 186 xfree(file);
204 fclose(f);
205 logit("Authentication refused: %s", line);
206 restore_uid(); 187 restore_uid();
207 return (0); 188 return (0);
208 } 189 }
diff --git a/auth-sia.c b/auth-sia.c
index a9e1c258c..debf30201 100644
--- a/auth-sia.c
+++ b/auth-sia.c
@@ -34,6 +34,10 @@
34#include <unistd.h> 34#include <unistd.h>
35#include <stdarg.h> 35#include <stdarg.h>
36#include <string.h> 36#include <string.h>
37#include <sys/types.h>
38#include <sys/security.h>
39#include <prot.h>
40#include <time.h>
37 41
38#include "ssh.h" 42#include "ssh.h"
39#include "key.h" 43#include "key.h"
@@ -49,6 +53,52 @@ extern ServerOptions options;
49extern int saved_argc; 53extern int saved_argc;
50extern char **saved_argv; 54extern char **saved_argv;
51 55
56static int
57sia_password_change_required(const char *user)
58{
59 struct es_passwd *acct;
60 time_t pw_life;
61 time_t pw_date;
62
63 set_auth_parameters(saved_argc, saved_argv);
64
65 if ((acct = getespwnam(user)) == NULL) {
66 error("Couldn't access protected database entry for %s", user);
67 endprpwent();
68 return (0);
69 }
70
71 /* If forced password change flag is set, honor it */
72 if (acct->uflg->fg_psw_chg_reqd && acct->ufld->fd_psw_chg_reqd) {
73 endprpwent();
74 return (1);
75 }
76
77 /* Obtain password lifetime; if none, it can't have expired */
78 if (acct->uflg->fg_expire)
79 pw_life = acct->ufld->fd_expire;
80 else if (acct->sflg->fg_expire)
81 pw_life = acct->sfld->fd_expire;
82 else {
83 endprpwent();
84 return (0);
85 }
86
87 /* Offset from last change; if none, it must be expired */
88 if (acct->uflg->fg_schange)
89 pw_date = acct->ufld->fd_schange + pw_life;
90 else {
91 endprpwent();
92 return (1);
93 }
94
95 endprpwent();
96
97 /* If expiration date is prior to now, change password */
98
99 return (pw_date <= time((time_t *) NULL));
100}
101
52int 102int
53sys_auth_passwd(Authctxt *authctxt, const char *pass) 103sys_auth_passwd(Authctxt *authctxt, const char *pass)
54{ 104{
@@ -76,6 +126,9 @@ sys_auth_passwd(Authctxt *authctxt, const char *pass)
76 126
77 sia_ses_release(&ent); 127 sia_ses_release(&ent);
78 128
129 authctxt->force_pwchange = sia_password_change_required(
130 authctxt->user);
131
79 return (1); 132 return (1);
80} 133}
81 134
diff --git a/auth.c b/auth.c
index c1e0f4812..2370e5c2c 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth.c,v 1.79 2008/07/02 12:03:51 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -32,6 +32,7 @@
32#include <netinet/in.h> 32#include <netinet/in.h>
33 33
34#include <errno.h> 34#include <errno.h>
35#include <fcntl.h>
35#ifdef HAVE_PATHS_H 36#ifdef HAVE_PATHS_H
36# include <paths.h> 37# include <paths.h>
37#endif 38#endif
@@ -48,6 +49,7 @@
48#include <stdarg.h> 49#include <stdarg.h>
49#include <stdio.h> 50#include <stdio.h>
50#include <string.h> 51#include <string.h>
52#include <unistd.h>
51 53
52#include "xmalloc.h" 54#include "xmalloc.h"
53#include "match.h" 55#include "match.h"
@@ -113,6 +115,7 @@ allowed_user(struct passwd * pw)
113#endif /* USE_SHADOW */ 115#endif /* USE_SHADOW */
114 116
115 /* grab passwd field for locked account check */ 117 /* grab passwd field for locked account check */
118 passwd = pw->pw_passwd;
116#ifdef USE_SHADOW 119#ifdef USE_SHADOW
117 if (spw != NULL) 120 if (spw != NULL)
118#ifdef USE_LIBIAF 121#ifdef USE_LIBIAF
@@ -120,8 +123,6 @@ allowed_user(struct passwd * pw)
120#else 123#else
121 passwd = spw->sp_pwdp; 124 passwd = spw->sp_pwdp;
122#endif /* USE_LIBIAF */ 125#endif /* USE_LIBIAF */
123#else
124 passwd = pw->pw_passwd;
125#endif 126#endif
126 127
127 /* check for locked account */ 128 /* check for locked account */
@@ -410,7 +411,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
410 * 411 *
411 * Returns 0 on success and -1 on failure 412 * Returns 0 on success and -1 on failure
412 */ 413 */
413int 414static int
414secure_filename(FILE *f, const char *file, struct passwd *pw, 415secure_filename(FILE *f, const char *file, struct passwd *pw,
415 char *err, size_t errlen) 416 char *err, size_t errlen)
416{ 417{
@@ -470,6 +471,46 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
470 return 0; 471 return 0;
471} 472}
472 473
474FILE *
475auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
476{
477 char line[1024];
478 struct stat st;
479 int fd;
480 FILE *f;
481
482 /*
483 * Open the file containing the authorized keys
484 * Fail quietly if file does not exist
485 */
486 if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1)
487 return NULL;
488
489 if (fstat(fd, &st) < 0) {
490 close(fd);
491 return NULL;
492 }
493 if (!S_ISREG(st.st_mode)) {
494 logit("User %s authorized keys %s is not a regular file",
495 pw->pw_name, file);
496 close(fd);
497 return NULL;
498 }
499 unset_nonblock(fd);
500 if ((f = fdopen(fd, "r")) == NULL) {
501 close(fd);
502 return NULL;
503 }
504 if (options.strict_modes &&
505 secure_filename(f, file, pw, line, sizeof(line)) != 0) {
506 fclose(f);
507 logit("Authentication refused: %s", line);
508 return NULL;
509 }
510
511 return f;
512}
513
473struct passwd * 514struct passwd *
474getpwnamallow(const char *user) 515getpwnamallow(const char *user)
475{ 516{
diff --git a/auth.h b/auth.h
index 8c554b6a6..6a70f0eb6 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.h,v 1.58 2006/08/18 09:15:20 markus Exp $ */ 1/* $OpenBSD: auth.h,v 1.61 2008/07/02 12:03:51 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -166,8 +166,7 @@ void abandon_challenge_response(Authctxt *);
166char *authorized_keys_file(struct passwd *); 166char *authorized_keys_file(struct passwd *);
167char *authorized_keys_file2(struct passwd *); 167char *authorized_keys_file2(struct passwd *);
168 168
169int 169FILE *auth_openkeyfile(const char *, struct passwd *, int);
170secure_filename(FILE *, const char *, struct passwd *, char *, size_t);
171 170
172HostStatus 171HostStatus
173check_key_in_hostfiles(struct passwd *, Key *, const char *, 172check_key_in_hostfiles(struct passwd *, Key *, const char *,
diff --git a/auth1.c b/auth1.c
index b9d6b1115..b8a255872 100644
--- a/auth1.c
+++ b/auth1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth1.c,v 1.70 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth1.c,v 1.73 2008/07/04 23:30:16 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
@@ -20,6 +20,7 @@
20#include <unistd.h> 20#include <unistd.h>
21#include <pwd.h> 21#include <pwd.h>
22 22
23#include "openbsd-compat/sys-queue.h"
23#include "xmalloc.h" 24#include "xmalloc.h"
24#include "rsa.h" 25#include "rsa.h"
25#include "ssh1.h" 26#include "ssh1.h"
@@ -283,6 +284,8 @@ do_authloop(Authctxt *authctxt)
283 type != SSH_CMSG_AUTH_TIS_RESPONSE) 284 type != SSH_CMSG_AUTH_TIS_RESPONSE)
284 abandon_challenge_response(authctxt); 285 abandon_challenge_response(authctxt);
285 286
287 if (authctxt->failures >= options.max_authtries)
288 goto skip;
286 if ((meth = lookup_authmethod1(type)) == NULL) { 289 if ((meth = lookup_authmethod1(type)) == NULL) {
287 logit("Unknown message during authentication: " 290 logit("Unknown message during authentication: "
288 "type %d", type); 291 "type %d", type);
@@ -351,7 +354,7 @@ do_authloop(Authctxt *authctxt)
351 msg[len] = '\0'; 354 msg[len] = '\0';
352 else 355 else
353 msg = "Access denied."; 356 msg = "Access denied.";
354 packet_disconnect(msg); 357 packet_disconnect("%s", msg);
355 } 358 }
356#endif 359#endif
357 360
@@ -367,7 +370,7 @@ do_authloop(Authctxt *authctxt)
367 if (authenticated) 370 if (authenticated)
368 return; 371 return;
369 372
370 if (authctxt->failures++ > options.max_authtries) { 373 if (++authctxt->failures >= options.max_authtries) {
371#ifdef SSH_AUDIT_EVENTS 374#ifdef SSH_AUDIT_EVENTS
372 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 375 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
373#endif 376#endif
diff --git a/auth2-chall.c b/auth2-chall.c
index 51059c2bd..d816578c6 100644
--- a/auth2-chall.c
+++ b/auth2-chall.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-chall.c,v 1.32 2007/01/03 03:01:40 stevesk Exp $ */ 1/* $OpenBSD: auth2-chall.c,v 1.33 2007/09/21 08:15:29 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.
diff --git a/auth2-gss.c b/auth2-gss.c
index c77c841a3..0e08d889c 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-gss.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 663dec5d9..041051c53 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-hostbased.c,v 1.11 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth2-hostbased.c,v 1.12 2008/07/17 08:51:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -151,15 +151,16 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
151 debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", 151 debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
152 chost, resolvedname, ipaddr); 152 chost, resolvedname, ipaddr);
153 153
154 if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
155 debug2("stripping trailing dot from chost %s", chost);
156 chost[len - 1] = '\0';
157 }
158
154 if (options.hostbased_uses_name_from_packet_only) { 159 if (options.hostbased_uses_name_from_packet_only) {
155 if (auth_rhosts2(pw, cuser, chost, chost) == 0) 160 if (auth_rhosts2(pw, cuser, chost, chost) == 0)
156 return 0; 161 return 0;
157 lookup = chost; 162 lookup = chost;
158 } else { 163 } else {
159 if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
160 debug2("stripping trailing dot from chost %s", chost);
161 chost[len - 1] = '\0';
162 }
163 if (strcasecmp(resolvedname, chost) != 0) 164 if (strcasecmp(resolvedname, chost) != 0)
164 logit("userauth_hostbased mismatch: " 165 logit("userauth_hostbased mismatch: "
165 "client sends %s, but we resolve %s to %s", 166 "client sends %s, but we resolve %s to %s",
diff --git a/auth2-none.c b/auth2-none.c
index 952b44824..10accfe55 100644
--- a/auth2-none.c
+++ b/auth2-none.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-none.c,v 1.13 2006/08/05 07:52:52 dtucker Exp $ */ 1/* $OpenBSD: auth2-none.c,v 1.15 2008/07/02 12:36:39 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -31,8 +31,10 @@
31 31
32#include <fcntl.h> 32#include <fcntl.h>
33#include <stdarg.h> 33#include <stdarg.h>
34#include <string.h>
34#include <unistd.h> 35#include <unistd.h>
35 36
37#include "atomicio.h"
36#include "xmalloc.h" 38#include "xmalloc.h"
37#include "key.h" 39#include "key.h"
38#include "hostfile.h" 40#include "hostfile.h"
@@ -41,7 +43,6 @@
41#include "log.h" 43#include "log.h"
42#include "buffer.h" 44#include "buffer.h"
43#include "servconf.h" 45#include "servconf.h"
44#include "atomicio.h"
45#include "compat.h" 46#include "compat.h"
46#include "ssh2.h" 47#include "ssh2.h"
47#ifdef GSSAPI 48#ifdef GSSAPI
@@ -55,75 +56,11 @@ extern ServerOptions options;
55/* "none" is allowed only one time */ 56/* "none" is allowed only one time */
56static int none_enabled = 1; 57static int none_enabled = 1;
57 58
58char *
59auth2_read_banner(void)
60{
61 struct stat st;
62 char *banner = NULL;
63 size_t len, n;
64 int fd;
65
66 if ((fd = open(options.banner, O_RDONLY)) == -1)
67 return (NULL);
68 if (fstat(fd, &st) == -1) {
69 close(fd);
70 return (NULL);
71 }
72 if (st.st_size > 1*1024*1024) {
73 close(fd);
74 return (NULL);
75 }
76
77 len = (size_t)st.st_size; /* truncate */
78 banner = xmalloc(len + 1);
79 n = atomicio(read, fd, banner, len);
80 close(fd);
81
82 if (n != len) {
83 xfree(banner);
84 return (NULL);
85 }
86 banner[n] = '\0';
87
88 return (banner);
89}
90
91void
92userauth_send_banner(const char *msg)
93{
94 if (datafellows & SSH_BUG_BANNER)
95 return;
96
97 packet_start(SSH2_MSG_USERAUTH_BANNER);
98 packet_put_cstring(msg);
99 packet_put_cstring(""); /* language, unused */
100 packet_send();
101 debug("%s: sent", __func__);
102}
103
104static void
105userauth_banner(void)
106{
107 char *banner = NULL;
108
109 if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
110 return;
111
112 if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
113 goto done;
114 userauth_send_banner(banner);
115
116done:
117 if (banner)
118 xfree(banner);
119}
120
121static int 59static int
122userauth_none(Authctxt *authctxt) 60userauth_none(Authctxt *authctxt)
123{ 61{
124 none_enabled = 0; 62 none_enabled = 0;
125 packet_check_eom(); 63 packet_check_eom();
126 userauth_banner();
127#ifdef HAVE_CYGWIN 64#ifdef HAVE_CYGWIN
128 if (check_nt_auth(1, authctxt->pw) == 0) 65 if (check_nt_auth(1, authctxt->pw) == 0)
129 return (0); 66 return (0);
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 9863cd9e6..b1e38e5f5 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.19 2008/07/03 21:46:58 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -28,9 +28,11 @@
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/stat.h> 29#include <sys/stat.h>
30 30
31#include <fcntl.h>
31#include <pwd.h> 32#include <pwd.h>
32#include <stdio.h> 33#include <stdio.h>
33#include <stdarg.h> 34#include <stdarg.h>
35#include <unistd.h>
34 36
35#include "xmalloc.h" 37#include "xmalloc.h"
36#include "ssh.h" 38#include "ssh.h"
@@ -183,7 +185,6 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
183 int found_key = 0; 185 int found_key = 0;
184 FILE *f; 186 FILE *f;
185 u_long linenum = 0; 187 u_long linenum = 0;
186 struct stat st;
187 Key *found; 188 Key *found;
188 char *fp; 189 char *fp;
189 190
@@ -191,24 +192,9 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
191 temporarily_use_uid(pw); 192 temporarily_use_uid(pw);
192 193
193 debug("trying public key file %s", file); 194 debug("trying public key file %s", file);
195 f = auth_openkeyfile(file, pw, options.strict_modes);
194 196
195 /* Fail quietly if file does not exist */
196 if (stat(file, &st) < 0) {
197 /* Restore the privileged uid. */
198 restore_uid();
199 return 0;
200 }
201 /* Open the file containing the authorized keys. */
202 f = fopen(file, "r");
203 if (!f) { 197 if (!f) {
204 /* Restore the privileged uid. */
205 restore_uid();
206 return 0;
207 }
208 if (options.strict_modes &&
209 secure_filename(f, file, pw, line, sizeof(line)) != 0) {
210 fclose(f);
211 logit("Authentication refused: %s", line);
212 restore_uid(); 198 restore_uid();
213 return 0; 199 return 0;
214 } 200 }
diff --git a/auth2.c b/auth2.c
index bded8c2f8..a835abfc6 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.115 2007/04/14 22:01:58 stevesk Exp $ */ 1/* $OpenBSD: auth2.c,v 1.119 2008/07/04 23:30:16 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -26,12 +26,17 @@
26#include "includes.h" 26#include "includes.h"
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/uio.h>
29 31
32#include <fcntl.h>
30#include <pwd.h> 33#include <pwd.h>
31#include <stdarg.h> 34#include <stdarg.h>
32#include <string.h> 35#include <string.h>
36#include <unistd.h>
33 37
34#include "xmalloc.h" 38#include "xmalloc.h"
39#include "atomicio.h"
35#include "ssh2.h" 40#include "ssh2.h"
36#include "packet.h" 41#include "packet.h"
37#include "log.h" 42#include "log.h"
@@ -87,12 +92,75 @@ static void input_userauth_request(int, u_int32_t, void *);
87/* helper */ 92/* helper */
88static Authmethod *authmethod_lookup(const char *); 93static Authmethod *authmethod_lookup(const char *);
89static char *authmethods_get(void); 94static char *authmethods_get(void);
90int user_key_allowed(struct passwd *, Key *); 95
96char *
97auth2_read_banner(void)
98{
99 struct stat st;
100 char *banner = NULL;
101 size_t len, n;
102 int fd;
103
104 if ((fd = open(options.banner, O_RDONLY)) == -1)
105 return (NULL);
106 if (fstat(fd, &st) == -1) {
107 close(fd);
108 return (NULL);
109 }
110 if (st.st_size > 1*1024*1024) {
111 close(fd);
112 return (NULL);
113 }
114
115 len = (size_t)st.st_size; /* truncate */
116 banner = xmalloc(len + 1);
117 n = atomicio(read, fd, banner, len);
118 close(fd);
119
120 if (n != len) {
121 xfree(banner);
122 return (NULL);
123 }
124 banner[n] = '\0';
125
126 return (banner);
127}
128
129void
130userauth_send_banner(const char *msg)
131{
132 if (datafellows & SSH_BUG_BANNER)
133 return;
134
135 packet_start(SSH2_MSG_USERAUTH_BANNER);
136 packet_put_cstring(msg);
137 packet_put_cstring(""); /* language, unused */
138 packet_send();
139 debug("%s: sent", __func__);
140}
141
142static void
143userauth_banner(void)
144{
145 char *banner = NULL;
146
147 if (options.banner == NULL ||
148 strcasecmp(options.banner, "none") == 0 ||
149 (datafellows & SSH_BUG_BANNER) != 0)
150 return;
151
152 if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
153 goto done;
154 userauth_send_banner(banner);
155
156done:
157 if (banner)
158 xfree(banner);
159}
91 160
92/* 161/*
93 * loop until authctxt->success == TRUE 162 * loop until authctxt->success == TRUE
94 */ 163 */
95
96void 164void
97do_authentication2(Authctxt *authctxt) 165do_authentication2(Authctxt *authctxt)
98{ 166{
@@ -180,6 +248,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
180 authctxt->style = style ? xstrdup(style) : NULL; 248 authctxt->style = style ? xstrdup(style) : NULL;
181 if (use_privsep) 249 if (use_privsep)
182 mm_inform_authserv(service, style); 250 mm_inform_authserv(service, style);
251 userauth_banner();
183 } else if (strcmp(user, authctxt->user) != 0 || 252 } else if (strcmp(user, authctxt->user) != 0 ||
184 strcmp(service, authctxt->service) != 0) { 253 strcmp(service, authctxt->service) != 0) {
185 packet_disconnect("Change of username or service not allowed: " 254 packet_disconnect("Change of username or service not allowed: "
@@ -198,7 +267,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
198 267
199 /* try to authenticate user */ 268 /* try to authenticate user */
200 m = authmethod_lookup(method); 269 m = authmethod_lookup(method);
201 if (m != NULL) { 270 if (m != NULL && authctxt->failures < options.max_authtries) {
202 debug2("input_userauth_request: try method %s", method); 271 debug2("input_userauth_request: try method %s", method);
203 authenticated = m->userauth(authctxt); 272 authenticated = m->userauth(authctxt);
204 } 273 }
@@ -265,7 +334,11 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
265 /* now we can break out */ 334 /* now we can break out */
266 authctxt->success = 1; 335 authctxt->success = 1;
267 } else { 336 } else {
268 if (authctxt->failures++ > options.max_authtries) { 337
338 /* Allow initial try of "none" auth without failure penalty */
339 if (authctxt->attempt > 1 || strcmp(method, "none") != 0)
340 authctxt->failures++;
341 if (authctxt->failures >= options.max_authtries) {
269#ifdef SSH_AUDIT_EVENTS 342#ifdef SSH_AUDIT_EVENTS
270 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 343 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
271#endif 344#endif
@@ -321,3 +394,4 @@ authmethod_lookup(const char *name)
321 name ? name : "NULL"); 394 name ? name : "NULL");
322 return NULL; 395 return NULL;
323} 396}
397
diff --git a/bufaux.c b/bufaux.c
index cbdc22c64..cd9a35ded 100644
--- a/bufaux.c
+++ b/bufaux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bufaux.c,v 1.44 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: bufaux.c,v 1.46 2008/06/10 23:21:34 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -180,7 +180,7 @@ buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
180 return (NULL); 180 return (NULL);
181 } 181 }
182 /* Append a null character to make processing easier. */ 182 /* Append a null character to make processing easier. */
183 value[len] = 0; 183 value[len] = '\0';
184 /* Optionally return the length of the string. */ 184 /* Optionally return the length of the string. */
185 if (length_ptr) 185 if (length_ptr)
186 *length_ptr = len; 186 *length_ptr = len;
@@ -197,6 +197,22 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
197 return (ret); 197 return (ret);
198} 198}
199 199
200void *
201buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
202{
203 void *ptr;
204 u_int len;
205
206 len = buffer_get_int(buffer);
207 if (len > 256 * 1024)
208 fatal("buffer_get_string_ptr: bad string length %u", len);
209 ptr = buffer_ptr(buffer);
210 buffer_consume(buffer, len);
211 if (length_ptr)
212 *length_ptr = len;
213 return (ptr);
214}
215
200/* 216/*
201 * Stores and arbitrary binary string in the buffer. 217 * Stores and arbitrary binary string in the buffer.
202 */ 218 */
diff --git a/buffer.h b/buffer.h
index ecc4aea83..d0f354ee7 100644
--- a/buffer.h
+++ b/buffer.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: buffer.h,v 1.16 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: buffer.h,v 1.17 2008/05/08 06:59:01 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -66,6 +66,7 @@ int buffer_get_char(Buffer *);
66void buffer_put_char(Buffer *, int); 66void buffer_put_char(Buffer *, int);
67 67
68void *buffer_get_string(Buffer *, u_int *); 68void *buffer_get_string(Buffer *, u_int *);
69void *buffer_get_string_ptr(Buffer *, u_int *);
69void buffer_put_string(Buffer *, const void *, u_int); 70void buffer_put_string(Buffer *, const void *, u_int);
70void buffer_put_cstring(Buffer *, const char *); 71void buffer_put_cstring(Buffer *, const char *);
71 72
diff --git a/canohost.c b/canohost.c
index 2345cc35c..42011fd0a 100644
--- a/canohost.c
+++ b/canohost.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: canohost.c,v 1.61 2006/08/03 03:34:41 deraadt Exp $ */ 1/* $OpenBSD: canohost.c,v 1.63 2008/06/12 00:03:49 dtucker 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
@@ -32,6 +32,7 @@
32#include "packet.h" 32#include "packet.h"
33#include "log.h" 33#include "log.h"
34#include "canohost.h" 34#include "canohost.h"
35#include "misc.h"
35 36
36static void check_ip_options(int, char *); 37static void check_ip_options(int, char *);
37 38
@@ -88,7 +89,7 @@ get_remote_hostname(int sock, int use_dns)
88 memset(&hints, 0, sizeof(hints)); 89 memset(&hints, 0, sizeof(hints));
89 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 90 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
90 hints.ai_flags = AI_NUMERICHOST; 91 hints.ai_flags = AI_NUMERICHOST;
91 if (getaddrinfo(name, "0", &hints, &ai) == 0) { 92 if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
92 logit("Nasty PTR record \"%s\" is set up for %s, ignoring", 93 logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
93 name, ntop); 94 name, ntop);
94 freeaddrinfo(ai); 95 freeaddrinfo(ai);
@@ -271,7 +272,7 @@ get_socket_address(int sock, int remote, int flags)
271 if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, 272 if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
272 sizeof(ntop), NULL, 0, flags)) != 0) { 273 sizeof(ntop), NULL, 0, flags)) != 0) {
273 error("get_socket_address: getnameinfo %d failed: %s", flags, 274 error("get_socket_address: getnameinfo %d failed: %s", flags,
274 r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); 275 ssh_gai_strerror(r));
275 return NULL; 276 return NULL;
276 } 277 }
277 return xstrdup(ntop); 278 return xstrdup(ntop);
@@ -372,7 +373,7 @@ get_sock_port(int sock, int local)
372 if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, 373 if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
373 strport, sizeof(strport), NI_NUMERICSERV)) != 0) 374 strport, sizeof(strport), NI_NUMERICSERV)) != 0)
374 fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s", 375 fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s",
375 r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); 376 ssh_gai_strerror(r));
376 return atoi(strport); 377 return atoi(strport);
377} 378}
378 379
diff --git a/channels.c b/channels.c
index 2006353d4..69c99c9b2 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.270 2007/06/25 08:20:03 dtucker Exp $ */ 1/* $OpenBSD: channels.c,v 1.286 2008/07/16 11:52:19 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
@@ -61,6 +61,7 @@
61#include <unistd.h> 61#include <unistd.h>
62#include <stdarg.h> 62#include <stdarg.h>
63 63
64#include "openbsd-compat/sys-queue.h"
64#include "xmalloc.h" 65#include "xmalloc.h"
65#include "ssh.h" 66#include "ssh.h"
66#include "ssh1.h" 67#include "ssh1.h"
@@ -164,6 +165,10 @@ static int IPv4or6 = AF_UNSPEC;
164/* helper */ 165/* helper */
165static void port_open_helper(Channel *c, char *rtype); 166static void port_open_helper(Channel *c, char *rtype);
166 167
168/* non-blocking connect helpers */
169static int connect_next(struct channel_connect *);
170static void channel_connect_ctx_free(struct channel_connect *);
171
167/* -- channel core */ 172/* -- channel core */
168 173
169Channel * 174Channel *
@@ -216,7 +221,7 @@ channel_lookup(int id)
216 */ 221 */
217static void 222static void
218channel_register_fds(Channel *c, int rfd, int wfd, int efd, 223channel_register_fds(Channel *c, int rfd, int wfd, int efd,
219 int extusage, int nonblock) 224 int extusage, int nonblock, int is_tty)
220{ 225{
221 /* Update the maximum file descriptor value. */ 226 /* Update the maximum file descriptor value. */
222 channel_max_fd = MAX(channel_max_fd, rfd); 227 channel_max_fd = MAX(channel_max_fd, rfd);
@@ -232,18 +237,9 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
232 c->efd = efd; 237 c->efd = efd;
233 c->extended_usage = extusage; 238 c->extended_usage = extusage;
234 239
235 /* XXX ugly hack: nonblock is only set by the server */ 240 if ((c->isatty = is_tty) != 0)
236 if (nonblock && isatty(c->rfd)) {
237 debug2("channel %d: rfd %d isatty", c->self, c->rfd); 241 debug2("channel %d: rfd %d isatty", c->self, c->rfd);
238 c->isatty = 1; 242 c->wfd_isatty = is_tty || isatty(c->wfd);
239 if (!isatty(c->wfd)) {
240 error("channel %d: wfd %d is not a tty?",
241 c->self, c->wfd);
242 }
243 } else {
244 c->isatty = 0;
245 }
246 c->wfd_isatty = isatty(c->wfd);
247 243
248 /* enable nonblocking mode */ 244 /* enable nonblocking mode */
249 if (nonblock) { 245 if (nonblock) {
@@ -303,7 +299,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
303 c->ostate = CHAN_OUTPUT_OPEN; 299 c->ostate = CHAN_OUTPUT_OPEN;
304 c->istate = CHAN_INPUT_OPEN; 300 c->istate = CHAN_INPUT_OPEN;
305 c->flags = 0; 301 c->flags = 0;
306 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); 302 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0);
307 c->self = found; 303 c->self = found;
308 c->type = type; 304 c->type = type;
309 c->ctype = ctype; 305 c->ctype = ctype;
@@ -319,10 +315,13 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
319 c->single_connection = 0; 315 c->single_connection = 0;
320 c->detach_user = NULL; 316 c->detach_user = NULL;
321 c->detach_close = 0; 317 c->detach_close = 0;
322 c->confirm = NULL; 318 c->open_confirm = NULL;
323 c->confirm_ctx = NULL; 319 c->open_confirm_ctx = NULL;
324 c->input_filter = NULL; 320 c->input_filter = NULL;
325 c->output_filter = NULL; 321 c->output_filter = NULL;
322 c->filter_ctx = NULL;
323 c->filter_cleanup = NULL;
324 TAILQ_INIT(&c->status_confirms);
326 debug("channel %d: new [%s]", found, remote_name); 325 debug("channel %d: new [%s]", found, remote_name);
327 return c; 326 return c;
328} 327}
@@ -379,6 +378,7 @@ channel_free(Channel *c)
379{ 378{
380 char *s; 379 char *s;
381 u_int i, n; 380 u_int i, n;
381 struct channel_confirm *cc;
382 382
383 for (n = 0, i = 0; i < channels_alloc; i++) 383 for (n = 0, i = 0; i < channels_alloc; i++)
384 if (channels[i]) 384 if (channels[i])
@@ -402,6 +402,15 @@ channel_free(Channel *c)
402 xfree(c->remote_name); 402 xfree(c->remote_name);
403 c->remote_name = NULL; 403 c->remote_name = NULL;
404 } 404 }
405 while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
406 if (cc->abandon_cb != NULL)
407 cc->abandon_cb(c, cc->ctx);
408 TAILQ_REMOVE(&c->status_confirms, cc, entry);
409 bzero(cc, sizeof(*cc));
410 xfree(cc);
411 }
412 if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
413 c->filter_cleanup(c->self, c->filter_ctx);
405 channels[c->self] = NULL; 414 channels[c->self] = NULL;
406 xfree(c); 415 xfree(c);
407} 416}
@@ -660,16 +669,33 @@ channel_request_start(int id, char *service, int wantconfirm)
660} 669}
661 670
662void 671void
663channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) 672channel_register_status_confirm(int id, channel_confirm_cb *cb,
673 channel_confirm_abandon_cb *abandon_cb, void *ctx)
674{
675 struct channel_confirm *cc;
676 Channel *c;
677
678 if ((c = channel_lookup(id)) == NULL)
679 fatal("channel_register_expect: %d: bad id", id);
680
681 cc = xmalloc(sizeof(*cc));
682 cc->cb = cb;
683 cc->abandon_cb = abandon_cb;
684 cc->ctx = ctx;
685 TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry);
686}
687
688void
689channel_register_open_confirm(int id, channel_callback_fn *fn, void *ctx)
664{ 690{
665 Channel *c = channel_lookup(id); 691 Channel *c = channel_lookup(id);
666 692
667 if (c == NULL) { 693 if (c == NULL) {
668 logit("channel_register_comfirm: %d: bad id", id); 694 logit("channel_register_open_comfirm: %d: bad id", id);
669 return; 695 return;
670 } 696 }
671 c->confirm = fn; 697 c->open_confirm = fn;
672 c->confirm_ctx = ctx; 698 c->open_confirm_ctx = ctx;
673} 699}
674 700
675void 701void
@@ -700,7 +726,7 @@ channel_cancel_cleanup(int id)
700 726
701void 727void
702channel_register_filter(int id, channel_infilter_fn *ifn, 728channel_register_filter(int id, channel_infilter_fn *ifn,
703 channel_outfilter_fn *ofn) 729 channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx)
704{ 730{
705 Channel *c = channel_lookup(id); 731 Channel *c = channel_lookup(id);
706 732
@@ -710,17 +736,19 @@ channel_register_filter(int id, channel_infilter_fn *ifn,
710 } 736 }
711 c->input_filter = ifn; 737 c->input_filter = ifn;
712 c->output_filter = ofn; 738 c->output_filter = ofn;
739 c->filter_ctx = ctx;
740 c->filter_cleanup = cfn;
713} 741}
714 742
715void 743void
716channel_set_fds(int id, int rfd, int wfd, int efd, 744channel_set_fds(int id, int rfd, int wfd, int efd,
717 int extusage, int nonblock, u_int window_max) 745 int extusage, int nonblock, int is_tty, u_int window_max)
718{ 746{
719 Channel *c = channel_lookup(id); 747 Channel *c = channel_lookup(id);
720 748
721 if (c == NULL || c->type != SSH_CHANNEL_LARVAL) 749 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
722 fatal("channel_activate for non-larval channel %d.", id); 750 fatal("channel_activate for non-larval channel %d.", id);
723 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); 751 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, is_tty);
724 c->type = SSH_CHANNEL_OPEN; 752 c->type = SSH_CHANNEL_OPEN;
725 c->local_window = c->local_window_max = window_max; 753 c->local_window = c->local_window_max = window_max;
726 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); 754 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
@@ -788,7 +816,8 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
788 } 816 }
789 } 817 }
790 /** XXX check close conditions, too */ 818 /** XXX check close conditions, too */
791 if (compat20 && c->efd != -1) { 819 if (compat20 && c->efd != -1 &&
820 !(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) {
792 if (c->extended_usage == CHAN_EXTENDED_WRITE && 821 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
793 buffer_len(&c->extended) > 0) 822 buffer_len(&c->extended) > 0)
794 FD_SET(c->efd, writeset); 823 FD_SET(c->efd, writeset);
@@ -1181,7 +1210,7 @@ static void
1181channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset) 1210channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
1182{ 1211{
1183 Channel *nc; 1212 Channel *nc;
1184 struct sockaddr addr; 1213 struct sockaddr_storage addr;
1185 int newsock; 1214 int newsock;
1186 socklen_t addrlen; 1215 socklen_t addrlen;
1187 char buf[16384], *remote_ipaddr; 1216 char buf[16384], *remote_ipaddr;
@@ -1190,7 +1219,7 @@ channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
1190 if (FD_ISSET(c->sock, readset)) { 1219 if (FD_ISSET(c->sock, readset)) {
1191 debug("X11 connection requested."); 1220 debug("X11 connection requested.");
1192 addrlen = sizeof(addr); 1221 addrlen = sizeof(addr);
1193 newsock = accept(c->sock, &addr, &addrlen); 1222 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1194 if (c->single_connection) { 1223 if (c->single_connection) {
1195 debug2("single_connection: closing X11 listener."); 1224 debug2("single_connection: closing X11 listener.");
1196 channel_close_fd(&c->sock); 1225 channel_close_fd(&c->sock);
@@ -1307,7 +1336,7 @@ static void
1307channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) 1336channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
1308{ 1337{
1309 Channel *nc; 1338 Channel *nc;
1310 struct sockaddr addr; 1339 struct sockaddr_storage addr;
1311 int newsock, nextstate; 1340 int newsock, nextstate;
1312 socklen_t addrlen; 1341 socklen_t addrlen;
1313 char *rtype; 1342 char *rtype;
@@ -1331,7 +1360,7 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
1331 } 1360 }
1332 1361
1333 addrlen = sizeof(addr); 1362 addrlen = sizeof(addr);
1334 newsock = accept(c->sock, &addr, &addrlen); 1363 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1335 if (newsock < 0) { 1364 if (newsock < 0) {
1336 error("accept: %.100s", strerror(errno)); 1365 error("accept: %.100s", strerror(errno));
1337 return; 1366 return;
@@ -1366,12 +1395,12 @@ channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
1366{ 1395{
1367 Channel *nc; 1396 Channel *nc;
1368 int newsock; 1397 int newsock;
1369 struct sockaddr addr; 1398 struct sockaddr_storage addr;
1370 socklen_t addrlen; 1399 socklen_t addrlen;
1371 1400
1372 if (FD_ISSET(c->sock, readset)) { 1401 if (FD_ISSET(c->sock, readset)) {
1373 addrlen = sizeof(addr); 1402 addrlen = sizeof(addr);
1374 newsock = accept(c->sock, &addr, &addrlen); 1403 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1375 if (newsock < 0) { 1404 if (newsock < 0) {
1376 error("accept from auth socket: %.100s", strerror(errno)); 1405 error("accept from auth socket: %.100s", strerror(errno));
1377 return; 1406 return;
@@ -1398,7 +1427,7 @@ channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
1398static void 1427static void
1399channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) 1428channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1400{ 1429{
1401 int err = 0; 1430 int err = 0, sock;
1402 socklen_t sz = sizeof(err); 1431 socklen_t sz = sizeof(err);
1403 1432
1404 if (FD_ISSET(c->sock, writeset)) { 1433 if (FD_ISSET(c->sock, writeset)) {
@@ -1407,7 +1436,9 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1407 error("getsockopt SO_ERROR failed"); 1436 error("getsockopt SO_ERROR failed");
1408 } 1437 }
1409 if (err == 0) { 1438 if (err == 0) {
1410 debug("channel %d: connected", c->self); 1439 debug("channel %d: connected to %s port %d",
1440 c->self, c->connect_ctx.host, c->connect_ctx.port);
1441 channel_connect_ctx_free(&c->connect_ctx);
1411 c->type = SSH_CHANNEL_OPEN; 1442 c->type = SSH_CHANNEL_OPEN;
1412 if (compat20) { 1443 if (compat20) {
1413 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 1444 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
@@ -1421,8 +1452,19 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1421 packet_put_int(c->self); 1452 packet_put_int(c->self);
1422 } 1453 }
1423 } else { 1454 } else {
1424 debug("channel %d: not connected: %s", 1455 debug("channel %d: connection failed: %s",
1425 c->self, strerror(err)); 1456 c->self, strerror(err));
1457 /* Try next address, if any */
1458 if ((sock = connect_next(&c->connect_ctx)) > 0) {
1459 close(c->sock);
1460 c->sock = c->rfd = c->wfd = sock;
1461 channel_max_fd = channel_find_maxfd();
1462 return;
1463 }
1464 /* Exhausted all addresses */
1465 error("connect_to %.100s port %d: failed.",
1466 c->connect_ctx.host, c->connect_ctx.port);
1467 channel_connect_ctx_free(&c->connect_ctx);
1426 if (compat20) { 1468 if (compat20) {
1427 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 1469 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1428 packet_put_int(c->remote_id); 1470 packet_put_int(c->remote_id);
@@ -1452,7 +1494,8 @@ channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
1452 if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) { 1494 if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) {
1453 errno = 0; 1495 errno = 0;
1454 len = read(c->rfd, buf, sizeof(buf)); 1496 len = read(c->rfd, buf, sizeof(buf));
1455 if (len < 0 && (errno == EINTR || (errno == EAGAIN && !force))) 1497 if (len < 0 && (errno == EINTR ||
1498 ((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
1456 return 1; 1499 return 1;
1457#ifndef PTY_ZEROREAD 1500#ifndef PTY_ZEROREAD
1458 if (len <= 0) { 1501 if (len <= 0) {
@@ -1523,7 +1566,8 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
1523 c->local_consumed += dlen + 4; 1566 c->local_consumed += dlen + 4;
1524 len = write(c->wfd, buf, dlen); 1567 len = write(c->wfd, buf, dlen);
1525 xfree(data); 1568 xfree(data);
1526 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1569 if (len < 0 && (errno == EINTR || errno == EAGAIN ||
1570 errno == EWOULDBLOCK))
1527 return 1; 1571 return 1;
1528 if (len <= 0) { 1572 if (len <= 0) {
1529 if (c->type != SSH_CHANNEL_OPEN) 1573 if (c->type != SSH_CHANNEL_OPEN)
@@ -1541,7 +1585,8 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
1541#endif 1585#endif
1542 1586
1543 len = write(c->wfd, buf, dlen); 1587 len = write(c->wfd, buf, dlen);
1544 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1588 if (len < 0 &&
1589 (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
1545 return 1; 1590 return 1;
1546 if (len <= 0) { 1591 if (len <= 0) {
1547 if (c->type != SSH_CHANNEL_OPEN) { 1592 if (c->type != SSH_CHANNEL_OPEN) {
@@ -1593,7 +1638,8 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
1593 buffer_len(&c->extended)); 1638 buffer_len(&c->extended));
1594 debug2("channel %d: written %d to efd %d", 1639 debug2("channel %d: written %d to efd %d",
1595 c->self, len, c->efd); 1640 c->self, len, c->efd);
1596 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1641 if (len < 0 && (errno == EINTR || errno == EAGAIN ||
1642 errno == EWOULDBLOCK))
1597 return 1; 1643 return 1;
1598 if (len <= 0) { 1644 if (len <= 0) {
1599 debug2("channel %d: closing write-efd %d", 1645 debug2("channel %d: closing write-efd %d",
@@ -1608,8 +1654,8 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
1608 len = read(c->efd, buf, sizeof(buf)); 1654 len = read(c->efd, buf, sizeof(buf));
1609 debug2("channel %d: read %d from efd %d", 1655 debug2("channel %d: read %d from efd %d",
1610 c->self, len, c->efd); 1656 c->self, len, c->efd);
1611 if (len < 0 && (errno == EINTR || 1657 if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
1612 (errno == EAGAIN && !c->detach_close))) 1658 errno == EWOULDBLOCK) && !c->detach_close)))
1613 return 1; 1659 return 1;
1614 if (len <= 0) { 1660 if (len <= 0) {
1615 debug2("channel %d: closing read-efd %d", 1661 debug2("channel %d: closing read-efd %d",
@@ -1633,7 +1679,8 @@ channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset)
1633 /* Monitor control fd to detect if the slave client exits */ 1679 /* Monitor control fd to detect if the slave client exits */
1634 if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) { 1680 if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) {
1635 len = read(c->ctl_fd, buf, sizeof(buf)); 1681 len = read(c->ctl_fd, buf, sizeof(buf));
1636 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1682 if (len < 0 &&
1683 (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
1637 return 1; 1684 return 1;
1638 if (len <= 0) { 1685 if (len <= 0) {
1639 debug2("channel %d: ctl read<=0", c->self); 1686 debug2("channel %d: ctl read<=0", c->self);
@@ -2012,7 +2059,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
2012 return; 2059 return;
2013 2060
2014 /* Get the data. */ 2061 /* Get the data. */
2015 data = packet_get_string(&data_len); 2062 data = packet_get_string_ptr(&data_len);
2016 2063
2017 /* 2064 /*
2018 * Ignore data for protocol > 1.3 if output end is no longer open. 2065 * Ignore data for protocol > 1.3 if output end is no longer open.
@@ -2026,7 +2073,6 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
2026 c->local_window -= data_len; 2073 c->local_window -= data_len;
2027 c->local_consumed += data_len; 2074 c->local_consumed += data_len;
2028 } 2075 }
2029 xfree(data);
2030 return; 2076 return;
2031 } 2077 }
2032 2078
@@ -2038,17 +2084,15 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
2038 if (data_len > c->local_window) { 2084 if (data_len > c->local_window) {
2039 logit("channel %d: rcvd too much data %d, win %d", 2085 logit("channel %d: rcvd too much data %d, win %d",
2040 c->self, data_len, c->local_window); 2086 c->self, data_len, c->local_window);
2041 xfree(data);
2042 return; 2087 return;
2043 } 2088 }
2044 c->local_window -= data_len; 2089 c->local_window -= data_len;
2045 } 2090 }
2046 packet_check_eom();
2047 if (c->datagram) 2091 if (c->datagram)
2048 buffer_put_string(&c->output, data, data_len); 2092 buffer_put_string(&c->output, data, data_len);
2049 else 2093 else
2050 buffer_append(&c->output, data, data_len); 2094 buffer_append(&c->output, data, data_len);
2051 xfree(data); 2095 packet_check_eom();
2052} 2096}
2053 2097
2054/* ARGSUSED */ 2098/* ARGSUSED */
@@ -2212,9 +2256,9 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
2212 if (compat20) { 2256 if (compat20) {
2213 c->remote_window = packet_get_int(); 2257 c->remote_window = packet_get_int();
2214 c->remote_maxpacket = packet_get_int(); 2258 c->remote_maxpacket = packet_get_int();
2215 if (c->confirm) { 2259 if (c->open_confirm) {
2216 debug2("callback start"); 2260 debug2("callback start");
2217 c->confirm(c->self, c->confirm_ctx); 2261 c->open_confirm(c->self, c->open_confirm_ctx);
2218 debug2("callback done"); 2262 debug2("callback done");
2219 } 2263 }
2220 debug2("channel %d: open confirm rwindow %u rmax %u", c->self, 2264 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
@@ -2303,7 +2347,7 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt)
2303 Channel *c = NULL; 2347 Channel *c = NULL;
2304 u_short host_port; 2348 u_short host_port;
2305 char *host, *originator_string; 2349 char *host, *originator_string;
2306 int remote_id, sock = -1; 2350 int remote_id;
2307 2351
2308 remote_id = packet_get_int(); 2352 remote_id = packet_get_int();
2309 host = packet_get_string(NULL); 2353 host = packet_get_string(NULL);
@@ -2315,22 +2359,46 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt)
2315 originator_string = xstrdup("unknown (remote did not supply name)"); 2359 originator_string = xstrdup("unknown (remote did not supply name)");
2316 } 2360 }
2317 packet_check_eom(); 2361 packet_check_eom();
2318 sock = channel_connect_to(host, host_port); 2362 c = channel_connect_to(host, host_port,
2319 if (sock != -1) { 2363 "connected socket", originator_string);
2320 c = channel_new("connected socket",
2321 SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
2322 originator_string, 1);
2323 c->remote_id = remote_id;
2324 }
2325 xfree(originator_string); 2364 xfree(originator_string);
2365 xfree(host);
2326 if (c == NULL) { 2366 if (c == NULL) {
2327 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 2367 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2328 packet_put_int(remote_id); 2368 packet_put_int(remote_id);
2329 packet_send(); 2369 packet_send();
2330 } 2370 } else
2331 xfree(host); 2371 c->remote_id = remote_id;
2332} 2372}
2333 2373
2374/* ARGSUSED */
2375void
2376channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
2377{
2378 Channel *c;
2379 struct channel_confirm *cc;
2380 int remote_id;
2381
2382 /* Reset keepalive timeout */
2383 keep_alive_timeouts = 0;
2384
2385 remote_id = packet_get_int();
2386 packet_check_eom();
2387
2388 debug2("channel_input_confirm: type %d id %d", type, remote_id);
2389
2390 if ((c = channel_lookup(remote_id)) == NULL) {
2391 logit("channel_input_success_failure: %d: unknown", remote_id);
2392 return;
2393 }
2394 ;
2395 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
2396 return;
2397 cc->cb(type, c, cc->ctx);
2398 TAILQ_REMOVE(&c->status_confirms, cc, entry);
2399 bzero(cc, sizeof(*cc));
2400 xfree(cc);
2401}
2334 2402
2335/* -- tcp forwarding */ 2403/* -- tcp forwarding */
2336 2404
@@ -2385,7 +2453,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2385 wildcard = 1; 2453 wildcard = 1;
2386 } else if (gateway_ports || is_client) { 2454 } else if (gateway_ports || is_client) {
2387 if (((datafellows & SSH_OLD_FORWARD_ADDR) && 2455 if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
2388 strcmp(listen_addr, "0.0.0.0") == 0) || 2456 strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
2389 *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || 2457 *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
2390 (!is_client && gateway_ports == 1)) 2458 (!is_client && gateway_ports == 1))
2391 wildcard = 1; 2459 wildcard = 1;
@@ -2409,10 +2477,11 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2409 if (addr == NULL) { 2477 if (addr == NULL) {
2410 /* This really shouldn't happen */ 2478 /* This really shouldn't happen */
2411 packet_disconnect("getaddrinfo: fatal error: %s", 2479 packet_disconnect("getaddrinfo: fatal error: %s",
2412 gai_strerror(r)); 2480 ssh_gai_strerror(r));
2413 } else { 2481 } else {
2414 error("channel_setup_fwd_listener: " 2482 error("channel_setup_fwd_listener: "
2415 "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); 2483 "getaddrinfo(%.64s): %s", addr,
2484 ssh_gai_strerror(r));
2416 } 2485 }
2417 return 0; 2486 return 0;
2418 } 2487 }
@@ -2717,35 +2786,37 @@ channel_clear_adm_permitted_opens(void)
2717 num_adm_permitted_opens = 0; 2786 num_adm_permitted_opens = 0;
2718} 2787}
2719 2788
2720/* return socket to remote host, port */ 2789void
2790channel_print_adm_permitted_opens(void)
2791{
2792 int i;
2793
2794 for (i = 0; i < num_adm_permitted_opens; i++)
2795 if (permitted_adm_opens[i].host_to_connect != NULL)
2796 printf(" %s:%d", permitted_adm_opens[i].host_to_connect,
2797 permitted_adm_opens[i].port_to_connect);
2798}
2799
2800/* Try to start non-blocking connect to next host in cctx list */
2721static int 2801static int
2722connect_to(const char *host, u_short port) 2802connect_next(struct channel_connect *cctx)
2723{ 2803{
2724 struct addrinfo hints, *ai, *aitop; 2804 int sock, saved_errno;
2725 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 2805 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
2726 int gaierr;
2727 int sock = -1;
2728 2806
2729 memset(&hints, 0, sizeof(hints)); 2807 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) {
2730 hints.ai_family = IPv4or6; 2808 if (cctx->ai->ai_family != AF_INET &&
2731 hints.ai_socktype = SOCK_STREAM; 2809 cctx->ai->ai_family != AF_INET6)
2732 snprintf(strport, sizeof strport, "%d", port);
2733 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
2734 error("connect_to %.100s: unknown host (%s)", host,
2735 gai_strerror(gaierr));
2736 return -1;
2737 }
2738 for (ai = aitop; ai; ai = ai->ai_next) {
2739 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
2740 continue; 2810 continue;
2741 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), 2811 if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen,
2742 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 2812 ntop, sizeof(ntop), strport, sizeof(strport),
2743 error("connect_to: getnameinfo failed"); 2813 NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
2814 error("connect_next: getnameinfo failed");
2744 continue; 2815 continue;
2745 } 2816 }
2746 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 2817 if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype,
2747 if (sock < 0) { 2818 cctx->ai->ai_protocol)) == -1) {
2748 if (ai->ai_next == NULL) 2819 if (cctx->ai->ai_next == NULL)
2749 error("socket: %.100s", strerror(errno)); 2820 error("socket: %.100s", strerror(errno));
2750 else 2821 else
2751 verbose("socket: %.100s", strerror(errno)); 2822 verbose("socket: %.100s", strerror(errno));
@@ -2753,45 +2824,95 @@ connect_to(const char *host, u_short port)
2753 } 2824 }
2754 if (set_nonblock(sock) == -1) 2825 if (set_nonblock(sock) == -1)
2755 fatal("%s: set_nonblock(%d)", __func__, sock); 2826 fatal("%s: set_nonblock(%d)", __func__, sock);
2756 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && 2827 if (connect(sock, cctx->ai->ai_addr,
2757 errno != EINPROGRESS) { 2828 cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {
2758 error("connect_to %.100s port %s: %.100s", ntop, strport, 2829 debug("connect_next: host %.100s ([%.100s]:%s): "
2830 "%.100s", cctx->host, ntop, strport,
2759 strerror(errno)); 2831 strerror(errno));
2832 saved_errno = errno;
2760 close(sock); 2833 close(sock);
2834 errno = saved_errno;
2761 continue; /* fail -- try next */ 2835 continue; /* fail -- try next */
2762 } 2836 }
2763 break; /* success */ 2837 debug("connect_next: host %.100s ([%.100s]:%s) "
2838 "in progress, fd=%d", cctx->host, ntop, strport, sock);
2839 cctx->ai = cctx->ai->ai_next;
2840 set_nodelay(sock);
2841 return sock;
2842 }
2843 return -1;
2844}
2845
2846static void
2847channel_connect_ctx_free(struct channel_connect *cctx)
2848{
2849 xfree(cctx->host);
2850 if (cctx->aitop)
2851 freeaddrinfo(cctx->aitop);
2852 bzero(cctx, sizeof(*cctx));
2853 cctx->host = NULL;
2854 cctx->ai = cctx->aitop = NULL;
2855}
2856
2857/* Return CONNECTING channel to remote host, port */
2858static Channel *
2859connect_to(const char *host, u_short port, char *ctype, char *rname)
2860{
2861 struct addrinfo hints;
2862 int gaierr;
2863 int sock = -1;
2864 char strport[NI_MAXSERV];
2865 struct channel_connect cctx;
2866 Channel *c;
2764 2867
2868 memset(&cctx, 0, sizeof(cctx));
2869 memset(&hints, 0, sizeof(hints));
2870 hints.ai_family = IPv4or6;
2871 hints.ai_socktype = SOCK_STREAM;
2872 snprintf(strport, sizeof strport, "%d", port);
2873 if ((gaierr = getaddrinfo(host, strport, &hints, &cctx.aitop)) != 0) {
2874 error("connect_to %.100s: unknown host (%s)", host,
2875 ssh_gai_strerror(gaierr));
2876 return NULL;
2765 } 2877 }
2766 freeaddrinfo(aitop); 2878
2767 if (!ai) { 2879 cctx.host = xstrdup(host);
2768 error("connect_to %.100s port %d: failed.", host, port); 2880 cctx.port = port;
2769 return -1; 2881 cctx.ai = cctx.aitop;
2882
2883 if ((sock = connect_next(&cctx)) == -1) {
2884 error("connect to %.100s port %d failed: %s",
2885 host, port, strerror(errno));
2886 channel_connect_ctx_free(&cctx);
2887 return NULL;
2770 } 2888 }
2771 /* success */ 2889 c = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,
2772 set_nodelay(sock); 2890 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
2773 return sock; 2891 c->connect_ctx = cctx;
2892 return c;
2774} 2893}
2775 2894
2776int 2895Channel *
2777channel_connect_by_listen_address(u_short listen_port) 2896channel_connect_by_listen_address(u_short listen_port, char *ctype, char *rname)
2778{ 2897{
2779 int i; 2898 int i;
2780 2899
2781 for (i = 0; i < num_permitted_opens; i++) 2900 for (i = 0; i < num_permitted_opens; i++) {
2782 if (permitted_opens[i].host_to_connect != NULL && 2901 if (permitted_opens[i].host_to_connect != NULL &&
2783 permitted_opens[i].listen_port == listen_port) 2902 permitted_opens[i].listen_port == listen_port) {
2784 return connect_to( 2903 return connect_to(
2785 permitted_opens[i].host_to_connect, 2904 permitted_opens[i].host_to_connect,
2786 permitted_opens[i].port_to_connect); 2905 permitted_opens[i].port_to_connect, ctype, rname);
2906 }
2907 }
2787 error("WARNING: Server requests forwarding for unknown listen_port %d", 2908 error("WARNING: Server requests forwarding for unknown listen_port %d",
2788 listen_port); 2909 listen_port);
2789 return -1; 2910 return NULL;
2790} 2911}
2791 2912
2792/* Check if connecting to that port is permitted and connect. */ 2913/* Check if connecting to that port is permitted and connect. */
2793int 2914Channel *
2794channel_connect_to(const char *host, u_short port) 2915channel_connect_to(const char *host, u_short port, char *ctype, char *rname)
2795{ 2916{
2796 int i, permit, permit_adm = 1; 2917 int i, permit, permit_adm = 1;
2797 2918
@@ -2817,9 +2938,9 @@ channel_connect_to(const char *host, u_short port)
2817 if (!permit || !permit_adm) { 2938 if (!permit || !permit_adm) {
2818 logit("Received request to connect to host %.100s port %d, " 2939 logit("Received request to connect to host %.100s port %d, "
2819 "but the request was denied.", host, port); 2940 "but the request was denied.", host, port);
2820 return -1; 2941 return NULL;
2821 } 2942 }
2822 return connect_to(host, port); 2943 return connect_to(host, port, ctype, rname);
2823} 2944}
2824 2945
2825void 2946void
@@ -2874,7 +2995,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2874 hints.ai_socktype = SOCK_STREAM; 2995 hints.ai_socktype = SOCK_STREAM;
2875 snprintf(strport, sizeof strport, "%d", port); 2996 snprintf(strport, sizeof strport, "%d", port);
2876 if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { 2997 if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
2877 error("getaddrinfo: %.100s", gai_strerror(gaierr)); 2998 error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
2878 return -1; 2999 return -1;
2879 } 3000 }
2880 for (ai = aitop; ai; ai = ai->ai_next) { 3001 for (ai = aitop; ai; ai = ai->ai_next) {
@@ -2900,14 +3021,12 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2900 error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); 3021 error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno));
2901 } 3022 }
2902#endif 3023#endif
2903 channel_set_reuseaddr(sock); 3024 if (x11_use_localhost)
3025 channel_set_reuseaddr(sock);
2904 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 3026 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2905 debug2("bind port %d: %.100s", port, strerror(errno)); 3027 debug2("bind port %d: %.100s", port, strerror(errno));
2906 close(sock); 3028 close(sock);
2907 3029
2908 if (ai->ai_next)
2909 continue;
2910
2911 for (n = 0; n < num_socks; n++) { 3030 for (n = 0; n < num_socks; n++) {
2912 close(socks[n]); 3031 close(socks[n]);
2913 } 3032 }
@@ -2915,17 +3034,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2915 break; 3034 break;
2916 } 3035 }
2917 socks[num_socks++] = sock; 3036 socks[num_socks++] = sock;
2918#ifndef DONT_TRY_OTHER_AF
2919 if (num_socks == NUM_SOCKS) 3037 if (num_socks == NUM_SOCKS)
2920 break; 3038 break;
2921#else
2922 if (x11_use_localhost) {
2923 if (num_socks == NUM_SOCKS)
2924 break;
2925 } else {
2926 break;
2927 }
2928#endif
2929 } 3039 }
2930 freeaddrinfo(aitop); 3040 freeaddrinfo(aitop);
2931 if (num_socks > 0) 3041 if (num_socks > 0)
@@ -3047,7 +3157,8 @@ x11_connect_display(void)
3047 hints.ai_socktype = SOCK_STREAM; 3157 hints.ai_socktype = SOCK_STREAM;
3048 snprintf(strport, sizeof strport, "%u", 6000 + display_number); 3158 snprintf(strport, sizeof strport, "%u", 6000 + display_number);
3049 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { 3159 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
3050 error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); 3160 error("%.100s: unknown host. (%s)", buf,
3161 ssh_gai_strerror(gaierr));
3051 return -1; 3162 return -1;
3052 } 3163 }
3053 for (ai = aitop; ai; ai = ai->ai_next) { 3164 for (ai = aitop; ai; ai = ai->ai_next) {
diff --git a/channels.h b/channels.h
index b632a86af..108b36068 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.89 2007/06/11 09:14:00 markus Exp $ */ 1/* $OpenBSD: channels.h,v 1.96 2008/06/15 20:06:26 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -62,8 +62,27 @@ typedef struct Channel Channel;
62 62
63typedef void channel_callback_fn(int, void *); 63typedef void channel_callback_fn(int, void *);
64typedef int channel_infilter_fn(struct Channel *, char *, int); 64typedef int channel_infilter_fn(struct Channel *, char *, int);
65typedef void channel_filter_cleanup_fn(int, void *);
65typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); 66typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *);
66 67
68/* Channel success/failure callbacks */
69typedef void channel_confirm_cb(int, struct Channel *, void *);
70typedef void channel_confirm_abandon_cb(struct Channel *, void *);
71struct channel_confirm {
72 TAILQ_ENTRY(channel_confirm) entry;
73 channel_confirm_cb *cb;
74 channel_confirm_abandon_cb *abandon_cb;
75 void *ctx;
76};
77TAILQ_HEAD(channel_confirms, channel_confirm);
78
79/* Context for non-blocking connects */
80struct channel_connect {
81 char *host;
82 int port;
83 struct addrinfo *ai, *aitop;
84};
85
67struct Channel { 86struct Channel {
68 int type; /* channel type/state */ 87 int type; /* channel type/state */
69 int self; /* my own channel identifier */ 88 int self; /* my own channel identifier */
@@ -104,16 +123,23 @@ struct Channel {
104 char *ctype; /* type */ 123 char *ctype; /* type */
105 124
106 /* callback */ 125 /* callback */
107 channel_callback_fn *confirm; 126 channel_callback_fn *open_confirm;
108 void *confirm_ctx; 127 void *open_confirm_ctx;
109 channel_callback_fn *detach_user; 128 channel_callback_fn *detach_user;
110 int detach_close; 129 int detach_close;
130 struct channel_confirms status_confirms;
111 131
112 /* filter */ 132 /* filter */
113 channel_infilter_fn *input_filter; 133 channel_infilter_fn *input_filter;
114 channel_outfilter_fn *output_filter; 134 channel_outfilter_fn *output_filter;
135 void *filter_ctx;
136 channel_filter_cleanup_fn *filter_cleanup;
137
138 /* keep boundaries */
139 int datagram;
115 140
116 int datagram; /* keep boundaries */ 141 /* non-blocking connect */
142 struct channel_connect connect_ctx;
117}; 143};
118 144
119#define CHAN_EXTENDED_IGNORE 0 145#define CHAN_EXTENDED_IGNORE 0
@@ -162,7 +188,7 @@ struct Channel {
162Channel *channel_by_id(int); 188Channel *channel_by_id(int);
163Channel *channel_lookup(int); 189Channel *channel_lookup(int);
164Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); 190Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int);
165void channel_set_fds(int, int, int, int, int, int, u_int); 191void channel_set_fds(int, int, int, int, int, int, int, u_int);
166void channel_free(Channel *); 192void channel_free(Channel *);
167void channel_free_all(void); 193void channel_free_all(void);
168void channel_stop_listening(void); 194void channel_stop_listening(void);
@@ -170,8 +196,11 @@ void channel_stop_listening(void);
170void channel_send_open(int); 196void channel_send_open(int);
171void channel_request_start(int, char *, int); 197void channel_request_start(int, char *, int);
172void channel_register_cleanup(int, channel_callback_fn *, int); 198void channel_register_cleanup(int, channel_callback_fn *, int);
173void channel_register_confirm(int, channel_callback_fn *, void *); 199void channel_register_open_confirm(int, channel_callback_fn *, void *);
174void channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *); 200void channel_register_filter(int, channel_infilter_fn *,
201 channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
202void channel_register_status_confirm(int, channel_confirm_cb *,
203 channel_confirm_abandon_cb *, void *);
175void channel_cancel_cleanup(int); 204void channel_cancel_cleanup(int);
176int channel_close_fd(int *); 205int channel_close_fd(int *);
177void channel_send_window_changes(void); 206void channel_send_window_changes(void);
@@ -188,6 +217,7 @@ void channel_input_open_confirmation(int, u_int32_t, void *);
188void channel_input_open_failure(int, u_int32_t, void *); 217void channel_input_open_failure(int, u_int32_t, void *);
189void channel_input_port_open(int, u_int32_t, void *); 218void channel_input_port_open(int, u_int32_t, void *);
190void channel_input_window_adjust(int, u_int32_t, void *); 219void channel_input_window_adjust(int, u_int32_t, void *);
220void channel_input_status_confirm(int, u_int32_t, void *);
191 221
192/* file descriptor handling (read/write) */ 222/* file descriptor handling (read/write) */
193 223
@@ -208,9 +238,10 @@ void channel_add_permitted_opens(char *, int);
208int channel_add_adm_permitted_opens(char *, int); 238int channel_add_adm_permitted_opens(char *, int);
209void channel_clear_permitted_opens(void); 239void channel_clear_permitted_opens(void);
210void channel_clear_adm_permitted_opens(void); 240void channel_clear_adm_permitted_opens(void);
241void channel_print_adm_permitted_opens(void);
211int channel_input_port_forward_request(int, int); 242int channel_input_port_forward_request(int, int);
212int channel_connect_to(const char *, u_short); 243Channel *channel_connect_to(const char *, u_short, char *, char *);
213int channel_connect_by_listen_address(u_short); 244Channel *channel_connect_by_listen_address(u_short, char *, char *);
214int channel_request_remote_forwarding(const char *, u_short, 245int channel_request_remote_forwarding(const char *, u_short,
215 const char *, u_short); 246 const char *, u_short);
216int channel_setup_local_fwd_listener(const char *, u_short, 247int channel_setup_local_fwd_listener(const char *, u_short,
@@ -225,7 +256,7 @@ int x11_connect_display(void);
225int x11_create_display_inet(int, int, int, u_int *, int **); 256int x11_create_display_inet(int, int, int, u_int *, int **);
226void x11_input_open(int, u_int32_t, void *); 257void x11_input_open(int, u_int32_t, void *);
227void x11_request_forwarding_with_spoofing(int, const char *, const char *, 258void x11_request_forwarding_with_spoofing(int, const char *, const char *,
228 const char *); 259 const char *);
229void deny_input_open(int, u_int32_t, void *); 260void deny_input_open(int, u_int32_t, void *);
230 261
231/* agent forwarding */ 262/* agent forwarding */
@@ -240,6 +271,7 @@ void chan_mark_dead(Channel *);
240/* channel events */ 271/* channel events */
241 272
242void chan_rcvd_oclose(Channel *); 273void chan_rcvd_oclose(Channel *);
274void chan_rcvd_eow(Channel *); /* SSH2-only */
243void chan_read_failed(Channel *); 275void chan_read_failed(Channel *);
244void chan_ibuf_empty(Channel *); 276void chan_ibuf_empty(Channel *);
245 277
diff --git a/clientloop.c b/clientloop.c
index b57fda042..f10fab769 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.181 2007/08/15 08:14:46 markus Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.201 2008/07/16 11:51:14 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
@@ -86,6 +86,7 @@
86#include <pwd.h> 86#include <pwd.h>
87#include <unistd.h> 87#include <unistd.h>
88 88
89#include "openbsd-compat/sys-queue.h"
89#include "xmalloc.h" 90#include "xmalloc.h"
90#include "ssh.h" 91#include "ssh.h"
91#include "ssh1.h" 92#include "ssh1.h"
@@ -120,7 +121,7 @@ extern int stdin_null_flag;
120extern int no_shell_flag; 121extern int no_shell_flag;
121 122
122/* Control socket */ 123/* Control socket */
123extern int control_fd; 124extern int muxserver_sock;
124 125
125/* 126/*
126 * Name of the host we are connecting to. This is the name given on the 127 * Name of the host we are connecting to. This is the name given on the
@@ -143,36 +144,46 @@ static int in_non_blocking_mode = 0;
143 144
144/* Common data for the client loop code. */ 145/* Common data for the client loop code. */
145static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ 146static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
146static int escape_char; /* Escape character. */ 147static int escape_char1; /* Escape character. (proto1 only) */
147static int escape_pending; /* Last character was the escape character */ 148static int escape_pending1; /* Last character was an escape (proto1 only) */
148static int last_was_cr; /* Last character was a newline. */ 149static int last_was_cr; /* Last character was a newline. */
149static int exit_status; /* Used to store the exit status of the command. */ 150static int exit_status; /* Used to store the command exit status. */
150static int stdin_eof; /* EOF has been encountered on standard error. */ 151static int stdin_eof; /* EOF has been encountered on stderr. */
151static Buffer stdin_buffer; /* Buffer for stdin data. */ 152static Buffer stdin_buffer; /* Buffer for stdin data. */
152static Buffer stdout_buffer; /* Buffer for stdout data. */ 153static Buffer stdout_buffer; /* Buffer for stdout data. */
153static Buffer stderr_buffer; /* Buffer for stderr data. */ 154static Buffer stderr_buffer; /* Buffer for stderr data. */
154static u_long stdin_bytes, stdout_bytes, stderr_bytes;
155static u_int buffer_high;/* Soft max buffer size. */ 155static u_int buffer_high;/* Soft max buffer size. */
156static int connection_in; /* Connection to server (input). */ 156static int connection_in; /* Connection to server (input). */
157static int connection_out; /* Connection to server (output). */ 157static int connection_out; /* Connection to server (output). */
158static int need_rekeying; /* Set to non-zero if rekeying is requested. */ 158static int need_rekeying; /* Set to non-zero if rekeying is requested. */
159static int session_closed = 0; /* In SSH2: login session closed. */ 159static int session_closed = 0; /* In SSH2: login session closed. */
160static int server_alive_timeouts = 0;
161 160
162static void client_init_dispatch(void); 161static void client_init_dispatch(void);
163int session_ident = -1; 162int session_ident = -1;
164 163
165struct confirm_ctx { 164/* Track escape per proto2 channel */
166 int want_tty; 165struct escape_filter_ctx {
167 int want_subsys; 166 int escape_pending;
168 int want_x_fwd; 167 int escape_char;
169 int want_agent_fwd;
170 Buffer cmd;
171 char *term;
172 struct termios tio;
173 char **env;
174}; 168};
175 169
170/* Context for channel confirmation replies */
171struct channel_reply_ctx {
172 const char *request_type;
173 int id, do_close;
174};
175
176/* Global request success/failure callbacks */
177struct global_confirm {
178 TAILQ_ENTRY(global_confirm) entry;
179 global_confirm_cb *cb;
180 void *ctx;
181 int ref_count;
182};
183TAILQ_HEAD(global_confirms, global_confirm);
184static struct global_confirms global_confirms =
185 TAILQ_HEAD_INITIALIZER(global_confirms);
186
176/*XXX*/ 187/*XXX*/
177extern Kex *xxx_kex; 188extern Kex *xxx_kex;
178 189
@@ -380,7 +391,10 @@ client_check_initial_eof_on_stdin(void)
380 /* Check for immediate EOF on stdin. */ 391 /* Check for immediate EOF on stdin. */
381 len = read(fileno(stdin), buf, 1); 392 len = read(fileno(stdin), buf, 1);
382 if (len == 0) { 393 if (len == 0) {
383 /* EOF. Record that we have seen it and send EOF to server. */ 394 /*
395 * EOF. Record that we have seen it and send
396 * EOF to server.
397 */
384 debug("Sending eof."); 398 debug("Sending eof.");
385 stdin_eof = 1; 399 stdin_eof = 1;
386 packet_start(SSH_CMSG_EOF); 400 packet_start(SSH_CMSG_EOF);
@@ -391,8 +405,8 @@ client_check_initial_eof_on_stdin(void)
391 * and also process it as an escape character if 405 * and also process it as an escape character if
392 * appropriate. 406 * appropriate.
393 */ 407 */
394 if ((u_char) buf[0] == escape_char) 408 if ((u_char) buf[0] == escape_char1)
395 escape_pending = 1; 409 escape_pending1 = 1;
396 else 410 else
397 buffer_append(&stdin_buffer, buf, 1); 411 buffer_append(&stdin_buffer, buf, 1);
398 } 412 }
@@ -422,7 +436,6 @@ client_make_packets_from_stdin_data(void)
422 packet_put_string(buffer_ptr(&stdin_buffer), len); 436 packet_put_string(buffer_ptr(&stdin_buffer), len);
423 packet_send(); 437 packet_send();
424 buffer_consume(&stdin_buffer, len); 438 buffer_consume(&stdin_buffer, len);
425 stdin_bytes += len;
426 /* If we have a pending EOF, send it now. */ 439 /* If we have a pending EOF, send it now. */
427 if (stdin_eof && buffer_len(&stdin_buffer) == 0) { 440 if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
428 packet_start(SSH_CMSG_EOF); 441 packet_start(SSH_CMSG_EOF);
@@ -467,14 +480,25 @@ client_check_window_change(void)
467static void 480static void
468client_global_request_reply(int type, u_int32_t seq, void *ctxt) 481client_global_request_reply(int type, u_int32_t seq, void *ctxt)
469{ 482{
470 server_alive_timeouts = 0; 483 struct global_confirm *gc;
471 client_global_request_reply_fwd(type, seq, ctxt); 484
485 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
486 return;
487 if (gc->cb != NULL)
488 gc->cb(type, seq, gc->ctx);
489 if (--gc->ref_count <= 0) {
490 TAILQ_REMOVE(&global_confirms, gc, entry);
491 bzero(gc, sizeof(*gc));
492 xfree(gc);
493 }
494
495 keep_alive_timeouts = 0;
472} 496}
473 497
474static void 498static void
475server_alive_check(void) 499server_alive_check(void)
476{ 500{
477 if (++server_alive_timeouts > options.server_alive_count_max) { 501 if (++keep_alive_timeouts > options.server_alive_count_max) {
478 logit("Timeout, server not responding."); 502 logit("Timeout, server not responding.");
479 cleanup_exit(255); 503 cleanup_exit(255);
480 } 504 }
@@ -482,6 +506,8 @@ server_alive_check(void)
482 packet_put_cstring("keepalive@openssh.com"); 506 packet_put_cstring("keepalive@openssh.com");
483 packet_put_char(1); /* boolean: want reply */ 507 packet_put_char(1); /* boolean: want reply */
484 packet_send(); 508 packet_send();
509 /* Insert an empty placeholder to maintain ordering */
510 client_register_global_confirm(NULL, NULL);
485} 511}
486 512
487/* 513/*
@@ -533,8 +559,8 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
533 if (packet_have_data_to_write()) 559 if (packet_have_data_to_write())
534 FD_SET(connection_out, *writesetp); 560 FD_SET(connection_out, *writesetp);
535 561
536 if (control_fd != -1) 562 if (muxserver_sock != -1)
537 FD_SET(control_fd, *readsetp); 563 FD_SET(muxserver_sock, *readsetp);
538 564
539 /* 565 /*
540 * Wait for something to happen. This will suspend the process until 566 * Wait for something to happen. This will suspend the process until
@@ -576,9 +602,11 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
576{ 602{
577 /* Flush stdout and stderr buffers. */ 603 /* Flush stdout and stderr buffers. */
578 if (buffer_len(bout) > 0) 604 if (buffer_len(bout) > 0)
579 atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); 605 atomicio(vwrite, fileno(stdout), buffer_ptr(bout),
606 buffer_len(bout));
580 if (buffer_len(berr) > 0) 607 if (buffer_len(berr) > 0)
581 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); 608 atomicio(vwrite, fileno(stderr), buffer_ptr(berr),
609 buffer_len(berr));
582 610
583 leave_raw_mode(); 611 leave_raw_mode();
584 612
@@ -618,9 +646,13 @@ client_process_net_input(fd_set *readset)
618 /* Read as much as possible. */ 646 /* Read as much as possible. */
619 len = read(connection_in, buf, sizeof(buf)); 647 len = read(connection_in, buf, sizeof(buf));
620 if (len == 0) { 648 if (len == 0) {
621 /* Received EOF. The remote host has closed the connection. */ 649 /*
622 snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", 650 * Received EOF. The remote host has closed the
623 host); 651 * connection.
652 */
653 snprintf(buf, sizeof buf,
654 "Connection to %.300s closed by remote host.\r\n",
655 host);
624 buffer_append(&stderr_buffer, buf, strlen(buf)); 656 buffer_append(&stderr_buffer, buf, strlen(buf));
625 quit_pending = 1; 657 quit_pending = 1;
626 return; 658 return;
@@ -629,13 +661,18 @@ client_process_net_input(fd_set *readset)
629 * There is a kernel bug on Solaris that causes select to 661 * There is a kernel bug on Solaris that causes select to
630 * sometimes wake up even though there is no data available. 662 * sometimes wake up even though there is no data available.
631 */ 663 */
632 if (len < 0 && (errno == EAGAIN || errno == EINTR)) 664 if (len < 0 &&
665 (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
633 len = 0; 666 len = 0;
634 667
635 if (len < 0) { 668 if (len < 0) {
636 /* An error has encountered. Perhaps there is a network problem. */ 669 /*
637 snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", 670 * An error has encountered. Perhaps there is a
638 host, strerror(errno)); 671 * network problem.
672 */
673 snprintf(buf, sizeof buf,
674 "Read from remote host %.300s: %.100s\r\n",
675 host, strerror(errno));
639 buffer_append(&stderr_buffer, buf, strlen(buf)); 676 buffer_append(&stderr_buffer, buf, strlen(buf));
640 quit_pending = 1; 677 quit_pending = 1;
641 return; 678 return;
@@ -645,289 +682,81 @@ client_process_net_input(fd_set *readset)
645} 682}
646 683
647static void 684static void
648client_subsystem_reply(int type, u_int32_t seq, void *ctxt) 685client_status_confirm(int type, Channel *c, void *ctx)
649{ 686{
650 int id; 687 struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx;
651 Channel *c; 688 char errmsg[256];
652 689 int tochan;
653 id = packet_get_int(); 690
654 packet_check_eom(); 691 /* XXX supress on mux _client_ quietmode */
655 692 tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
656 if ((c = channel_lookup(id)) == NULL) { 693 c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
657 error("%s: no channel for id %d", __func__, id); 694
658 return; 695 if (type == SSH2_MSG_CHANNEL_SUCCESS) {
659 } 696 debug2("%s request accepted on channel %d",
660 697 cr->request_type, c->self);
661 if (type == SSH2_MSG_CHANNEL_SUCCESS) 698 } else if (type == SSH2_MSG_CHANNEL_FAILURE) {
662 debug2("Request suceeded on channel %d", id); 699 if (tochan) {
663 else if (type == SSH2_MSG_CHANNEL_FAILURE) { 700 snprintf(errmsg, sizeof(errmsg),
664 error("Request failed on channel %d", id); 701 "%s request failed\r\n", cr->request_type);
665 channel_free(c); 702 } else {
703 snprintf(errmsg, sizeof(errmsg),
704 "%s request failed on channel %d",
705 cr->request_type, c->self);
706 }
707 /* If error occurred on primary session channel, then exit */
708 if (cr->do_close && c->self == session_ident)
709 fatal("%s", errmsg);
710 /* If error occurred on mux client, append to their stderr */
711 if (tochan)
712 buffer_append(&c->extended, errmsg, strlen(errmsg));
713 else
714 error("%s", errmsg);
715 if (cr->do_close) {
716 chan_read_failed(c);
717 chan_write_failed(c);
718 }
666 } 719 }
720 xfree(cr);
667} 721}
668 722
669static void 723static void
670client_extra_session2_setup(int id, void *arg) 724client_abandon_status_confirm(Channel *c, void *ctx)
671{ 725{
672 struct confirm_ctx *cctx = arg; 726 xfree(ctx);
673 const char *display;
674 Channel *c;
675 int i;
676
677 if (cctx == NULL)
678 fatal("%s: cctx == NULL", __func__);
679 if ((c = channel_lookup(id)) == NULL)
680 fatal("%s: no channel for id %d", __func__, id);
681
682 display = getenv("DISPLAY");
683 if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
684 char *proto, *data;
685 /* Get reasonable local authentication information. */
686 client_x11_get_proto(display, options.xauth_location,
687 options.forward_x11_trusted, &proto, &data);
688 /* Request forwarding with authentication spoofing. */
689 debug("Requesting X11 forwarding with authentication spoofing.");
690 x11_request_forwarding_with_spoofing(id, display, proto, data);
691 /* XXX wait for reply */
692 }
693
694 if (cctx->want_agent_fwd && options.forward_agent) {
695 debug("Requesting authentication agent forwarding.");
696 channel_request_start(id, "auth-agent-req@openssh.com", 0);
697 packet_send();
698 }
699
700 client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
701 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env,
702 client_subsystem_reply);
703
704 c->confirm_ctx = NULL;
705 buffer_free(&cctx->cmd);
706 xfree(cctx->term);
707 if (cctx->env != NULL) {
708 for (i = 0; cctx->env[i] != NULL; i++)
709 xfree(cctx->env[i]);
710 xfree(cctx->env);
711 }
712 xfree(cctx);
713} 727}
714 728
715static void 729static void
716client_process_control(fd_set *readset) 730client_expect_confirm(int id, const char *request, int do_close)
717{ 731{
718 Buffer m; 732 struct channel_reply_ctx *cr = xmalloc(sizeof(*cr));
719 Channel *c;
720 int client_fd, new_fd[3], ver, allowed, window, packetmax;
721 socklen_t addrlen;
722 struct sockaddr_storage addr;
723 struct confirm_ctx *cctx;
724 char *cmd;
725 u_int i, len, env_len, command, flags;
726 uid_t euid;
727 gid_t egid;
728
729 /*
730 * Accept connection on control socket
731 */
732 if (control_fd == -1 || !FD_ISSET(control_fd, readset))
733 return;
734
735 memset(&addr, 0, sizeof(addr));
736 addrlen = sizeof(addr);
737 if ((client_fd = accept(control_fd,
738 (struct sockaddr*)&addr, &addrlen)) == -1) {
739 error("%s accept: %s", __func__, strerror(errno));
740 return;
741 }
742
743 if (getpeereid(client_fd, &euid, &egid) < 0) {
744 error("%s getpeereid failed: %s", __func__, strerror(errno));
745 close(client_fd);
746 return;
747 }
748 if ((euid != 0) && (getuid() != euid)) {
749 error("control mode uid mismatch: peer euid %u != uid %u",
750 (u_int) euid, (u_int) getuid());
751 close(client_fd);
752 return;
753 }
754
755 unset_nonblock(client_fd);
756
757 /* Read command */
758 buffer_init(&m);
759 if (ssh_msg_recv(client_fd, &m) == -1) {
760 error("%s: client msg_recv failed", __func__);
761 close(client_fd);
762 buffer_free(&m);
763 return;
764 }
765 if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
766 error("%s: wrong client version %d", __func__, ver);
767 buffer_free(&m);
768 close(client_fd);
769 return;
770 }
771
772 allowed = 1;
773 command = buffer_get_int(&m);
774 flags = buffer_get_int(&m);
775
776 buffer_clear(&m);
777
778 switch (command) {
779 case SSHMUX_COMMAND_OPEN:
780 if (options.control_master == SSHCTL_MASTER_ASK ||
781 options.control_master == SSHCTL_MASTER_AUTO_ASK)
782 allowed = ask_permission("Allow shared connection "
783 "to %s? ", host);
784 /* continue below */
785 break;
786 case SSHMUX_COMMAND_TERMINATE:
787 if (options.control_master == SSHCTL_MASTER_ASK ||
788 options.control_master == SSHCTL_MASTER_AUTO_ASK)
789 allowed = ask_permission("Terminate shared connection "
790 "to %s? ", host);
791 if (allowed)
792 quit_pending = 1;
793 /* FALLTHROUGH */
794 case SSHMUX_COMMAND_ALIVE_CHECK:
795 /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
796 buffer_clear(&m);
797 buffer_put_int(&m, allowed);
798 buffer_put_int(&m, getpid());
799 if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
800 error("%s: client msg_send failed", __func__);
801 close(client_fd);
802 buffer_free(&m);
803 return;
804 }
805 buffer_free(&m);
806 close(client_fd);
807 return;
808 default:
809 error("Unsupported command %d", command);
810 buffer_free(&m);
811 close(client_fd);
812 return;
813 }
814
815 /* Reply for SSHMUX_COMMAND_OPEN */
816 buffer_clear(&m);
817 buffer_put_int(&m, allowed);
818 buffer_put_int(&m, getpid());
819 if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
820 error("%s: client msg_send failed", __func__);
821 close(client_fd);
822 buffer_free(&m);
823 return;
824 }
825
826 if (!allowed) {
827 error("Refused control connection");
828 close(client_fd);
829 buffer_free(&m);
830 return;
831 }
832 733
833 buffer_clear(&m); 734 cr->request_type = request;
834 if (ssh_msg_recv(client_fd, &m) == -1) { 735 cr->do_close = do_close;
835 error("%s: client msg_recv failed", __func__);
836 close(client_fd);
837 buffer_free(&m);
838 return;
839 }
840 if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
841 error("%s: wrong client version %d", __func__, ver);
842 buffer_free(&m);
843 close(client_fd);
844 return;
845 }
846 736
847 cctx = xcalloc(1, sizeof(*cctx)); 737 channel_register_status_confirm(id, client_status_confirm,
848 cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; 738 client_abandon_status_confirm, cr);
849 cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; 739}
850 cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
851 cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
852 cctx->term = buffer_get_string(&m, &len);
853
854 cmd = buffer_get_string(&m, &len);
855 buffer_init(&cctx->cmd);
856 buffer_append(&cctx->cmd, cmd, strlen(cmd));
857
858 env_len = buffer_get_int(&m);
859 env_len = MIN(env_len, 4096);
860 debug3("%s: receiving %d env vars", __func__, env_len);
861 if (env_len != 0) {
862 cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env));
863 for (i = 0; i < env_len; i++)
864 cctx->env[i] = buffer_get_string(&m, &len);
865 cctx->env[i] = NULL;
866 }
867 740
868 debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, 741void
869 cctx->want_tty, cctx->want_subsys, cmd); 742client_register_global_confirm(global_confirm_cb *cb, void *ctx)
870 xfree(cmd); 743{
871 744 struct global_confirm *gc, *last_gc;
872 /* Gather fds from client */ 745
873 new_fd[0] = mm_receive_fd(client_fd); 746 /* Coalesce identical callbacks */
874 new_fd[1] = mm_receive_fd(client_fd); 747 last_gc = TAILQ_LAST(&global_confirms, global_confirms);
875 new_fd[2] = mm_receive_fd(client_fd); 748 if (last_gc && last_gc->cb == cb && last_gc->ctx == ctx) {
876 749 if (++last_gc->ref_count >= INT_MAX)
877 debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, 750 fatal("%s: last_gc->ref_count = %d",
878 new_fd[0], new_fd[1], new_fd[2]); 751 __func__, last_gc->ref_count);
879
880 /* Try to pick up ttymodes from client before it goes raw */
881 if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
882 error("%s: tcgetattr: %s", __func__, strerror(errno));
883
884 /* This roundtrip is just for synchronisation of ttymodes */
885 buffer_clear(&m);
886 if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
887 error("%s: client msg_send failed", __func__);
888 close(client_fd);
889 close(new_fd[0]);
890 close(new_fd[1]);
891 close(new_fd[2]);
892 buffer_free(&m);
893 xfree(cctx->term);
894 if (env_len != 0) {
895 for (i = 0; i < env_len; i++)
896 xfree(cctx->env[i]);
897 xfree(cctx->env);
898 }
899 return; 752 return;
900 } 753 }
901 buffer_free(&m);
902
903 /* enable nonblocking unless tty */
904 if (!isatty(new_fd[0]))
905 set_nonblock(new_fd[0]);
906 if (!isatty(new_fd[1]))
907 set_nonblock(new_fd[1]);
908 if (!isatty(new_fd[2]))
909 set_nonblock(new_fd[2]);
910
911 set_nonblock(client_fd);
912
913 window = CHAN_SES_WINDOW_DEFAULT;
914 packetmax = CHAN_SES_PACKET_DEFAULT;
915 if (cctx->want_tty) {
916 window >>= 1;
917 packetmax >>= 1;
918 }
919
920 c = channel_new("session", SSH_CHANNEL_OPENING,
921 new_fd[0], new_fd[1], new_fd[2], window, packetmax,
922 CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
923 754
924 /* XXX */ 755 gc = xmalloc(sizeof(*gc));
925 c->ctl_fd = client_fd; 756 gc->cb = cb;
926 757 gc->ctx = ctx;
927 debug3("%s: channel_new: %d", __func__, c->self); 758 gc->ref_count = 1;
928 759 TAILQ_INSERT_TAIL(&global_confirms, gc, entry);
929 channel_send_open(c->self);
930 channel_register_confirm(c->self, client_extra_session2_setup, cctx);
931} 760}
932 761
933static void 762static void
@@ -940,6 +769,9 @@ process_cmdline(void)
940 u_short cancel_port; 769 u_short cancel_port;
941 Forward fwd; 770 Forward fwd;
942 771
772 bzero(&fwd, sizeof(fwd));
773 fwd.listen_host = fwd.connect_host = NULL;
774
943 leave_raw_mode(); 775 leave_raw_mode();
944 handler = signal(SIGINT, SIG_IGN); 776 handler = signal(SIGINT, SIG_IGN);
945 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 777 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
@@ -1039,11 +871,18 @@ out:
1039 enter_raw_mode(); 871 enter_raw_mode();
1040 if (cmd) 872 if (cmd)
1041 xfree(cmd); 873 xfree(cmd);
874 if (fwd.listen_host != NULL)
875 xfree(fwd.listen_host);
876 if (fwd.connect_host != NULL)
877 xfree(fwd.connect_host);
1042} 878}
1043 879
1044/* process the characters one by one */ 880/*
881 * Process the characters one by one, call with c==NULL for proto1 case.
882 */
1045static int 883static int
1046process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) 884process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
885 char *buf, int len)
1047{ 886{
1048 char string[1024]; 887 char string[1024];
1049 pid_t pid; 888 pid_t pid;
@@ -1051,7 +890,20 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
1051 u_int i; 890 u_int i;
1052 u_char ch; 891 u_char ch;
1053 char *s; 892 char *s;
893 int *escape_pendingp, escape_char;
894 struct escape_filter_ctx *efc;
1054 895
896 if (c == NULL) {
897 escape_pendingp = &escape_pending1;
898 escape_char = escape_char1;
899 } else {
900 if (c->filter_ctx == NULL)
901 return 0;
902 efc = (struct escape_filter_ctx *)c->filter_ctx;
903 escape_pendingp = &efc->escape_pending;
904 escape_char = efc->escape_char;
905 }
906
1055 if (len <= 0) 907 if (len <= 0)
1056 return (0); 908 return (0);
1057 909
@@ -1059,25 +911,42 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
1059 /* Get one character at a time. */ 911 /* Get one character at a time. */
1060 ch = buf[i]; 912 ch = buf[i];
1061 913
1062 if (escape_pending) { 914 if (*escape_pendingp) {
1063 /* We have previously seen an escape character. */ 915 /* We have previously seen an escape character. */
1064 /* Clear the flag now. */ 916 /* Clear the flag now. */
1065 escape_pending = 0; 917 *escape_pendingp = 0;
1066 918
1067 /* Process the escaped character. */ 919 /* Process the escaped character. */
1068 switch (ch) { 920 switch (ch) {
1069 case '.': 921 case '.':
1070 /* Terminate the connection. */ 922 /* Terminate the connection. */
1071 snprintf(string, sizeof string, "%c.\r\n", escape_char); 923 snprintf(string, sizeof string, "%c.\r\n",
924 escape_char);
1072 buffer_append(berr, string, strlen(string)); 925 buffer_append(berr, string, strlen(string));
1073 926
1074 quit_pending = 1; 927 if (c && c->ctl_fd != -1) {
928 chan_read_failed(c);
929 chan_write_failed(c);
930 return 0;
931 } else
932 quit_pending = 1;
1075 return -1; 933 return -1;
1076 934
1077 case 'Z' - 64: 935 case 'Z' - 64:
1078 /* Suspend the program. */ 936 /* XXX support this for mux clients */
1079 /* Print a message to that effect to the user. */ 937 if (c && c->ctl_fd != -1) {
1080 snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char); 938 noescape:
939 snprintf(string, sizeof string,
940 "%c%c escape not available to "
941 "multiplexed sessions\r\n",
942 escape_char, ch);
943 buffer_append(berr, string,
944 strlen(string));
945 continue;
946 }
947 /* Suspend the program. Inform the user */
948 snprintf(string, sizeof string,
949 "%c^Z [suspend ssh]\r\n", escape_char);
1081 buffer_append(berr, string, strlen(string)); 950 buffer_append(berr, string, strlen(string));
1082 951
1083 /* Restore terminal modes and suspend. */ 952 /* Restore terminal modes and suspend. */
@@ -1102,16 +971,20 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
1102 case 'R': 971 case 'R':
1103 if (compat20) { 972 if (compat20) {
1104 if (datafellows & SSH_BUG_NOREKEY) 973 if (datafellows & SSH_BUG_NOREKEY)
1105 logit("Server does not support re-keying"); 974 logit("Server does not "
975 "support re-keying");
1106 else 976 else
1107 need_rekeying = 1; 977 need_rekeying = 1;
1108 } 978 }
1109 continue; 979 continue;
1110 980
1111 case '&': 981 case '&':
982 if (c && c->ctl_fd != -1)
983 goto noescape;
1112 /* 984 /*
1113 * Detach the program (continue to serve connections, 985 * Detach the program (continue to serve
1114 * but put in background and no more new connections). 986 * connections, but put in background and no
987 * more new connections).
1115 */ 988 */
1116 /* Restore tty modes. */ 989 /* Restore tty modes. */
1117 leave_raw_mode(); 990 leave_raw_mode();
@@ -1140,9 +1013,9 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
1140 return -1; 1013 return -1;
1141 } else if (!stdin_eof) { 1014 } else if (!stdin_eof) {
1142 /* 1015 /*
1143 * Sending SSH_CMSG_EOF alone does not always appear 1016 * Sending SSH_CMSG_EOF alone does not
1144 * to be enough. So we try to send an EOF character 1017 * always appear to be enough. So we
1145 * first. 1018 * try to send an EOF character first.
1146 */ 1019 */
1147 packet_start(SSH_CMSG_STDIN_DATA); 1020 packet_start(SSH_CMSG_STDIN_DATA);
1148 packet_put_string("\004", 1); 1021 packet_put_string("\004", 1);
@@ -1157,27 +1030,50 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
1157 continue; 1030 continue;
1158 1031
1159 case '?': 1032 case '?':
1160 snprintf(string, sizeof string, 1033 if (c && c->ctl_fd != -1) {
1034 snprintf(string, sizeof string,
1161"%c?\r\n\ 1035"%c?\r\n\
1162Supported escape sequences:\r\n\ 1036Supported escape sequences:\r\n\
1163%c. - terminate connection\r\n\ 1037 %c. - terminate session\r\n\
1164%cB - send a BREAK to the remote system\r\n\ 1038 %cB - send a BREAK to the remote system\r\n\
1165%cC - open a command line\r\n\ 1039 %cC - open a command line\r\n\
1166%cR - Request rekey (SSH protocol 2 only)\r\n\ 1040 %cR - Request rekey (SSH protocol 2 only)\r\n\
1167%c^Z - suspend ssh\r\n\ 1041 %c# - list forwarded connections\r\n\
1168%c# - list forwarded connections\r\n\ 1042 %c? - this message\r\n\
1169%c& - background ssh (when waiting for connections to terminate)\r\n\ 1043 %c%c - send the escape character by typing it twice\r\n\
1170%c? - this message\r\n\
1171%c%c - send the escape character by typing it twice\r\n\
1172(Note that escapes are only recognized immediately after newline.)\r\n", 1044(Note that escapes are only recognized immediately after newline.)\r\n",
1173 escape_char, escape_char, escape_char, escape_char, 1045 escape_char, escape_char,
1174 escape_char, escape_char, escape_char, escape_char, 1046 escape_char, escape_char,
1175 escape_char, escape_char, escape_char); 1047 escape_char, escape_char,
1048 escape_char, escape_char,
1049 escape_char);
1050 } else {
1051 snprintf(string, sizeof string,
1052"%c?\r\n\
1053Supported escape sequences:\r\n\
1054 %c. - terminate connection (and any multiplexed sessions)\r\n\
1055 %cB - send a BREAK to the remote system\r\n\
1056 %cC - open a command line\r\n\
1057 %cR - Request rekey (SSH protocol 2 only)\r\n\
1058 %c^Z - suspend ssh\r\n\
1059 %c# - list forwarded connections\r\n\
1060 %c& - background ssh (when waiting for connections to terminate)\r\n\
1061 %c? - this message\r\n\
1062 %c%c - send the escape character by typing it twice\r\n\
1063(Note that escapes are only recognized immediately after newline.)\r\n",
1064 escape_char, escape_char,
1065 escape_char, escape_char,
1066 escape_char, escape_char,
1067 escape_char, escape_char,
1068 escape_char, escape_char,
1069 escape_char);
1070 }
1176 buffer_append(berr, string, strlen(string)); 1071 buffer_append(berr, string, strlen(string));
1177 continue; 1072 continue;
1178 1073
1179 case '#': 1074 case '#':
1180 snprintf(string, sizeof string, "%c#\r\n", escape_char); 1075 snprintf(string, sizeof string, "%c#\r\n",
1076 escape_char);
1181 buffer_append(berr, string, strlen(string)); 1077 buffer_append(berr, string, strlen(string));
1182 s = channel_open_message(); 1078 s = channel_open_message();
1183 buffer_append(berr, s, strlen(s)); 1079 buffer_append(berr, s, strlen(s));
@@ -1198,12 +1094,15 @@ Supported escape sequences:\r\n\
1198 } 1094 }
1199 } else { 1095 } else {
1200 /* 1096 /*
1201 * The previous character was not an escape char. Check if this 1097 * The previous character was not an escape char.
1202 * is an escape. 1098 * Check if this is an escape.
1203 */ 1099 */
1204 if (last_was_cr && ch == escape_char) { 1100 if (last_was_cr && ch == escape_char) {
1205 /* It is. Set the flag and continue to next character. */ 1101 /*
1206 escape_pending = 1; 1102 * It is. Set the flag and continue to
1103 * next character.
1104 */
1105 *escape_pendingp = 1;
1207 continue; 1106 continue;
1208 } 1107 }
1209 } 1108 }
@@ -1229,7 +1128,8 @@ client_process_input(fd_set *readset)
1229 if (FD_ISSET(fileno(stdin), readset)) { 1128 if (FD_ISSET(fileno(stdin), readset)) {
1230 /* Read as much as possible. */ 1129 /* Read as much as possible. */
1231 len = read(fileno(stdin), buf, sizeof(buf)); 1130 len = read(fileno(stdin), buf, sizeof(buf));
1232 if (len < 0 && (errno == EAGAIN || errno == EINTR)) 1131 if (len < 0 &&
1132 (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
1233 return; /* we'll try again later */ 1133 return; /* we'll try again later */
1234 if (len <= 0) { 1134 if (len <= 0) {
1235 /* 1135 /*
@@ -1238,7 +1138,8 @@ client_process_input(fd_set *readset)
1238 * if it was an error condition. 1138 * if it was an error condition.
1239 */ 1139 */
1240 if (len < 0) { 1140 if (len < 0) {
1241 snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); 1141 snprintf(buf, sizeof buf, "read: %.100s\r\n",
1142 strerror(errno));
1242 buffer_append(&stderr_buffer, buf, strlen(buf)); 1143 buffer_append(&stderr_buffer, buf, strlen(buf));
1243 } 1144 }
1244 /* Mark that we have seen EOF. */ 1145 /* Mark that we have seen EOF. */
@@ -1254,7 +1155,7 @@ client_process_input(fd_set *readset)
1254 packet_start(SSH_CMSG_EOF); 1155 packet_start(SSH_CMSG_EOF);
1255 packet_send(); 1156 packet_send();
1256 } 1157 }
1257 } else if (escape_char == SSH_ESCAPECHAR_NONE) { 1158 } else if (escape_char1 == SSH_ESCAPECHAR_NONE) {
1258 /* 1159 /*
1259 * Normal successful read, and no escape character. 1160 * Normal successful read, and no escape character.
1260 * Just append the data to buffer. 1161 * Just append the data to buffer.
@@ -1262,11 +1163,12 @@ client_process_input(fd_set *readset)
1262 buffer_append(&stdin_buffer, buf, len); 1163 buffer_append(&stdin_buffer, buf, len);
1263 } else { 1164 } else {
1264 /* 1165 /*
1265 * Normal, successful read. But we have an escape character 1166 * Normal, successful read. But we have an escape
1266 * and have to process the characters one by one. 1167 * character and have to process the characters one
1168 * by one.
1267 */ 1169 */
1268 if (process_escapes(&stdin_buffer, &stdout_buffer, 1170 if (process_escapes(NULL, &stdin_buffer,
1269 &stderr_buffer, buf, len) == -1) 1171 &stdout_buffer, &stderr_buffer, buf, len) == -1)
1270 return; 1172 return;
1271 } 1173 }
1272 } 1174 }
@@ -1284,14 +1186,16 @@ client_process_output(fd_set *writeset)
1284 len = write(fileno(stdout), buffer_ptr(&stdout_buffer), 1186 len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
1285 buffer_len(&stdout_buffer)); 1187 buffer_len(&stdout_buffer));
1286 if (len <= 0) { 1188 if (len <= 0) {
1287 if (errno == EINTR || errno == EAGAIN) 1189 if (errno == EINTR || errno == EAGAIN ||
1190 errno == EWOULDBLOCK)
1288 len = 0; 1191 len = 0;
1289 else { 1192 else {
1290 /* 1193 /*
1291 * An error or EOF was encountered. Put an 1194 * An error or EOF was encountered. Put an
1292 * error message to stderr buffer. 1195 * error message to stderr buffer.
1293 */ 1196 */
1294 snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); 1197 snprintf(buf, sizeof buf,
1198 "write stdout: %.50s\r\n", strerror(errno));
1295 buffer_append(&stderr_buffer, buf, strlen(buf)); 1199 buffer_append(&stderr_buffer, buf, strlen(buf));
1296 quit_pending = 1; 1200 quit_pending = 1;
1297 return; 1201 return;
@@ -1299,7 +1203,6 @@ client_process_output(fd_set *writeset)
1299 } 1203 }
1300 /* Consume printed data from the buffer. */ 1204 /* Consume printed data from the buffer. */
1301 buffer_consume(&stdout_buffer, len); 1205 buffer_consume(&stdout_buffer, len);
1302 stdout_bytes += len;
1303 } 1206 }
1304 /* Write buffered output to stderr. */ 1207 /* Write buffered output to stderr. */
1305 if (FD_ISSET(fileno(stderr), writeset)) { 1208 if (FD_ISSET(fileno(stderr), writeset)) {
@@ -1307,17 +1210,20 @@ client_process_output(fd_set *writeset)
1307 len = write(fileno(stderr), buffer_ptr(&stderr_buffer), 1210 len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
1308 buffer_len(&stderr_buffer)); 1211 buffer_len(&stderr_buffer));
1309 if (len <= 0) { 1212 if (len <= 0) {
1310 if (errno == EINTR || errno == EAGAIN) 1213 if (errno == EINTR || errno == EAGAIN ||
1214 errno == EWOULDBLOCK)
1311 len = 0; 1215 len = 0;
1312 else { 1216 else {
1313 /* EOF or error, but can't even print error message. */ 1217 /*
1218 * EOF or error, but can't even print
1219 * error message.
1220 */
1314 quit_pending = 1; 1221 quit_pending = 1;
1315 return; 1222 return;
1316 } 1223 }
1317 } 1224 }
1318 /* Consume printed characters from the buffer. */ 1225 /* Consume printed characters from the buffer. */
1319 buffer_consume(&stderr_buffer, len); 1226 buffer_consume(&stderr_buffer, len);
1320 stderr_bytes += len;
1321 } 1227 }
1322} 1228}
1323 1229
@@ -1336,16 +1242,39 @@ client_process_output(fd_set *writeset)
1336static void 1242static void
1337client_process_buffered_input_packets(void) 1243client_process_buffered_input_packets(void)
1338{ 1244{
1339 dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL); 1245 dispatch_run(DISPATCH_NONBLOCK, &quit_pending,
1246 compat20 ? xxx_kex : NULL);
1340} 1247}
1341 1248
1342/* scan buf[] for '~' before sending data to the peer */ 1249/* scan buf[] for '~' before sending data to the peer */
1343 1250
1344static int 1251/* Helper: allocate a new escape_filter_ctx and fill in its escape char */
1345simple_escape_filter(Channel *c, char *buf, int len) 1252void *
1253client_new_escape_filter_ctx(int escape_char)
1254{
1255 struct escape_filter_ctx *ret;
1256
1257 ret = xmalloc(sizeof(*ret));
1258 ret->escape_pending = 0;
1259 ret->escape_char = escape_char;
1260 return (void *)ret;
1261}
1262
1263/* Free the escape filter context on channel free */
1264void
1265client_filter_cleanup(int cid, void *ctx)
1266{
1267 xfree(ctx);
1268}
1269
1270int
1271client_simple_escape_filter(Channel *c, char *buf, int len)
1346{ 1272{
1347 /* XXX we assume c->extended is writeable */ 1273 if (c->extended_usage != CHAN_EXTENDED_WRITE)
1348 return process_escapes(&c->input, &c->output, &c->extended, buf, len); 1274 return 0;
1275
1276 return process_escapes(c, &c->input, &c->output, &c->extended,
1277 buf, len);
1349} 1278}
1350 1279
1351static void 1280static void
@@ -1369,6 +1298,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1369 fd_set *readset = NULL, *writeset = NULL; 1298 fd_set *readset = NULL, *writeset = NULL;
1370 double start_time, total_time; 1299 double start_time, total_time;
1371 int max_fd = 0, max_fd2 = 0, len, rekeying = 0; 1300 int max_fd = 0, max_fd2 = 0, len, rekeying = 0;
1301 u_int64_t ibytes, obytes;
1372 u_int nalloc = 0; 1302 u_int nalloc = 0;
1373 char buf[100]; 1303 char buf[100];
1374 1304
@@ -1377,7 +1307,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1377 start_time = get_current_time(); 1307 start_time = get_current_time();
1378 1308
1379 /* Initialize variables. */ 1309 /* Initialize variables. */
1380 escape_pending = 0; 1310 escape_pending1 = 0;
1381 last_was_cr = 1; 1311 last_was_cr = 1;
1382 exit_status = -1; 1312 exit_status = -1;
1383 stdin_eof = 0; 1313 stdin_eof = 0;
@@ -1385,8 +1315,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1385 connection_in = packet_get_connection_in(); 1315 connection_in = packet_get_connection_in();
1386 connection_out = packet_get_connection_out(); 1316 connection_out = packet_get_connection_out();
1387 max_fd = MAX(connection_in, connection_out); 1317 max_fd = MAX(connection_in, connection_out);
1388 if (control_fd != -1) 1318 if (muxserver_sock != -1)
1389 max_fd = MAX(max_fd, control_fd); 1319 max_fd = MAX(max_fd, muxserver_sock);
1390 1320
1391 if (!compat20) { 1321 if (!compat20) {
1392 /* enable nonblocking unless tty */ 1322 /* enable nonblocking unless tty */
@@ -1400,11 +1330,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1400 max_fd = MAX(max_fd, fileno(stdout)); 1330 max_fd = MAX(max_fd, fileno(stdout));
1401 max_fd = MAX(max_fd, fileno(stderr)); 1331 max_fd = MAX(max_fd, fileno(stderr));
1402 } 1332 }
1403 stdin_bytes = 0;
1404 stdout_bytes = 0;
1405 stderr_bytes = 0;
1406 quit_pending = 0; 1333 quit_pending = 0;
1407 escape_char = escape_char_arg; 1334 escape_char1 = escape_char_arg;
1408 1335
1409 /* Initialize buffers. */ 1336 /* Initialize buffers. */
1410 buffer_init(&stdin_buffer); 1337 buffer_init(&stdin_buffer);
@@ -1432,9 +1359,11 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1432 1359
1433 if (compat20) { 1360 if (compat20) {
1434 session_ident = ssh2_chan_id; 1361 session_ident = ssh2_chan_id;
1435 if (escape_char != SSH_ESCAPECHAR_NONE) 1362 if (escape_char_arg != SSH_ESCAPECHAR_NONE)
1436 channel_register_filter(session_ident, 1363 channel_register_filter(session_ident,
1437 simple_escape_filter, NULL); 1364 client_simple_escape_filter, NULL,
1365 client_filter_cleanup,
1366 client_new_escape_filter_ctx(escape_char_arg));
1438 if (session_ident != -1) 1367 if (session_ident != -1)
1439 channel_register_cleanup(session_ident, 1368 channel_register_cleanup(session_ident,
1440 client_channel_closed, 0); 1369 client_channel_closed, 0);
@@ -1506,7 +1435,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1506 client_process_net_input(readset); 1435 client_process_net_input(readset);
1507 1436
1508 /* Accept control connections. */ 1437 /* Accept control connections. */
1509 client_process_control(readset); 1438 if (muxserver_sock != -1 &&FD_ISSET(muxserver_sock, readset)) {
1439 if (muxserver_accept_control())
1440 quit_pending = 1;
1441 }
1510 1442
1511 if (quit_pending) 1443 if (quit_pending)
1512 break; 1444 break;
@@ -1521,7 +1453,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1521 client_process_output(writeset); 1453 client_process_output(writeset);
1522 } 1454 }
1523 1455
1524 /* Send as much buffered packet data as possible to the sender. */ 1456 /*
1457 * Send as much buffered packet data as possible to the
1458 * sender.
1459 */
1525 if (FD_ISSET(connection_out, writeset)) 1460 if (FD_ISSET(connection_out, writeset))
1526 packet_write_poll(); 1461 packet_write_poll();
1527 } 1462 }
@@ -1566,7 +1501,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1566 * that the connection has been closed. 1501 * that the connection has been closed.
1567 */ 1502 */
1568 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { 1503 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
1569 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); 1504 snprintf(buf, sizeof buf,
1505 "Connection to %.64s closed.\r\n", host);
1570 buffer_append(&stderr_buffer, buf, strlen(buf)); 1506 buffer_append(&stderr_buffer, buf, strlen(buf));
1571 } 1507 }
1572 1508
@@ -1579,7 +1515,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1579 break; 1515 break;
1580 } 1516 }
1581 buffer_consume(&stdout_buffer, len); 1517 buffer_consume(&stdout_buffer, len);
1582 stdout_bytes += len;
1583 } 1518 }
1584 1519
1585 /* Output any buffered data for stderr. */ 1520 /* Output any buffered data for stderr. */
@@ -1591,7 +1526,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1591 break; 1526 break;
1592 } 1527 }
1593 buffer_consume(&stderr_buffer, len); 1528 buffer_consume(&stderr_buffer, len);
1594 stderr_bytes += len;
1595 } 1529 }
1596 1530
1597 /* Clear and free any buffers. */ 1531 /* Clear and free any buffers. */
@@ -1602,13 +1536,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1602 1536
1603 /* Report bytes transferred, and transfer rates. */ 1537 /* Report bytes transferred, and transfer rates. */
1604 total_time = get_current_time() - start_time; 1538 total_time = get_current_time() - start_time;
1605 debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", 1539 packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
1606 stdin_bytes, stdout_bytes, stderr_bytes, total_time); 1540 packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
1541 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
1542 obytes, ibytes, total_time);
1607 if (total_time > 0) 1543 if (total_time > 0)
1608 debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", 1544 verbose("Bytes per second: sent %.1f, received %.1f",
1609 stdin_bytes / total_time, stdout_bytes / total_time, 1545 obytes / total_time, ibytes / total_time);
1610 stderr_bytes / total_time);
1611
1612 /* Return the exit status of the program. */ 1546 /* Return the exit status of the program. */
1613 debug("Exit status %d", exit_status); 1547 debug("Exit status %d", exit_status);
1614 return exit_status; 1548 return exit_status;
@@ -1699,7 +1633,6 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
1699 Channel *c = NULL; 1633 Channel *c = NULL;
1700 char *listen_address, *originator_address; 1634 char *listen_address, *originator_address;
1701 int listen_port, originator_port; 1635 int listen_port, originator_port;
1702 int sock;
1703 1636
1704 /* Get rest of the packet */ 1637 /* Get rest of the packet */
1705 listen_address = packet_get_string(NULL); 1638 listen_address = packet_get_string(NULL);
@@ -1708,19 +1641,13 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
1708 originator_port = packet_get_int(); 1641 originator_port = packet_get_int();
1709 packet_check_eom(); 1642 packet_check_eom();
1710 1643
1711 debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d", 1644 debug("client_request_forwarded_tcpip: listen %s port %d, "
1712 listen_address, listen_port, originator_address, originator_port); 1645 "originator %s port %d", listen_address, listen_port,
1646 originator_address, originator_port);
1647
1648 c = channel_connect_by_listen_address(listen_port,
1649 "forwarded-tcpip", originator_address);
1713 1650
1714 sock = channel_connect_by_listen_address(listen_port);
1715 if (sock < 0) {
1716 xfree(originator_address);
1717 xfree(listen_address);
1718 return NULL;
1719 }
1720 c = channel_new("forwarded-tcpip",
1721 SSH_CHANNEL_CONNECTING, sock, sock, -1,
1722 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1723 originator_address, 1);
1724 xfree(originator_address); 1651 xfree(originator_address);
1725 xfree(listen_address); 1652 xfree(listen_address);
1726 return c; 1653 return c;
@@ -1736,7 +1663,8 @@ client_request_x11(const char *request_type, int rchan)
1736 1663
1737 if (!options.forward_x11) { 1664 if (!options.forward_x11) {
1738 error("Warning: ssh server tried X11 forwarding."); 1665 error("Warning: ssh server tried X11 forwarding.");
1739 error("Warning: this is probably a break-in attempt by a malicious server."); 1666 error("Warning: this is probably a break-in attempt by a "
1667 "malicious server.");
1740 return NULL; 1668 return NULL;
1741 } 1669 }
1742 originator = packet_get_string(NULL); 1670 originator = packet_get_string(NULL);
@@ -1769,7 +1697,8 @@ client_request_agent(const char *request_type, int rchan)
1769 1697
1770 if (!options.forward_agent) { 1698 if (!options.forward_agent) {
1771 error("Warning: ssh server tried agent forwarding."); 1699 error("Warning: ssh server tried agent forwarding.");
1772 error("Warning: this is probably a break-in attempt by a malicious server."); 1700 error("Warning: this is probably a break-in attempt by a "
1701 "malicious server.");
1773 return NULL; 1702 return NULL;
1774 } 1703 }
1775 sock = ssh_get_authentication_socket(); 1704 sock = ssh_get_authentication_socket();
@@ -1777,7 +1706,7 @@ client_request_agent(const char *request_type, int rchan)
1777 return NULL; 1706 return NULL;
1778 c = channel_new("authentication agent connection", 1707 c = channel_new("authentication agent connection",
1779 SSH_CHANNEL_OPEN, sock, sock, -1, 1708 SSH_CHANNEL_OPEN, sock, sock, -1,
1780 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, 1709 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
1781 "authentication agent connection", 1); 1710 "authentication agent connection", 1);
1782 c->force_drain = 1; 1711 c->force_drain = 1;
1783 return c; 1712 return c;
@@ -1812,7 +1741,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
1812#if defined(SSH_TUN_FILTER) 1741#if defined(SSH_TUN_FILTER)
1813 if (options.tun_open == SSH_TUNMODE_POINTOPOINT) 1742 if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
1814 channel_register_filter(c->self, sys_tun_infilter, 1743 channel_register_filter(c->self, sys_tun_infilter,
1815 sys_tun_outfilter); 1744 sys_tun_outfilter, NULL, NULL);
1816#endif 1745#endif
1817 1746
1818 packet_start(SSH2_MSG_CHANNEL_OPEN); 1747 packet_start(SSH2_MSG_CHANNEL_OPEN);
@@ -1895,7 +1824,11 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
1895 if (id == -1) { 1824 if (id == -1) {
1896 error("client_input_channel_req: request for channel -1"); 1825 error("client_input_channel_req: request for channel -1");
1897 } else if ((c = channel_lookup(id)) == NULL) { 1826 } else if ((c = channel_lookup(id)) == NULL) {
1898 error("client_input_channel_req: channel %d: unknown channel", id); 1827 error("client_input_channel_req: channel %d: "
1828 "unknown channel", id);
1829 } else if (strcmp(rtype, "eow@openssh.com") == 0) {
1830 packet_check_eom();
1831 chan_rcvd_eow(c);
1899 } else if (strcmp(rtype, "exit-status") == 0) { 1832 } else if (strcmp(rtype, "exit-status") == 0) {
1900 exitval = packet_get_int(); 1833 exitval = packet_get_int();
1901 if (id == session_ident) { 1834 if (id == session_ident) {
@@ -1940,8 +1873,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
1940 1873
1941void 1874void
1942client_session2_setup(int id, int want_tty, int want_subsystem, 1875client_session2_setup(int id, int want_tty, int want_subsystem,
1943 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env, 1876 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)
1944 dispatch_fn *subsys_repl)
1945{ 1877{
1946 int len; 1878 int len;
1947 Channel *c = NULL; 1879 Channel *c = NULL;
@@ -1953,20 +1885,21 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
1953 1885
1954 if (want_tty) { 1886 if (want_tty) {
1955 struct winsize ws; 1887 struct winsize ws;
1956 struct termios tio;
1957 1888
1958 /* Store window size in the packet. */ 1889 /* Store window size in the packet. */
1959 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) 1890 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)
1960 memset(&ws, 0, sizeof(ws)); 1891 memset(&ws, 0, sizeof(ws));
1961 1892
1962 channel_request_start(id, "pty-req", 0); 1893 channel_request_start(id, "pty-req", 1);
1894 client_expect_confirm(id, "PTY allocation", 0);
1963 packet_put_cstring(term != NULL ? term : ""); 1895 packet_put_cstring(term != NULL ? term : "");
1964 packet_put_int((u_int)ws.ws_col); 1896 packet_put_int((u_int)ws.ws_col);
1965 packet_put_int((u_int)ws.ws_row); 1897 packet_put_int((u_int)ws.ws_row);
1966 packet_put_int((u_int)ws.ws_xpixel); 1898 packet_put_int((u_int)ws.ws_xpixel);
1967 packet_put_int((u_int)ws.ws_ypixel); 1899 packet_put_int((u_int)ws.ws_ypixel);
1968 tio = get_saved_tio(); 1900 if (tiop == NULL)
1969 tty_make_modes(-1, tiop != NULL ? tiop : &tio); 1901 tiop = get_saved_tio();
1902 tty_make_modes(-1, tiop);
1970 packet_send(); 1903 packet_send();
1971 /* XXX wait for reply */ 1904 /* XXX wait for reply */
1972 c->client_tty = 1; 1905 c->client_tty = 1;
@@ -2014,22 +1947,21 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2014 if (len > 900) 1947 if (len > 900)
2015 len = 900; 1948 len = 900;
2016 if (want_subsystem) { 1949 if (want_subsystem) {
2017 debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd)); 1950 debug("Sending subsystem: %.*s",
2018 channel_request_start(id, "subsystem", subsys_repl != NULL); 1951 len, (u_char*)buffer_ptr(cmd));
2019 if (subsys_repl != NULL) { 1952 channel_request_start(id, "subsystem", 1);
2020 /* register callback for reply */ 1953 client_expect_confirm(id, "subsystem", 1);
2021 /* XXX we assume that client_loop has already been called */
2022 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, subsys_repl);
2023 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, subsys_repl);
2024 }
2025 } else { 1954 } else {
2026 debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd)); 1955 debug("Sending command: %.*s",
2027 channel_request_start(id, "exec", 0); 1956 len, (u_char*)buffer_ptr(cmd));
1957 channel_request_start(id, "exec", 1);
1958 client_expect_confirm(id, "exec", 1);
2028 } 1959 }
2029 packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 1960 packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
2030 packet_send(); 1961 packet_send();
2031 } else { 1962 } else {
2032 channel_request_start(id, "shell", 0); 1963 channel_request_start(id, "shell", 1);
1964 client_expect_confirm(id, "shell", 1);
2033 packet_send(); 1965 packet_send();
2034 } 1966 }
2035} 1967}
@@ -2048,6 +1980,8 @@ client_init_dispatch_20(void)
2048 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 1980 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
2049 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); 1981 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
2050 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 1982 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
1983 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
1984 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
2051 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); 1985 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
2052 1986
2053 /* rekeying */ 1987 /* rekeying */
@@ -2057,6 +1991,7 @@ client_init_dispatch_20(void)
2057 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); 1991 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
2058 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 1992 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
2059} 1993}
1994
2060static void 1995static void
2061client_init_dispatch_13(void) 1996client_init_dispatch_13(void)
2062{ 1997{
@@ -2076,6 +2011,7 @@ client_init_dispatch_13(void)
2076 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? 2011 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
2077 &x11_input_open : &deny_input_open); 2012 &x11_input_open : &deny_input_open);
2078} 2013}
2014
2079static void 2015static void
2080client_init_dispatch_15(void) 2016client_init_dispatch_15(void)
2081{ 2017{
@@ -2083,6 +2019,7 @@ client_init_dispatch_15(void)
2083 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); 2019 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
2084 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); 2020 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
2085} 2021}
2022
2086static void 2023static void
2087client_init_dispatch(void) 2024client_init_dispatch(void)
2088{ 2025{
@@ -2100,7 +2037,7 @@ cleanup_exit(int i)
2100{ 2037{
2101 leave_raw_mode(); 2038 leave_raw_mode();
2102 leave_non_blocking(); 2039 leave_non_blocking();
2103 if (options.control_path != NULL && control_fd != -1) 2040 if (options.control_path != NULL && muxserver_sock != -1)
2104 unlink(options.control_path); 2041 unlink(options.control_path);
2105 _exit(i); 2042 _exit(i);
2106} 2043}
diff --git a/clientloop.h b/clientloop.h
index c7d2233d0..8bb874b38 100644
--- a/clientloop.h
+++ b/clientloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.h,v 1.17 2007/08/07 07:32:53 djm Exp $ */ 1/* $OpenBSD: clientloop.h,v 1.22 2008/06/12 15:19:17 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -43,11 +43,20 @@ void client_x11_get_proto(const char *, const char *, u_int,
43 char **, char **); 43 char **, char **);
44void client_global_request_reply_fwd(int, u_int32_t, void *); 44void client_global_request_reply_fwd(int, u_int32_t, void *);
45void client_session2_setup(int, int, int, const char *, struct termios *, 45void client_session2_setup(int, int, int, const char *, struct termios *,
46 int, Buffer *, char **, dispatch_fn *); 46 int, Buffer *, char **);
47int client_request_tun_fwd(int, int, int); 47int client_request_tun_fwd(int, int, int);
48 48
49/* Escape filter for protocol 2 sessions */
50void *client_new_escape_filter_ctx(int);
51void client_filter_cleanup(int, void *);
52int client_simple_escape_filter(Channel *, char *, int);
53
54/* Global request confirmation callbacks */
55typedef void global_confirm_cb(int, u_int32_t seq, void *);
56void client_register_global_confirm(global_confirm_cb *, void *);
57
49/* Multiplexing protocol version */ 58/* Multiplexing protocol version */
50#define SSHMUX_VER 1 59#define SSHMUX_VER 2
51 60
52/* Multiplexing control protocol flags */ 61/* Multiplexing control protocol flags */
53#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ 62#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */
@@ -58,3 +67,7 @@ int client_request_tun_fwd(int, int, int);
58#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ 67#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */
59#define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */ 68#define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */
60#define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */ 69#define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */
70
71void muxserver_listen(void);
72int muxserver_accept_control(void);
73void muxclient(const char *);
diff --git a/config.h.in b/config.h.in
index fd8e77dfd..a650bdba8 100644
--- a/config.h.in
+++ b/config.h.in
@@ -7,6 +7,9 @@
7/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */ 7/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */
8#undef AIX_LOGINFAILED_4ARG 8#undef AIX_LOGINFAILED_4ARG
9 9
10/* System only supports IPv4 audit records */
11#undef AU_IPv4
12
10/* Define if your resolver libs need this for getrrsetbyname */ 13/* Define if your resolver libs need this for getrrsetbyname */
11#undef BIND_8_COMPAT 14#undef BIND_8_COMPAT
12 15
@@ -19,6 +22,9 @@
19/* getgroups(0,NULL) will return -1 */ 22/* getgroups(0,NULL) will return -1 */
20#undef BROKEN_GETGROUPS 23#undef BROKEN_GETGROUPS
21 24
25/* FreeBSD glob does not do what we need */
26#undef BROKEN_GLOB
27
22/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ 28/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */
23#undef BROKEN_INET_NTOA 29#undef BROKEN_INET_NTOA
24 30
@@ -32,6 +38,9 @@
32 */ 38 */
33#undef BROKEN_ONE_BYTE_DIRENT_D_NAME 39#undef BROKEN_ONE_BYTE_DIRENT_D_NAME
34 40
41/* Can't do comparisons on readv */
42#undef BROKEN_READV_COMPARISON
43
35/* Define if you have a broken realpath. */ 44/* Define if you have a broken realpath. */
36#undef BROKEN_REALPATH 45#undef BROKEN_REALPATH
37 46
@@ -53,6 +62,9 @@
53/* LynxOS has broken setvbuf() implementation */ 62/* LynxOS has broken setvbuf() implementation */
54#undef BROKEN_SETVBUF 63#undef BROKEN_SETVBUF
55 64
65/* QNX shadow support is broken */
66#undef BROKEN_SHADOW_EXPIRE
67
56/* Define if your snprintf is busted */ 68/* Define if your snprintf is busted */
57#undef BROKEN_SNPRINTF 69#undef BROKEN_SNPRINTF
58 70
@@ -107,12 +119,12 @@
107/* Define if you don't want to use wtmpx */ 119/* Define if you don't want to use wtmpx */
108#undef DISABLE_WTMPX 120#undef DISABLE_WTMPX
109 121
110/* Workaround more Linux IPv6 quirks */
111#undef DONT_TRY_OTHER_AF
112
113/* Builtin PRNG command timeout */ 122/* Builtin PRNG command timeout */
114#undef ENTROPY_TIMEOUT_MSEC 123#undef ENTROPY_TIMEOUT_MSEC
115 124
125/* f_fsid has members */
126#undef FSID_HAS_VAL
127
116/* Define to 1 if the `getpgrp' function requires zero arguments. */ 128/* Define to 1 if the `getpgrp' function requires zero arguments. */
117#undef GETPGRP_VOID 129#undef GETPGRP_VOID
118 130
@@ -149,6 +161,12 @@
149/* Define to 1 if you have the `arc4random' function. */ 161/* Define to 1 if you have the `arc4random' function. */
150#undef HAVE_ARC4RANDOM 162#undef HAVE_ARC4RANDOM
151 163
164/* Define to 1 if you have the `arc4random_buf' function. */
165#undef HAVE_ARC4RANDOM_BUF
166
167/* Define to 1 if you have the `arc4random_uniform' function. */
168#undef HAVE_ARC4RANDOM_UNIFORM
169
152/* Define to 1 if you have the `asprintf' function. */ 170/* Define to 1 if you have the `asprintf' function. */
153#undef HAVE_ASPRINTF 171#undef HAVE_ASPRINTF
154 172
@@ -161,6 +179,9 @@
161/* OpenBSD's gcc has sentinel */ 179/* OpenBSD's gcc has sentinel */
162#undef HAVE_ATTRIBUTE__SENTINEL__ 180#undef HAVE_ATTRIBUTE__SENTINEL__
163 181
182/* Define to 1 if you have the `aug_get_machine' function. */
183#undef HAVE_AUG_GET_MACHINE
184
164/* Define to 1 if you have the `b64_ntop' function. */ 185/* Define to 1 if you have the `b64_ntop' function. */
165#undef HAVE_B64_NTOP 186#undef HAVE_B64_NTOP
166 187
@@ -320,9 +341,21 @@
320/* Define to 1 if you have the <floatingpoint.h> header file. */ 341/* Define to 1 if you have the <floatingpoint.h> header file. */
321#undef HAVE_FLOATINGPOINT_H 342#undef HAVE_FLOATINGPOINT_H
322 343
344/* Define to 1 if you have the `fmt_scaled' function. */
345#undef HAVE_FMT_SCALED
346
323/* Define to 1 if you have the `freeaddrinfo' function. */ 347/* Define to 1 if you have the `freeaddrinfo' function. */
324#undef HAVE_FREEADDRINFO 348#undef HAVE_FREEADDRINFO
325 349
350/* Define to 1 if the system has the type `fsblkcnt_t'. */
351#undef HAVE_FSBLKCNT_T
352
353/* Define to 1 if the system has the type `fsfilcnt_t'. */
354#undef HAVE_FSFILCNT_T
355
356/* Define to 1 if you have the `fstatvfs' function. */
357#undef HAVE_FSTATVFS
358
326/* Define to 1 if you have the `futimes' function. */ 359/* Define to 1 if you have the `futimes' function. */
327#undef HAVE_FUTIMES 360#undef HAVE_FUTIMES
328 361
@@ -344,6 +377,9 @@
344/* Define to 1 if you have the `getgrouplist' function. */ 377/* Define to 1 if you have the `getgrouplist' function. */
345#undef HAVE_GETGROUPLIST 378#undef HAVE_GETGROUPLIST
346 379
380/* Define to 1 if you have the `getgrset' function. */
381#undef HAVE_GETGRSET
382
347/* Define to 1 if you have the `getluid' function. */ 383/* Define to 1 if you have the `getluid' function. */
348#undef HAVE_GETLUID 384#undef HAVE_GETLUID
349 385
@@ -494,6 +530,9 @@
494/* Define to 1 if you have the <libgen.h> header file. */ 530/* Define to 1 if you have the <libgen.h> header file. */
495#undef HAVE_LIBGEN_H 531#undef HAVE_LIBGEN_H
496 532
533/* Define if system has libiaf that supports set_id */
534#undef HAVE_LIBIAF
535
497/* Define to 1 if you have the `nsl' library (-lnsl). */ 536/* Define to 1 if you have the `nsl' library (-lnsl). */
498#undef HAVE_LIBNSL 537#undef HAVE_LIBNSL
499 538
@@ -792,6 +831,12 @@
792/* Fields in struct sockaddr_storage */ 831/* Fields in struct sockaddr_storage */
793#undef HAVE_SS_FAMILY_IN_SS 832#undef HAVE_SS_FAMILY_IN_SS
794 833
834/* Define to 1 if you have the `statfs' function. */
835#undef HAVE_STATFS
836
837/* Define to 1 if you have the `statvfs' function. */
838#undef HAVE_STATVFS
839
795/* Define to 1 if you have the <stddef.h> header file. */ 840/* Define to 1 if you have the <stddef.h> header file. */
796#undef HAVE_STDDEF_H 841#undef HAVE_STDDEF_H
797 842
@@ -894,12 +939,18 @@
894/* Define to 1 if you have the <sys/mman.h> header file. */ 939/* Define to 1 if you have the <sys/mman.h> header file. */
895#undef HAVE_SYS_MMAN_H 940#undef HAVE_SYS_MMAN_H
896 941
942/* Define to 1 if you have the <sys/mount.h> header file. */
943#undef HAVE_SYS_MOUNT_H
944
897/* Define to 1 if you have the <sys/ndir.h> header file. */ 945/* Define to 1 if you have the <sys/ndir.h> header file. */
898#undef HAVE_SYS_NDIR_H 946#undef HAVE_SYS_NDIR_H
899 947
900/* Define if your system defines sys_nerr */ 948/* Define if your system defines sys_nerr */
901#undef HAVE_SYS_NERR 949#undef HAVE_SYS_NERR
902 950
951/* Define to 1 if you have the <sys/poll.h> header file. */
952#undef HAVE_SYS_POLL_H
953
903/* Define to 1 if you have the <sys/prctl.h> header file. */ 954/* Define to 1 if you have the <sys/prctl.h> header file. */
904#undef HAVE_SYS_PRCTL_H 955#undef HAVE_SYS_PRCTL_H
905 956
@@ -912,6 +963,9 @@
912/* Define to 1 if you have the <sys/select.h> header file. */ 963/* Define to 1 if you have the <sys/select.h> header file. */
913#undef HAVE_SYS_SELECT_H 964#undef HAVE_SYS_SELECT_H
914 965
966/* Define to 1 if you have the <sys/statvfs.h> header file. */
967#undef HAVE_SYS_STATVFS_H
968
915/* Define to 1 if you have the <sys/stat.h> header file. */ 969/* Define to 1 if you have the <sys/stat.h> header file. */
916#undef HAVE_SYS_STAT_H 970#undef HAVE_SYS_STAT_H
917 971
diff --git a/configure b/configure
index 1d29674e0..19cc20c84 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
1#! /bin/sh 1#! /bin/sh
2# From configure.ac Revision: 1.383 . 2# From configure.ac Revision: 1.409 .
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.61 for OpenSSH Portable. 4# Generated by GNU Autoconf 2.61 for OpenSSH Portable.
5# 5#
@@ -723,6 +723,7 @@ MANTYPE
723mansubdir 723mansubdir
724user_path 724user_path
725piddir 725piddir
726TEST_SSH_IPV6
726LIBOBJS 727LIBOBJS
727LTLIBOBJS' 728LTLIBOBJS'
728ac_subst_files='' 729ac_subst_files=''
@@ -1324,6 +1325,7 @@ Optional Features:
1324Optional Packages: 1325Optional Packages:
1325 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] 1326 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
1326 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) 1327 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
1328 --without-stackprotect Don't use compiler's stack protection
1327 --without-rpath Disable auto-added -R linker paths 1329 --without-rpath Disable auto-added -R linker paths
1328 --with-cflags Specify additional flags to pass to compiler 1330 --with-cflags Specify additional flags to pass to compiler
1329 --with-cppflags Specify additional flags to pass to preprocessor 1331 --with-cppflags Specify additional flags to pass to preprocessor
@@ -1349,7 +1351,7 @@ Optional Packages:
1349 --with-privsep-user=user Specify non-privileged user for privilege separation 1351 --with-privsep-user=user Specify non-privileged user for privilege separation
1350 --with-sectok Enable smartcard support using libsectok 1352 --with-sectok Enable smartcard support using libsectok
1351 --with-opensc[=PFX] Enable smartcard support using OpenSC (optionally in PATH) 1353 --with-opensc[=PFX] Enable smartcard support using OpenSC (optionally in PATH)
1352 --with-selinux Enable SELinux support 1354 --with-selinux Enable SELinux support
1353 --with-kerberos5=PATH Enable Kerberos 5 support 1355 --with-kerberos5=PATH Enable Kerberos 5 support
1354 --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) 1356 --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)
1355 --with-xauth=PATH Specify path to xauth program 1357 --with-xauth=PATH Specify path to xauth program
@@ -5383,6 +5385,17 @@ if test $ac_cv_have_decl_LLONG_MAX = yes; then
5383fi 5385fi
5384 5386
5385 5387
5388use_stack_protector=1
5389
5390# Check whether --with-stackprotect was given.
5391if test "${with_stackprotect+set}" = set; then
5392 withval=$with_stackprotect;
5393 if test "x$withval" = "xno"; then
5394 use_stack_protector=0
5395 fi
5396fi
5397
5398
5386if test "$GCC" = "yes" || test "$GCC" = "egcs"; then 5399if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
5387 CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized" 5400 CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized"
5388 GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` 5401 GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
@@ -5393,11 +5406,175 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
5393 no_attrib_nonnull=1 5406 no_attrib_nonnull=1
5394 ;; 5407 ;;
5395 2.*) no_attrib_nonnull=1 ;; 5408 2.*) no_attrib_nonnull=1 ;;
5396 3.*) CFLAGS="$CFLAGS -Wsign-compare" ;; 5409 3.*) CFLAGS="$CFLAGS -Wsign-compare -Wformat-security" ;;
5397 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign" ;; 5410 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign -Wformat-security" ;;
5398 *) ;; 5411 *) ;;
5399 esac 5412 esac
5400 5413
5414 { echo "$as_me:$LINENO: checking if $CC accepts -fno-builtin-memset" >&5
5415echo $ECHO_N "checking if $CC accepts -fno-builtin-memset... $ECHO_C" >&6; }
5416 saved_CFLAGS="$CFLAGS"
5417 CFLAGS="$CFLAGS -fno-builtin-memset"
5418 cat >conftest.$ac_ext <<_ACEOF
5419/* confdefs.h. */
5420_ACEOF
5421cat confdefs.h >>conftest.$ac_ext
5422cat >>conftest.$ac_ext <<_ACEOF
5423/* end confdefs.h. */
5424
5425#include <string.h>
5426int main(void){char b[10]; memset(b, 0, sizeof(b));}
5427
5428_ACEOF
5429rm -f conftest.$ac_objext conftest$ac_exeext
5430if { (ac_try="$ac_link"
5431case "(($ac_try" in
5432 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
5433 *) ac_try_echo=$ac_try;;
5434esac
5435eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
5436 (eval "$ac_link") 2>conftest.er1
5437 ac_status=$?
5438 grep -v '^ *+' conftest.er1 >conftest.err
5439 rm -f conftest.er1
5440 cat conftest.err >&5
5441 echo "$as_me:$LINENO: \$? = $ac_status" >&5
5442 (exit $ac_status); } && {
5443 test -z "$ac_c_werror_flag" ||
5444 test ! -s conftest.err
5445 } && test -s conftest$ac_exeext &&
5446 $as_test_x conftest$ac_exeext; then
5447 { echo "$as_me:$LINENO: result: yes" >&5
5448echo "${ECHO_T}yes" >&6; }
5449else
5450 echo "$as_me: failed program was:" >&5
5451sed 's/^/| /' conftest.$ac_ext >&5
5452
5453 { echo "$as_me:$LINENO: result: no" >&5
5454echo "${ECHO_T}no" >&6; }
5455 CFLAGS="$saved_CFLAGS"
5456
5457fi
5458
5459rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
5460 conftest$ac_exeext conftest.$ac_ext
5461
5462 # -fstack-protector-all doesn't always work for some GCC versions
5463 # and/or platforms, so we test if we can. If it's not supported
5464 # on a give platform gcc will emit a warning so we use -Werror.
5465 if test "x$use_stack_protector" = "x1"; then
5466 for t in -fstack-protector-all -fstack-protector; do
5467 { echo "$as_me:$LINENO: checking if $CC supports $t" >&5
5468echo $ECHO_N "checking if $CC supports $t... $ECHO_C" >&6; }
5469 saved_CFLAGS="$CFLAGS"
5470 saved_LDFLAGS="$LDFLAGS"
5471 CFLAGS="$CFLAGS $t -Werror"
5472 LDFLAGS="$LDFLAGS $t -Werror"
5473 cat >conftest.$ac_ext <<_ACEOF
5474/* confdefs.h. */
5475_ACEOF
5476cat confdefs.h >>conftest.$ac_ext
5477cat >>conftest.$ac_ext <<_ACEOF
5478/* end confdefs.h. */
5479
5480#include <stdlib.h>
5481int main(void){return 0;}
5482
5483_ACEOF
5484rm -f conftest.$ac_objext conftest$ac_exeext
5485if { (ac_try="$ac_link"
5486case "(($ac_try" in
5487 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
5488 *) ac_try_echo=$ac_try;;
5489esac
5490eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
5491 (eval "$ac_link") 2>conftest.er1
5492 ac_status=$?
5493 grep -v '^ *+' conftest.er1 >conftest.err
5494 rm -f conftest.er1
5495 cat conftest.err >&5
5496 echo "$as_me:$LINENO: \$? = $ac_status" >&5
5497 (exit $ac_status); } && {
5498 test -z "$ac_c_werror_flag" ||
5499 test ! -s conftest.err
5500 } && test -s conftest$ac_exeext &&
5501 $as_test_x conftest$ac_exeext; then
5502 { echo "$as_me:$LINENO: result: yes" >&5
5503echo "${ECHO_T}yes" >&6; }
5504 CFLAGS="$saved_CFLAGS $t"
5505 LDFLAGS="$saved_LDFLAGS $t"
5506 { echo "$as_me:$LINENO: checking if $t works" >&5
5507echo $ECHO_N "checking if $t works... $ECHO_C" >&6; }
5508 if test "$cross_compiling" = yes; then
5509 { echo "$as_me:$LINENO: WARNING: cross compiling: cannot test" >&5
5510echo "$as_me: WARNING: cross compiling: cannot test" >&2;}
5511 break
5512
5513else
5514 cat >conftest.$ac_ext <<_ACEOF
5515/* confdefs.h. */
5516_ACEOF
5517cat confdefs.h >>conftest.$ac_ext
5518cat >>conftest.$ac_ext <<_ACEOF
5519/* end confdefs.h. */
5520
5521#include <stdlib.h>
5522int main(void){exit(0);}
5523
5524_ACEOF
5525rm -f conftest$ac_exeext
5526if { (ac_try="$ac_link"
5527case "(($ac_try" in
5528 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
5529 *) ac_try_echo=$ac_try;;
5530esac
5531eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
5532 (eval "$ac_link") 2>&5
5533 ac_status=$?
5534 echo "$as_me:$LINENO: \$? = $ac_status" >&5
5535 (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
5536 { (case "(($ac_try" in
5537 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
5538 *) ac_try_echo=$ac_try;;
5539esac
5540eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
5541 (eval "$ac_try") 2>&5
5542 ac_status=$?
5543 echo "$as_me:$LINENO: \$? = $ac_status" >&5
5544 (exit $ac_status); }; }; then
5545 { echo "$as_me:$LINENO: result: yes" >&5
5546echo "${ECHO_T}yes" >&6; }
5547 break
5548else
5549 echo "$as_me: program exited with status $ac_status" >&5
5550echo "$as_me: failed program was:" >&5
5551sed 's/^/| /' conftest.$ac_ext >&5
5552
5553( exit $ac_status )
5554 { echo "$as_me:$LINENO: result: no" >&5
5555echo "${ECHO_T}no" >&6; }
5556fi
5557rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
5558fi
5559
5560
5561
5562else
5563 echo "$as_me: failed program was:" >&5
5564sed 's/^/| /' conftest.$ac_ext >&5
5565
5566 { echo "$as_me:$LINENO: result: no" >&5
5567echo "${ECHO_T}no" >&6; }
5568
5569fi
5570
5571rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
5572 conftest$ac_exeext conftest.$ac_ext
5573 CFLAGS="$saved_CFLAGS"
5574 LDFLAGS="$saved_LDFLAGS"
5575 done
5576 fi
5577
5401 if test -z "$have_llong_max"; then 5578 if test -z "$have_llong_max"; then
5402 # retry LLONG_MAX with -std=gnu99, needed on some Linuxes 5579 # retry LLONG_MAX with -std=gnu99, needed on some Linuxes
5403 unset ac_cv_have_decl_LLONG_MAX 5580 unset ac_cv_have_decl_LLONG_MAX
@@ -5614,6 +5791,9 @@ fi
5614 5791
5615 5792
5616 5793
5794
5795
5796
5617for ac_header in \ 5797for ac_header in \
5618 bstring.h \ 5798 bstring.h \
5619 crypt.h \ 5799 crypt.h \
@@ -5653,7 +5833,9 @@ for ac_header in \
5653 sys/cdefs.h \ 5833 sys/cdefs.h \
5654 sys/dir.h \ 5834 sys/dir.h \
5655 sys/mman.h \ 5835 sys/mman.h \
5836 sys/mount.h \
5656 sys/ndir.h \ 5837 sys/ndir.h \
5838 sys/poll.h \
5657 sys/prctl.h \ 5839 sys/prctl.h \
5658 sys/pstat.h \ 5840 sys/pstat.h \
5659 sys/select.h \ 5841 sys/select.h \
@@ -5661,6 +5843,7 @@ for ac_header in \
5661 sys/stream.h \ 5843 sys/stream.h \
5662 sys/stropts.h \ 5844 sys/stropts.h \
5663 sys/strtio.h \ 5845 sys/strtio.h \
5846 sys/statvfs.h \
5664 sys/sysmacros.h \ 5847 sys/sysmacros.h \
5665 sys/time.h \ 5848 sys/time.h \
5666 sys/timers.h \ 5849 sys/timers.h \
@@ -6761,7 +6944,8 @@ fi
6761 6944
6762 6945
6763 6946
6764for ac_func in setauthdb 6947
6948for ac_func in getgrset setauthdb
6765do 6949do
6766as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` 6950as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
6767{ echo "$as_me:$LINENO: checking for $ac_func" >&5 6951{ echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -7094,6 +7278,11 @@ _ACEOF
7094_ACEOF 7278_ACEOF
7095 7279
7096 7280
7281cat >>confdefs.h <<\_ACEOF
7282#define BROKEN_GLOB 1
7283_ACEOF
7284
7285
7097cat >>confdefs.h <<_ACEOF 7286cat >>confdefs.h <<_ACEOF
7098#define BIND_8_COMPAT 1 7287#define BIND_8_COMPAT 1
7099_ACEOF 7288_ACEOF
@@ -7113,6 +7302,71 @@ cat >>confdefs.h <<\_ACEOF
7113#define SSH_TUN_PREPEND_AF 1 7302#define SSH_TUN_PREPEND_AF 1
7114_ACEOF 7303_ACEOF
7115 7304
7305
7306 { echo "$as_me:$LINENO: checking whether AU_IPv4 is declared" >&5
7307echo $ECHO_N "checking whether AU_IPv4 is declared... $ECHO_C" >&6; }
7308if test "${ac_cv_have_decl_AU_IPv4+set}" = set; then
7309 echo $ECHO_N "(cached) $ECHO_C" >&6
7310else
7311 cat >conftest.$ac_ext <<_ACEOF
7312/* confdefs.h. */
7313_ACEOF
7314cat confdefs.h >>conftest.$ac_ext
7315cat >>conftest.$ac_ext <<_ACEOF
7316/* end confdefs.h. */
7317$ac_includes_default
7318int
7319main ()
7320{
7321#ifndef AU_IPv4
7322 (void) AU_IPv4;
7323#endif
7324
7325 ;
7326 return 0;
7327}
7328_ACEOF
7329rm -f conftest.$ac_objext
7330if { (ac_try="$ac_compile"
7331case "(($ac_try" in
7332 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
7333 *) ac_try_echo=$ac_try;;
7334esac
7335eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
7336 (eval "$ac_compile") 2>conftest.er1
7337 ac_status=$?
7338 grep -v '^ *+' conftest.er1 >conftest.err
7339 rm -f conftest.er1
7340 cat conftest.err >&5
7341 echo "$as_me:$LINENO: \$? = $ac_status" >&5
7342 (exit $ac_status); } && {
7343 test -z "$ac_c_werror_flag" ||
7344 test ! -s conftest.err
7345 } && test -s conftest.$ac_objext; then
7346 ac_cv_have_decl_AU_IPv4=yes
7347else
7348 echo "$as_me: failed program was:" >&5
7349sed 's/^/| /' conftest.$ac_ext >&5
7350
7351 ac_cv_have_decl_AU_IPv4=no
7352fi
7353
7354rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
7355fi
7356{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_AU_IPv4" >&5
7357echo "${ECHO_T}$ac_cv_have_decl_AU_IPv4" >&6; }
7358if test $ac_cv_have_decl_AU_IPv4 = yes; then
7359 :
7360else
7361
7362cat >>confdefs.h <<\_ACEOF
7363#define AU_IPv4 0
7364_ACEOF
7365
7366 #include <bsm/audit.h>
7367
7368fi
7369
7116 ;; 7370 ;;
7117*-*-dragonfly*) 7371*-*-dragonfly*)
7118 SSHDLIBS="$SSHDLIBS -lcrypt" 7372 SSHDLIBS="$SSHDLIBS -lcrypt"
@@ -7433,11 +7687,6 @@ _ACEOF
7433 check_for_openpty_ctty_bug=1 7687 check_for_openpty_ctty_bug=1
7434 7688
7435cat >>confdefs.h <<\_ACEOF 7689cat >>confdefs.h <<\_ACEOF
7436#define DONT_TRY_OTHER_AF 1
7437_ACEOF
7438
7439
7440cat >>confdefs.h <<\_ACEOF
7441#define PAM_TTY_KLUDGE 1 7690#define PAM_TTY_KLUDGE 1
7442_ACEOF 7691_ACEOF
7443 7692
@@ -7956,6 +8205,11 @@ _ACEOF
7956fi 8205fi
7957 8206
7958 8207
8208
8209cat >>confdefs.h <<\_ACEOF
8210#define BROKEN_GLOB 1
8211_ACEOF
8212
7959 ;; 8213 ;;
7960*-*-bsdi*) 8214*-*-bsdi*)
7961 cat >>confdefs.h <<\_ACEOF 8215 cat >>confdefs.h <<\_ACEOF
@@ -8839,6 +9093,11 @@ _ACEOF
8839#define BROKEN_SETREGID 1 9093#define BROKEN_SETREGID 1
8840_ACEOF 9094_ACEOF
8841 9095
9096
9097cat >>confdefs.h <<\_ACEOF
9098#define BROKEN_READV_COMPARISON 1
9099_ACEOF
9100
8842 ;; 9101 ;;
8843 9102
8844*-*-nto-qnx*) 9103*-*-nto-qnx*)
@@ -8873,6 +9132,11 @@ _ACEOF
8873#define SSHD_ACQUIRES_CTTY 1 9132#define SSHD_ACQUIRES_CTTY 1
8874_ACEOF 9133_ACEOF
8875 9134
9135
9136cat >>confdefs.h <<\_ACEOF
9137#define BROKEN_SHADOW_EXPIRE 1
9138_ACEOF
9139
8876 enable_etc_default_login=no # has incompatible /etc/default/login 9140 enable_etc_default_login=no # has incompatible /etc/default/login
8877 case "$host" in 9141 case "$host" in
8878 *-*-nto-qnx6*) 9142 *-*-nto-qnx6*)
@@ -11038,7 +11302,8 @@ fi
11038 11302
11039 11303
11040 11304
11041for ac_func in logout updwtmp logwtmp 11305
11306for ac_func in fmt_scaled logout updwtmp logwtmp
11042do 11307do
11043as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` 11308as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
11044{ echo "$as_me:$LINENO: checking for $ac_func" >&5 11309{ echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -12179,7 +12444,8 @@ done
12179 12444
12180 # These are optional 12445 # These are optional
12181 12446
12182for ac_func in getaudit_addr 12447
12448for ac_func in getaudit_addr aug_get_machine
12183do 12449do
12184as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` 12450as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
12185{ echo "$as_me:$LINENO: checking for $ac_func" >&5 12451{ echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -12386,8 +12652,15 @@ fi
12386 12652
12387 12653
12388 12654
12655
12656
12657
12658
12659
12389for ac_func in \ 12660for ac_func in \
12390 arc4random \ 12661 arc4random \
12662 arc4random_buf \
12663 arc4random_uniform \
12391 asprintf \ 12664 asprintf \
12392 b64_ntop \ 12665 b64_ntop \
12393 __b64_ntop \ 12666 __b64_ntop \
@@ -12401,6 +12674,7 @@ for ac_func in \
12401 fchmod \ 12674 fchmod \
12402 fchown \ 12675 fchown \
12403 freeaddrinfo \ 12676 freeaddrinfo \
12677 fstatvfs \
12404 futimes \ 12678 futimes \
12405 getaddrinfo \ 12679 getaddrinfo \
12406 getcwd \ 12680 getcwd \
@@ -12452,6 +12726,8 @@ for ac_func in \
12452 sigvec \ 12726 sigvec \
12453 snprintf \ 12727 snprintf \
12454 socketpair \ 12728 socketpair \
12729 statfs \
12730 statvfs \
12455 strdup \ 12731 strdup \
12456 strerror \ 12732 strerror \
12457 strlcat \ 12733 strlcat \
@@ -16619,6 +16895,12 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
16619#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 16895#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
16620_ACEOF 16896_ACEOF
16621 SSHDLIBS="$SSHDLIBS -liaf" 16897 SSHDLIBS="$SSHDLIBS -liaf"
16898
16899cat >>confdefs.h <<\_ACEOF
16900#define HAVE_LIBIAF 1
16901_ACEOF
16902
16903
16622fi 16904fi
16623done 16905done
16624 16906
@@ -21400,6 +21682,153 @@ _ACEOF
21400 21682
21401fi 21683fi
21402 21684
21685{ echo "$as_me:$LINENO: checking for fsblkcnt_t" >&5
21686echo $ECHO_N "checking for fsblkcnt_t... $ECHO_C" >&6; }
21687if test "${ac_cv_type_fsblkcnt_t+set}" = set; then
21688 echo $ECHO_N "(cached) $ECHO_C" >&6
21689else
21690 cat >conftest.$ac_ext <<_ACEOF
21691/* confdefs.h. */
21692_ACEOF
21693cat confdefs.h >>conftest.$ac_ext
21694cat >>conftest.$ac_ext <<_ACEOF
21695/* end confdefs.h. */
21696
21697#include <sys/types.h>
21698#ifdef HAVE_SYS_BITYPES_H
21699#include <sys/bitypes.h>
21700#endif
21701#ifdef HAVE_SYS_STATFS_H
21702#include <sys/statfs.h>
21703#endif
21704#ifdef HAVE_SYS_STATVFS_H
21705#include <sys/statvfs.h>
21706#endif
21707
21708
21709typedef fsblkcnt_t ac__type_new_;
21710int
21711main ()
21712{
21713if ((ac__type_new_ *) 0)
21714 return 0;
21715if (sizeof (ac__type_new_))
21716 return 0;
21717 ;
21718 return 0;
21719}
21720_ACEOF
21721rm -f conftest.$ac_objext
21722if { (ac_try="$ac_compile"
21723case "(($ac_try" in
21724 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
21725 *) ac_try_echo=$ac_try;;
21726esac
21727eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
21728 (eval "$ac_compile") 2>conftest.er1
21729 ac_status=$?
21730 grep -v '^ *+' conftest.er1 >conftest.err
21731 rm -f conftest.er1
21732 cat conftest.err >&5
21733 echo "$as_me:$LINENO: \$? = $ac_status" >&5
21734 (exit $ac_status); } && {
21735 test -z "$ac_c_werror_flag" ||
21736 test ! -s conftest.err
21737 } && test -s conftest.$ac_objext; then
21738 ac_cv_type_fsblkcnt_t=yes
21739else
21740 echo "$as_me: failed program was:" >&5
21741sed 's/^/| /' conftest.$ac_ext >&5
21742
21743 ac_cv_type_fsblkcnt_t=no
21744fi
21745
21746rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
21747fi
21748{ echo "$as_me:$LINENO: result: $ac_cv_type_fsblkcnt_t" >&5
21749echo "${ECHO_T}$ac_cv_type_fsblkcnt_t" >&6; }
21750if test $ac_cv_type_fsblkcnt_t = yes; then
21751
21752cat >>confdefs.h <<_ACEOF
21753#define HAVE_FSBLKCNT_T 1
21754_ACEOF
21755
21756
21757fi
21758{ echo "$as_me:$LINENO: checking for fsfilcnt_t" >&5
21759echo $ECHO_N "checking for fsfilcnt_t... $ECHO_C" >&6; }
21760if test "${ac_cv_type_fsfilcnt_t+set}" = set; then
21761 echo $ECHO_N "(cached) $ECHO_C" >&6
21762else
21763 cat >conftest.$ac_ext <<_ACEOF
21764/* confdefs.h. */
21765_ACEOF
21766cat confdefs.h >>conftest.$ac_ext
21767cat >>conftest.$ac_ext <<_ACEOF
21768/* end confdefs.h. */
21769
21770#include <sys/types.h>
21771#ifdef HAVE_SYS_BITYPES_H
21772#include <sys/bitypes.h>
21773#endif
21774#ifdef HAVE_SYS_STATFS_H
21775#include <sys/statfs.h>
21776#endif
21777#ifdef HAVE_SYS_STATVFS_H
21778#include <sys/statvfs.h>
21779#endif
21780
21781
21782typedef fsfilcnt_t ac__type_new_;
21783int
21784main ()
21785{
21786if ((ac__type_new_ *) 0)
21787 return 0;
21788if (sizeof (ac__type_new_))
21789 return 0;
21790 ;
21791 return 0;
21792}
21793_ACEOF
21794rm -f conftest.$ac_objext
21795if { (ac_try="$ac_compile"
21796case "(($ac_try" in
21797 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
21798 *) ac_try_echo=$ac_try;;
21799esac
21800eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
21801 (eval "$ac_compile") 2>conftest.er1
21802 ac_status=$?
21803 grep -v '^ *+' conftest.er1 >conftest.err
21804 rm -f conftest.er1
21805 cat conftest.err >&5
21806 echo "$as_me:$LINENO: \$? = $ac_status" >&5
21807 (exit $ac_status); } && {
21808 test -z "$ac_c_werror_flag" ||
21809 test ! -s conftest.err
21810 } && test -s conftest.$ac_objext; then
21811 ac_cv_type_fsfilcnt_t=yes
21812else
21813 echo "$as_me: failed program was:" >&5
21814sed 's/^/| /' conftest.$ac_ext >&5
21815
21816 ac_cv_type_fsfilcnt_t=no
21817fi
21818
21819rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
21820fi
21821{ echo "$as_me:$LINENO: result: $ac_cv_type_fsfilcnt_t" >&5
21822echo "${ECHO_T}$ac_cv_type_fsfilcnt_t" >&6; }
21823if test $ac_cv_type_fsfilcnt_t = yes; then
21824
21825cat >>confdefs.h <<_ACEOF
21826#define HAVE_FSFILCNT_T 1
21827_ACEOF
21828
21829
21830fi
21831
21403 21832
21404{ echo "$as_me:$LINENO: checking for in_addr_t" >&5 21833{ echo "$as_me:$LINENO: checking for in_addr_t" >&5
21405echo $ECHO_N "checking for in_addr_t... $ECHO_C" >&6; } 21834echo $ECHO_N "checking for in_addr_t... $ECHO_C" >&6; }
@@ -23707,6 +24136,60 @@ _ACEOF
23707 24136
23708fi 24137fi
23709 24138
24139{ echo "$as_me:$LINENO: checking if f_fsid has val members" >&5
24140echo $ECHO_N "checking if f_fsid has val members... $ECHO_C" >&6; }
24141cat >conftest.$ac_ext <<_ACEOF
24142/* confdefs.h. */
24143_ACEOF
24144cat confdefs.h >>conftest.$ac_ext
24145cat >>conftest.$ac_ext <<_ACEOF
24146/* end confdefs.h. */
24147
24148#include <sys/types.h>
24149#include <sys/statvfs.h>
24150int
24151main ()
24152{
24153struct fsid_t t; t.val[0] = 0;
24154 ;
24155 return 0;
24156}
24157_ACEOF
24158rm -f conftest.$ac_objext
24159if { (ac_try="$ac_compile"
24160case "(($ac_try" in
24161 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
24162 *) ac_try_echo=$ac_try;;
24163esac
24164eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
24165 (eval "$ac_compile") 2>conftest.er1
24166 ac_status=$?
24167 grep -v '^ *+' conftest.er1 >conftest.err
24168 rm -f conftest.er1
24169 cat conftest.err >&5
24170 echo "$as_me:$LINENO: \$? = $ac_status" >&5
24171 (exit $ac_status); } && {
24172 test -z "$ac_c_werror_flag" ||
24173 test ! -s conftest.err
24174 } && test -s conftest.$ac_objext; then
24175 { echo "$as_me:$LINENO: result: yes" >&5
24176echo "${ECHO_T}yes" >&6; }
24177
24178cat >>confdefs.h <<\_ACEOF
24179#define FSID_HAS_VAL 1
24180_ACEOF
24181
24182else
24183 echo "$as_me: failed program was:" >&5
24184sed 's/^/| /' conftest.$ac_ext >&5
24185
24186 { echo "$as_me:$LINENO: result: no" >&5
24187echo "${ECHO_T}no" >&6; }
24188
24189fi
24190
24191rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
24192
23710{ echo "$as_me:$LINENO: checking for msg_control field in struct msghdr" >&5 24193{ echo "$as_me:$LINENO: checking for msg_control field in struct msghdr" >&5
23711echo $ECHO_N "checking for msg_control field in struct msghdr... $ECHO_C" >&6; } 24194echo $ECHO_N "checking for msg_control field in struct msghdr... $ECHO_C" >&6; }
23712if test "${ac_cv_have_control_in_msghdr+set}" = set; then 24195if test "${ac_cv_have_control_in_msghdr+set}" = set; then
@@ -25985,13 +26468,13 @@ if test "$ac_res" != no; then
25985fi 26468fi
25986 26469
25987 26470
25988 { echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgssapi" >&5 26471 { echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgssapi_krb5" >&5
25989echo $ECHO_N "checking for gss_init_sec_context in -lgssapi... $ECHO_C" >&6; } 26472echo $ECHO_N "checking for gss_init_sec_context in -lgssapi_krb5... $ECHO_C" >&6; }
25990if test "${ac_cv_lib_gssapi_gss_init_sec_context+set}" = set; then 26473if test "${ac_cv_lib_gssapi_krb5_gss_init_sec_context+set}" = set; then
25991 echo $ECHO_N "(cached) $ECHO_C" >&6 26474 echo $ECHO_N "(cached) $ECHO_C" >&6
25992else 26475else
25993 ac_check_lib_save_LIBS=$LIBS 26476 ac_check_lib_save_LIBS=$LIBS
25994LIBS="-lgssapi $K5LIBS $LIBS" 26477LIBS="-lgssapi_krb5 $K5LIBS $LIBS"
25995cat >conftest.$ac_ext <<_ACEOF 26478cat >conftest.$ac_ext <<_ACEOF
25996/* confdefs.h. */ 26479/* confdefs.h. */
25997_ACEOF 26480_ACEOF
@@ -26032,34 +26515,34 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
26032 test ! -s conftest.err 26515 test ! -s conftest.err
26033 } && test -s conftest$ac_exeext && 26516 } && test -s conftest$ac_exeext &&
26034 $as_test_x conftest$ac_exeext; then 26517 $as_test_x conftest$ac_exeext; then
26035 ac_cv_lib_gssapi_gss_init_sec_context=yes 26518 ac_cv_lib_gssapi_krb5_gss_init_sec_context=yes
26036else 26519else
26037 echo "$as_me: failed program was:" >&5 26520 echo "$as_me: failed program was:" >&5
26038sed 's/^/| /' conftest.$ac_ext >&5 26521sed 's/^/| /' conftest.$ac_ext >&5
26039 26522
26040 ac_cv_lib_gssapi_gss_init_sec_context=no 26523 ac_cv_lib_gssapi_krb5_gss_init_sec_context=no
26041fi 26524fi
26042 26525
26043rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ 26526rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
26044 conftest$ac_exeext conftest.$ac_ext 26527 conftest$ac_exeext conftest.$ac_ext
26045LIBS=$ac_check_lib_save_LIBS 26528LIBS=$ac_check_lib_save_LIBS
26046fi 26529fi
26047{ echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_gss_init_sec_context" >&5 26530{ echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&5
26048echo "${ECHO_T}$ac_cv_lib_gssapi_gss_init_sec_context" >&6; } 26531echo "${ECHO_T}$ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&6; }
26049if test $ac_cv_lib_gssapi_gss_init_sec_context = yes; then 26532if test $ac_cv_lib_gssapi_krb5_gss_init_sec_context = yes; then
26050 cat >>confdefs.h <<\_ACEOF 26533 cat >>confdefs.h <<\_ACEOF
26051#define GSSAPI 1 26534#define GSSAPI 1
26052_ACEOF 26535_ACEOF
26053 26536
26054 K5LIBS="-lgssapi $K5LIBS" 26537 K5LIBS="-lgssapi_krb5 $K5LIBS"
26055else 26538else
26056 { echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgssapi_krb5" >&5 26539 { echo "$as_me:$LINENO: checking for gss_init_sec_context in -lgssapi" >&5
26057echo $ECHO_N "checking for gss_init_sec_context in -lgssapi_krb5... $ECHO_C" >&6; } 26540echo $ECHO_N "checking for gss_init_sec_context in -lgssapi... $ECHO_C" >&6; }
26058if test "${ac_cv_lib_gssapi_krb5_gss_init_sec_context+set}" = set; then 26541if test "${ac_cv_lib_gssapi_gss_init_sec_context+set}" = set; then
26059 echo $ECHO_N "(cached) $ECHO_C" >&6 26542 echo $ECHO_N "(cached) $ECHO_C" >&6
26060else 26543else
26061 ac_check_lib_save_LIBS=$LIBS 26544 ac_check_lib_save_LIBS=$LIBS
26062LIBS="-lgssapi_krb5 $K5LIBS $LIBS" 26545LIBS="-lgssapi $K5LIBS $LIBS"
26063cat >conftest.$ac_ext <<_ACEOF 26546cat >conftest.$ac_ext <<_ACEOF
26064/* confdefs.h. */ 26547/* confdefs.h. */
26065_ACEOF 26548_ACEOF
@@ -26100,26 +26583,26 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
26100 test ! -s conftest.err 26583 test ! -s conftest.err
26101 } && test -s conftest$ac_exeext && 26584 } && test -s conftest$ac_exeext &&
26102 $as_test_x conftest$ac_exeext; then 26585 $as_test_x conftest$ac_exeext; then
26103 ac_cv_lib_gssapi_krb5_gss_init_sec_context=yes 26586 ac_cv_lib_gssapi_gss_init_sec_context=yes
26104else 26587else
26105 echo "$as_me: failed program was:" >&5 26588 echo "$as_me: failed program was:" >&5
26106sed 's/^/| /' conftest.$ac_ext >&5 26589sed 's/^/| /' conftest.$ac_ext >&5
26107 26590
26108 ac_cv_lib_gssapi_krb5_gss_init_sec_context=no 26591 ac_cv_lib_gssapi_gss_init_sec_context=no
26109fi 26592fi
26110 26593
26111rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ 26594rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
26112 conftest$ac_exeext conftest.$ac_ext 26595 conftest$ac_exeext conftest.$ac_ext
26113LIBS=$ac_check_lib_save_LIBS 26596LIBS=$ac_check_lib_save_LIBS
26114fi 26597fi
26115{ echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&5 26598{ echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_gss_init_sec_context" >&5
26116echo "${ECHO_T}$ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&6; } 26599echo "${ECHO_T}$ac_cv_lib_gssapi_gss_init_sec_context" >&6; }
26117if test $ac_cv_lib_gssapi_krb5_gss_init_sec_context = yes; then 26600if test $ac_cv_lib_gssapi_gss_init_sec_context = yes; then
26118 cat >>confdefs.h <<\_ACEOF 26601 cat >>confdefs.h <<\_ACEOF
26119#define GSSAPI 1 26602#define GSSAPI 1
26120_ACEOF 26603_ACEOF
26121 26604
26122 K5LIBS="-lgssapi_krb5 $K5LIBS" 26605 K5LIBS="-lgssapi $K5LIBS"
26123else 26606else
26124 { echo "$as_me:$LINENO: WARNING: Cannot find any suitable gss-api library - build may fail" >&5 26607 { echo "$as_me:$LINENO: WARNING: Cannot find any suitable gss-api library - build may fail" >&5
26125echo "$as_me: WARNING: Cannot find any suitable gss-api library - build may fail" >&2;} 26608echo "$as_me: WARNING: Cannot find any suitable gss-api library - build may fail" >&2;}
@@ -28389,6 +28872,15 @@ fi
28389 28872
28390CFLAGS="$CFLAGS $werror_flags" 28873CFLAGS="$CFLAGS $werror_flags"
28391 28874
28875if grep "#define BROKEN_GETADDRINFO 1" confdefs.h >/dev/null || \
28876 test "x$ac_cv_func_getaddrinfo" != "xyes" ; then
28877 TEST_SSH_IPV6=no
28878
28879else
28880 TEST_SSH_IPV6=yes
28881
28882fi
28883
28392 28884
28393ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile scard/Makefile ssh_prng_cmds survey.sh" 28885ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile scard/Makefile ssh_prng_cmds survey.sh"
28394 28886
@@ -29164,11 +29656,12 @@ MANTYPE!$MANTYPE$ac_delim
29164mansubdir!$mansubdir$ac_delim 29656mansubdir!$mansubdir$ac_delim
29165user_path!$user_path$ac_delim 29657user_path!$user_path$ac_delim
29166piddir!$piddir$ac_delim 29658piddir!$piddir$ac_delim
29659TEST_SSH_IPV6!$TEST_SSH_IPV6$ac_delim
29167LIBOBJS!$LIBOBJS$ac_delim 29660LIBOBJS!$LIBOBJS$ac_delim
29168LTLIBOBJS!$LTLIBOBJS$ac_delim 29661LTLIBOBJS!$LTLIBOBJS$ac_delim
29169_ACEOF 29662_ACEOF
29170 29663
29171 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 12; then 29664 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 13; then
29172 break 29665 break
29173 elif $ac_last_try; then 29666 elif $ac_last_try; then
29174 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 29667 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.ac b/configure.ac
index f1052b079..fcf7e416b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
1# $Id: configure.ac,v 1.383 2007/08/10 04:36:12 dtucker Exp $ 1# $Id: configure.ac,v 1.409 2008/07/09 11:07:19 djm 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.383 $) 18AC_REVISION($Revision: 1.409 $)
19AC_CONFIG_SRCDIR([ssh.c]) 19AC_CONFIG_SRCDIR([ssh.c])
20 20
21AC_CONFIG_HEADER(config.h) 21AC_CONFIG_HEADER(config.h)
@@ -90,6 +90,13 @@ AC_C_INLINE
90 90
91AC_CHECK_DECL(LLONG_MAX, have_llong_max=1, , [#include <limits.h>]) 91AC_CHECK_DECL(LLONG_MAX, have_llong_max=1, , [#include <limits.h>])
92 92
93use_stack_protector=1
94AC_ARG_WITH(stackprotect,
95 [ --without-stackprotect Don't use compiler's stack protection], [
96 if test "x$withval" = "xno"; then
97 use_stack_protector=0
98 fi ])
99
93if test "$GCC" = "yes" || test "$GCC" = "egcs"; then 100if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
94 CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized" 101 CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized"
95 GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` 102 GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
@@ -100,11 +107,61 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
100 no_attrib_nonnull=1 107 no_attrib_nonnull=1
101 ;; 108 ;;
102 2.*) no_attrib_nonnull=1 ;; 109 2.*) no_attrib_nonnull=1 ;;
103 3.*) CFLAGS="$CFLAGS -Wsign-compare" ;; 110 3.*) CFLAGS="$CFLAGS -Wsign-compare -Wformat-security" ;;
104 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign" ;; 111 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign -Wformat-security" ;;
105 *) ;; 112 *) ;;
106 esac 113 esac
107 114
115 AC_MSG_CHECKING(if $CC accepts -fno-builtin-memset)
116 saved_CFLAGS="$CFLAGS"
117 CFLAGS="$CFLAGS -fno-builtin-memset"
118 AC_LINK_IFELSE( [AC_LANG_SOURCE([[
119#include <string.h>
120int main(void){char b[10]; memset(b, 0, sizeof(b));}
121 ]])],
122 [ AC_MSG_RESULT(yes) ],
123 [ AC_MSG_RESULT(no)
124 CFLAGS="$saved_CFLAGS" ]
125)
126
127 # -fstack-protector-all doesn't always work for some GCC versions
128 # and/or platforms, so we test if we can. If it's not supported
129 # on a give platform gcc will emit a warning so we use -Werror.
130 if test "x$use_stack_protector" = "x1"; then
131 for t in -fstack-protector-all -fstack-protector; do
132 AC_MSG_CHECKING(if $CC supports $t)
133 saved_CFLAGS="$CFLAGS"
134 saved_LDFLAGS="$LDFLAGS"
135 CFLAGS="$CFLAGS $t -Werror"
136 LDFLAGS="$LDFLAGS $t -Werror"
137 AC_LINK_IFELSE(
138 [AC_LANG_SOURCE([
139#include <stdlib.h>
140int main(void){return 0;}
141 ])],
142 [ AC_MSG_RESULT(yes)
143 CFLAGS="$saved_CFLAGS $t"
144 LDFLAGS="$saved_LDFLAGS $t"
145 AC_MSG_CHECKING(if $t works)
146 AC_RUN_IFELSE(
147 [AC_LANG_SOURCE([
148#include <stdlib.h>
149int main(void){exit(0);}
150 ])],
151 [ AC_MSG_RESULT(yes)
152 break ],
153 [ AC_MSG_RESULT(no) ],
154 [ AC_MSG_WARN([cross compiling: cannot test])
155 break ]
156 )
157 ],
158 [ AC_MSG_RESULT(no) ]
159 )
160 CFLAGS="$saved_CFLAGS"
161 LDFLAGS="$saved_LDFLAGS"
162 done
163 fi
164
108 if test -z "$have_llong_max"; then 165 if test -z "$have_llong_max"; then
109 # retry LLONG_MAX with -std=gnu99, needed on some Linuxes 166 # retry LLONG_MAX with -std=gnu99, needed on some Linuxes
110 unset ac_cv_have_decl_LLONG_MAX 167 unset ac_cv_have_decl_LLONG_MAX
@@ -222,7 +279,9 @@ AC_CHECK_HEADERS( \
222 sys/cdefs.h \ 279 sys/cdefs.h \
223 sys/dir.h \ 280 sys/dir.h \
224 sys/mman.h \ 281 sys/mman.h \
282 sys/mount.h \
225 sys/ndir.h \ 283 sys/ndir.h \
284 sys/poll.h \
226 sys/prctl.h \ 285 sys/prctl.h \
227 sys/pstat.h \ 286 sys/pstat.h \
228 sys/select.h \ 287 sys/select.h \
@@ -230,6 +289,7 @@ AC_CHECK_HEADERS( \
230 sys/stream.h \ 289 sys/stream.h \
231 sys/stropts.h \ 290 sys/stropts.h \
232 sys/strtio.h \ 291 sys/strtio.h \
292 sys/statvfs.h \
233 sys/sysmacros.h \ 293 sys/sysmacros.h \
234 sys/time.h \ 294 sys/time.h \
235 sys/timers.h \ 295 sys/timers.h \
@@ -343,7 +403,7 @@ int main(void) { exit(0); }
343 [], 403 [],
344 [#include <usersec.h>] 404 [#include <usersec.h>]
345 ) 405 )
346 AC_CHECK_FUNCS(setauthdb) 406 AC_CHECK_FUNCS(getgrset setauthdb)
347 AC_CHECK_DECL(F_CLOSEM, 407 AC_CHECK_DECL(F_CLOSEM,
348 AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]), 408 AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]),
349 [], 409 [],
@@ -405,6 +465,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
405 AC_DEFINE(SETEUID_BREAKS_SETUID) 465 AC_DEFINE(SETEUID_BREAKS_SETUID)
406 AC_DEFINE(BROKEN_SETREUID) 466 AC_DEFINE(BROKEN_SETREUID)
407 AC_DEFINE(BROKEN_SETREGID) 467 AC_DEFINE(BROKEN_SETREGID)
468 AC_DEFINE(BROKEN_GLOB, 1, [OS X glob does not do what we expect])
408 AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1, 469 AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1,
409 [Define if your resolver libs need this for getrrsetbyname]) 470 [Define if your resolver libs need this for getrrsetbyname])
410 AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way]) 471 AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
@@ -412,6 +473,11 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
412 [Use tunnel device compatibility to OpenBSD]) 473 [Use tunnel device compatibility to OpenBSD])
413 AC_DEFINE(SSH_TUN_PREPEND_AF, 1, 474 AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
414 [Prepend the address family to IP tunnel traffic]) 475 [Prepend the address family to IP tunnel traffic])
476 m4_pattern_allow(AU_IPv)
477 AC_CHECK_DECL(AU_IPv4, [],
478 AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records])
479 [#include <bsm/audit.h>]
480 )
415 ;; 481 ;;
416*-*-dragonfly*) 482*-*-dragonfly*)
417 SSHDLIBS="$SSHDLIBS -lcrypt" 483 SSHDLIBS="$SSHDLIBS -lcrypt"
@@ -499,7 +565,6 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
499 no_dev_ptmx=1 565 no_dev_ptmx=1
500 check_for_libcrypt_later=1 566 check_for_libcrypt_later=1
501 check_for_openpty_ctty_bug=1 567 check_for_openpty_ctty_bug=1
502 AC_DEFINE(DONT_TRY_OTHER_AF, 1, [Workaround more Linux IPv6 quirks])
503 AC_DEFINE(PAM_TTY_KLUDGE, 1, 568 AC_DEFINE(PAM_TTY_KLUDGE, 1,
504 [Work around problematic Linux PAM modules handling of PAM_TTY]) 569 [Work around problematic Linux PAM modules handling of PAM_TTY])
505 AC_DEFINE(LOCKED_PASSWD_PREFIX, "!", 570 AC_DEFINE(LOCKED_PASSWD_PREFIX, "!",
@@ -549,6 +614,7 @@ mips-sony-bsd|mips-sony-newsos4)
549 AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way]) 614 AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
550 AC_CHECK_HEADER([net/if_tap.h], , 615 AC_CHECK_HEADER([net/if_tap.h], ,
551 AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support])) 616 AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support]))
617 AC_DEFINE(BROKEN_GLOB, 1, [FreeBSD glob does not do what we need])
552 ;; 618 ;;
553*-*-bsdi*) 619*-*-bsdi*)
554 AC_DEFINE(SETEUID_BREAKS_SETUID) 620 AC_DEFINE(SETEUID_BREAKS_SETUID)
@@ -775,6 +841,7 @@ mips-sony-bsd|mips-sony-newsos4)
775 AC_DEFINE(SETEUID_BREAKS_SETUID) 841 AC_DEFINE(SETEUID_BREAKS_SETUID)
776 AC_DEFINE(BROKEN_SETREUID) 842 AC_DEFINE(BROKEN_SETREUID)
777 AC_DEFINE(BROKEN_SETREGID) 843 AC_DEFINE(BROKEN_SETREGID)
844 AC_DEFINE(BROKEN_READV_COMPARISON, 1, [Can't do comparisons on readv])
778 ;; 845 ;;
779 846
780*-*-nto-qnx*) 847*-*-nto-qnx*)
@@ -785,6 +852,7 @@ mips-sony-bsd|mips-sony-newsos4)
785 AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems]) 852 AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems])
786 AC_DEFINE(DISABLE_LASTLOG) 853 AC_DEFINE(DISABLE_LASTLOG)
787 AC_DEFINE(SSHD_ACQUIRES_CTTY) 854 AC_DEFINE(SSHD_ACQUIRES_CTTY)
855 AC_DEFINE(BROKEN_SHADOW_EXPIRE, 1, [QNX shadow support is broken])
788 enable_etc_default_login=no # has incompatible /etc/default/login 856 enable_etc_default_login=no # has incompatible /etc/default/login
789 case "$host" in 857 case "$host" in
790 *-*-nto-qnx6*) 858 *-*-nto-qnx6*)
@@ -980,7 +1048,7 @@ dnl Checks for libutil functions
980AC_CHECK_HEADERS(libutil.h) 1048AC_CHECK_HEADERS(libutil.h)
981AC_SEARCH_LIBS(login, util bsd, [AC_DEFINE(HAVE_LOGIN, 1, 1049AC_SEARCH_LIBS(login, util bsd, [AC_DEFINE(HAVE_LOGIN, 1,
982 [Define if your libraries define login()])]) 1050 [Define if your libraries define login()])])
983AC_CHECK_FUNCS(logout updwtmp logwtmp) 1051AC_CHECK_FUNCS(fmt_scaled logout updwtmp logwtmp)
984 1052
985AC_FUNC_STRFTIME 1053AC_FUNC_STRFTIME
986 1054
@@ -1214,7 +1282,7 @@ AC_ARG_WITH(audit,
1214 AC_CHECK_FUNCS(getaudit, [], 1282 AC_CHECK_FUNCS(getaudit, [],
1215 [AC_MSG_ERROR(BSM enabled and required function not found)]) 1283 [AC_MSG_ERROR(BSM enabled and required function not found)])
1216 # These are optional 1284 # These are optional
1217 AC_CHECK_FUNCS(getaudit_addr) 1285 AC_CHECK_FUNCS(getaudit_addr aug_get_machine)
1218 AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module]) 1286 AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module])
1219 ;; 1287 ;;
1220 debug) 1288 debug)
@@ -1234,6 +1302,8 @@ AC_ARG_WITH(audit,
1234dnl Checks for library functions. Please keep in alphabetical order 1302dnl Checks for library functions. Please keep in alphabetical order
1235AC_CHECK_FUNCS( \ 1303AC_CHECK_FUNCS( \
1236 arc4random \ 1304 arc4random \
1305 arc4random_buf \
1306 arc4random_uniform \
1237 asprintf \ 1307 asprintf \
1238 b64_ntop \ 1308 b64_ntop \
1239 __b64_ntop \ 1309 __b64_ntop \
@@ -1247,6 +1317,7 @@ AC_CHECK_FUNCS( \
1247 fchmod \ 1317 fchmod \
1248 fchown \ 1318 fchown \
1249 freeaddrinfo \ 1319 freeaddrinfo \
1320 fstatvfs \
1250 futimes \ 1321 futimes \
1251 getaddrinfo \ 1322 getaddrinfo \
1252 getcwd \ 1323 getcwd \
@@ -1298,6 +1369,8 @@ AC_CHECK_FUNCS( \
1298 sigvec \ 1369 sigvec \
1299 snprintf \ 1370 snprintf \
1300 socketpair \ 1371 socketpair \
1372 statfs \
1373 statvfs \
1301 strdup \ 1374 strdup \
1302 strerror \ 1375 strerror \
1303 strlcat \ 1376 strlcat \
@@ -2004,7 +2077,10 @@ AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
2004saved_LIBS="$LIBS" 2077saved_LIBS="$LIBS"
2005AC_CHECK_LIB(iaf, ia_openinfo, [ 2078AC_CHECK_LIB(iaf, ia_openinfo, [
2006 LIBS="$LIBS -liaf" 2079 LIBS="$LIBS -liaf"
2007 AC_CHECK_FUNCS(set_id, [SSHDLIBS="$SSHDLIBS -liaf"]) 2080 AC_CHECK_FUNCS(set_id, [SSHDLIBS="$SSHDLIBS -liaf"
2081 AC_DEFINE(HAVE_LIBIAF, 1,
2082 [Define if system has libiaf that supports set_id])
2083 ])
2008]) 2084])
2009LIBS="$saved_LIBS" 2085LIBS="$saved_LIBS"
2010 2086
@@ -2588,6 +2664,18 @@ fi
2588TYPE_SOCKLEN_T 2664TYPE_SOCKLEN_T
2589 2665
2590AC_CHECK_TYPES(sig_atomic_t,,,[#include <signal.h>]) 2666AC_CHECK_TYPES(sig_atomic_t,,,[#include <signal.h>])
2667AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t],,,[
2668#include <sys/types.h>
2669#ifdef HAVE_SYS_BITYPES_H
2670#include <sys/bitypes.h>
2671#endif
2672#ifdef HAVE_SYS_STATFS_H
2673#include <sys/statfs.h>
2674#endif
2675#ifdef HAVE_SYS_STATVFS_H
2676#include <sys/statvfs.h>
2677#endif
2678])
2591 2679
2592AC_CHECK_TYPES(in_addr_t,,, 2680AC_CHECK_TYPES(in_addr_t,,,
2593[#include <sys/types.h> 2681[#include <sys/types.h>
@@ -2950,6 +3038,16 @@ if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then
2950 file descriptor passing]) 3038 file descriptor passing])
2951fi 3039fi
2952 3040
3041AC_MSG_CHECKING(if f_fsid has val members)
3042AC_TRY_COMPILE([
3043#include <sys/types.h>
3044#include <sys/statvfs.h>],
3045[struct fsid_t t; t.val[0] = 0;],
3046 [ AC_MSG_RESULT(yes)
3047 AC_DEFINE(FSID_HAS_VAL, 1, f_fsid has members) ],
3048 [ AC_MSG_RESULT(no) ]
3049)
3050
2953AC_CACHE_CHECK([for msg_control field in struct msghdr], 3051AC_CACHE_CHECK([for msg_control field in struct msghdr],
2954 ac_cv_have_control_in_msghdr, [ 3052 ac_cv_have_control_in_msghdr, [
2955 AC_COMPILE_IFELSE( 3053 AC_COMPILE_IFELSE(
@@ -3201,7 +3299,7 @@ int main() { return 0; }
3201SELINUX_MSG="no" 3299SELINUX_MSG="no"
3202LIBSELINUX="" 3300LIBSELINUX=""
3203AC_ARG_WITH(selinux, 3301AC_ARG_WITH(selinux,
3204 [ --with-selinux Enable SELinux support], 3302 [ --with-selinux Enable SELinux support],
3205 [ if test "x$withval" != "xno" ; then 3303 [ if test "x$withval" != "xno" ; then
3206 save_LIBS="$LIBS" 3304 save_LIBS="$LIBS"
3207 AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.]) 3305 AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.])
@@ -3278,12 +3376,12 @@ AC_ARG_WITH(kerberos5,
3278 ) 3376 )
3279 AC_SEARCH_LIBS(dn_expand, resolv) 3377 AC_SEARCH_LIBS(dn_expand, resolv)
3280 3378
3281 AC_CHECK_LIB(gssapi,gss_init_sec_context, 3379 AC_CHECK_LIB(gssapi_krb5, gss_init_sec_context,
3282 [ AC_DEFINE(GSSAPI) 3380 [ AC_DEFINE(GSSAPI)
3283 K5LIBS="-lgssapi $K5LIBS" ], 3381 K5LIBS="-lgssapi_krb5 $K5LIBS" ],
3284 [ AC_CHECK_LIB(gssapi_krb5,gss_init_sec_context, 3382 [ AC_CHECK_LIB(gssapi, gss_init_sec_context,
3285 [ AC_DEFINE(GSSAPI) 3383 [ AC_DEFINE(GSSAPI)
3286 K5LIBS="-lgssapi_krb5 $K5LIBS" ], 3384 K5LIBS="-lgssapi $K5LIBS" ],
3287 AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]), 3385 AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]),
3288 $K5LIBS) 3386 $K5LIBS)
3289 ], 3387 ],
@@ -3982,6 +4080,13 @@ dnl Adding -Werror to CFLAGS early prevents configure tests from running.
3982dnl Add now. 4080dnl Add now.
3983CFLAGS="$CFLAGS $werror_flags" 4081CFLAGS="$CFLAGS $werror_flags"
3984 4082
4083if grep "#define BROKEN_GETADDRINFO 1" confdefs.h >/dev/null || \
4084 test "x$ac_cv_func_getaddrinfo" != "xyes" ; then
4085 AC_SUBST(TEST_SSH_IPV6, no)
4086else
4087 AC_SUBST(TEST_SSH_IPV6, yes)
4088fi
4089
3985AC_EXEEXT 4090AC_EXEEXT
3986AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ 4091AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
3987 openbsd-compat/Makefile openbsd-compat/regress/Makefile \ 4092 openbsd-compat/Makefile openbsd-compat/regress/Makefile \
diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec
index 9cb5cb464..32d175d4b 100644
--- a/contrib/caldera/openssh.spec
+++ b/contrib/caldera/openssh.spec
@@ -17,11 +17,11 @@
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%if %{use_stable} 19%if %{use_stable}
20 %define version 4.7p1 20 %define version 5.1p1
21 %define cvs %{nil} 21 %define cvs %{nil}
22 %define release 1 22 %define release 1
23%else 23%else
24 %define version 4.1p1 24 %define version 5.1p1
25 %define cvs cvs20050315 25 %define cvs cvs20050315
26 %define release 0r1 26 %define release 0r1
27%endif 27%endif
@@ -342,6 +342,7 @@ fi
342%config %{SVIcdir}/sshd 342%config %{SVIcdir}/sshd
343%{_libexecdir}/sftp-server 343%{_libexecdir}/sftp-server
344%{_sbindir}/sshd 344%{_sbindir}/sshd
345%{_mandir}/man5/moduli.5.gz
345%{_mandir}/man5/sshd_config.5.gz 346%{_mandir}/man5/sshd_config.5.gz
346%{_mandir}/man8/sftp-server.8.gz 347%{_mandir}/man8/sftp-server.8.gz
347%{_mandir}/man8/sshd.8.gz 348%{_mandir}/man8/sshd.8.gz
@@ -357,4 +358,4 @@ fi
357* Mon Jan 01 1998 ... 358* Mon Jan 01 1998 ...
358Template Version: 1.31 359Template Version: 1.31
359 360
360$Id: openssh.spec,v 1.61 2007/08/15 09:22:20 dtucker Exp $ 361$Id: openssh.spec,v 1.65 2008/07/21 08:21:53 djm Exp $
diff --git a/contrib/cygwin/Makefile b/contrib/cygwin/Makefile
index 09e8ea2db..3e2d26404 100644
--- a/contrib/cygwin/Makefile
+++ b/contrib/cygwin/Makefile
@@ -8,6 +8,7 @@ sshdocdir=$(docdir)/openssh
8cygdocdir=$(docdir)/Cygwin 8cygdocdir=$(docdir)/Cygwin
9sysconfdir=/etc 9sysconfdir=/etc
10defaultsdir=$(sysconfdir)/defaults/etc 10defaultsdir=$(sysconfdir)/defaults/etc
11inetdefdir=$(defaultsdir)/inetd.d
11PRIVSEP_PATH=/var/empty 12PRIVSEP_PATH=/var/empty
12INSTALL=/usr/bin/install -c 13INSTALL=/usr/bin/install -c
13 14
@@ -27,6 +28,10 @@ move-config-files: $(DESTDIR)$(sysconfdir)/ssh_config $(DESTDIR)$(sysconfdir)/ss
27remove-empty-dir: 28remove-empty-dir:
28 rm -rf $(DESTDIR)$(PRIVSEP_PATH) 29 rm -rf $(DESTDIR)$(PRIVSEP_PATH)
29 30
31install-inetd-config:
32 $(srcdir)/mkinstalldirs $(DESTDIR)$(inetdefdir)
33 $(INSTALL) -m 644 sshd-inetd $(DESTDIR)$(inetdefdir)/sshd-inetd
34
30install-sshdoc: 35install-sshdoc:
31 $(srcdir)/mkinstalldirs $(DESTDIR)$(sshdocdir) 36 $(srcdir)/mkinstalldirs $(DESTDIR)$(sshdocdir)
32 $(INSTALL) -m 644 $(srcdir)/CREDITS $(DESTDIR)$(sshdocdir)/CREDITS 37 $(INSTALL) -m 644 $(srcdir)/CREDITS $(DESTDIR)$(sshdocdir)/CREDITS
@@ -52,5 +57,5 @@ install-scripts: ssh-host-config ssh-user-config
52 $(INSTALL) -m 755 ssh-host-config $(DESTDIR)$(bindir)/ssh-host-config 57 $(INSTALL) -m 755 ssh-host-config $(DESTDIR)$(bindir)/ssh-host-config
53 $(INSTALL) -m 755 ssh-user-config $(DESTDIR)$(bindir)/ssh-user-config 58 $(INSTALL) -m 755 ssh-user-config $(DESTDIR)$(bindir)/ssh-user-config
54 59
55cygwin-postinstall: move-config-files remove-empty-dir install-doc install-scripts 60cygwin-postinstall: move-config-files remove-empty-dir install-inetd-config install-doc install-scripts
56 @echo "Cygwin specific configuration finished." 61 @echo "Cygwin specific configuration finished."
diff --git a/contrib/cygwin/ssh-host-config b/contrib/cygwin/ssh-host-config
index e2ad69f19..bbb6da4c4 100644
--- a/contrib/cygwin/ssh-host-config
+++ b/contrib/cygwin/ssh-host-config
@@ -4,6 +4,15 @@
4# 4#
5# This file is part of the Cygwin port of OpenSSH. 5# This file is part of the Cygwin port of OpenSSH.
6 6
7# ======================================================================
8# Initialization
9# ======================================================================
10PROGNAME=$(basename $0)
11_tdir=$(dirname $0)
12PROGDIR=$(cd $_tdir && pwd)
13
14CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
15
7# Subdirectory where the new package is being installed 16# Subdirectory where the new package is being installed
8PREFIX=/usr 17PREFIX=/usr
9 18
@@ -11,43 +20,371 @@ PREFIX=/usr
11SYSCONFDIR=/etc 20SYSCONFDIR=/etc
12LOCALSTATEDIR=/var 21LOCALSTATEDIR=/var
13 22
14progname=$0 23source ${CSIH_SCRIPT}
15auto_answer=""
16port_number=22
17 24
25port_number=22
18privsep_configured=no 26privsep_configured=no
19privsep_used=yes 27privsep_used=yes
20sshd_in_passwd=no 28cygwin_value="ntsec"
21sshd_in_sam=no 29password_value=
30
31# ======================================================================
32# Routine: create_host_keys
33# ======================================================================
34create_host_keys() {
35 if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
36 then
37 csih_inform "Generating ${SYSCONFDIR}/ssh_host_key"
38 ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
39 fi
40
41 if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
42 then
43 csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
44 ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
45 fi
46
47 if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
48 then
49 csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
50 ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
51 fi
52} # --- End of create_host_keys --- #
53
54# ======================================================================
55# Routine: update_services_file
56# ======================================================================
57update_services_file() {
58 local _my_etcdir="/ssh-host-config.$$"
59 local _win_etcdir
60 local _services
61 local _spaces
62 local _serv_tmp
63 local _wservices
64
65 if csih_is_nt
66 then
67 _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
68 _services="${_my_etcdir}/services"
69 # On NT, 27 spaces, no space after the hash
70 _spaces=" #"
71 else
72 _win_etcdir="${WINDIR}"
73 _services="${_my_etcdir}/SERVICES"
74 # On 9x, 18 spaces (95 is very touchy), a space after the hash
75 _spaces=" # "
76 fi
77 _serv_tmp="${_my_etcdir}/srv.out.$$"
78
79 mount -t -f "${_win_etcdir}" "${_my_etcdir}"
80
81 # Depends on the above mount
82 _wservices=`cygpath -w "${_services}"`
83
84 # Remove sshd 22/port from services
85 if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
86 then
87 grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
88 if [ -f "${_serv_tmp}" ]
89 then
90 if mv "${_serv_tmp}" "${_services}"
91 then
92 csih_inform "Removing sshd from ${_wservices}"
93 else
94 csih_warning "Removing sshd from ${_wservices} failed!"
95 fi
96 rm -f "${_serv_tmp}"
97 else
98 csih_warning "Removing sshd from ${_wservices} failed!"
99 fi
100 fi
101
102 # Add ssh 22/tcp and ssh 22/udp to services
103 if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
104 then
105 if awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh 22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}"
106 then
107 if mv "${_serv_tmp}" "${_services}"
108 then
109 csih_inform "Added ssh to ${_wservices}"
110 else
111 csih_warning "Adding ssh to ${_wservices} failed!"
112 fi
113 rm -f "${_serv_tmp}"
114 else
115 csih_warning "Adding ssh to ${_wservices} failed!"
116 fi
117 fi
118 umount "${_my_etcdir}"
119} # --- End of update_services_file --- #
120
121# ======================================================================
122# Routine: sshd_privsep
123# MODIFIES: privsep_configured privsep_used
124# ======================================================================
125sshd_privsep() {
126 local sshdconfig_tmp
22 127
23request() 128 if [ "${privsep_configured}" != "yes" ]
24{ 129 then
25 if [ "${auto_answer}" = "yes" ] 130 if csih_is_nt
131 then
132 csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3."
133 csih_inform "However, this requires a non-privileged account called 'sshd'."
134 csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
135 if csih_request "Should privilege separation be used?"
136 then
137 privsep_used=yes
138 if ! csih_create_unprivileged_user sshd
139 then
140 csih_warning "Couldn't create user 'sshd'!"
141 csih_warning "Privilege separation set to 'no' again!"
142 csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
143 privsep_used=no
144 fi
145 else
146 privsep_used=no
147 fi
148 else
149 # On 9x don't use privilege separation. Since security isn't
150 # available it just adds useless additional processes.
151 privsep_used=no
152 fi
153 fi
154
155 # Create default sshd_config from skeleton files in /etc/defaults/etc or
156 # modify to add the missing privsep configuration option
157 if cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
26 then 158 then
27 echo "$1 (yes/no) yes" 159 csih_inform "Updating ${SYSCONFDIR}/sshd_config file"
28 return 0 160 sshdconfig_tmp=${SYSCONFDIR}/sshd_config.$$
29 elif [ "${auto_answer}" = "no" ] 161 sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
162 s/^#Port 22/Port ${port_number}/
163 s/^#StrictModes yes/StrictModes no/" \
164 < ${SYSCONFDIR}/sshd_config \
165 > "${sshdconfig_tmp}"
166 mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config
167 elif [ "${privsep_configured}" != "yes" ]
30 then 168 then
31 echo "$1 (yes/no) no" 169 echo >> ${SYSCONFDIR}/sshd_config
32 return 1 170 echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
33 fi 171 fi
172} # --- End of sshd_privsep --- #
173
174# ======================================================================
175# Routine: update_inetd_conf
176# ======================================================================
177update_inetd_conf() {
178 local _inetcnf="${SYSCONFDIR}/inetd.conf"
179 local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
180 local _inetcnf_dir="${SYSCONFDIR}/inetd.d"
181 local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd"
182 local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$"
183 local _with_comment=1
184
185 if [ -d "${_inetcnf_dir}" ]
186 then
187 # we have inetutils-1.5 inetd.d support
188 if [ -f "${_inetcnf}" ]
189 then
190 grep -q '^[ \t]*ssh' "${_inetcnf}" && _with_comment=0
34 191
35 answer="" 192 # check for sshd OR ssh in top-level inetd.conf file, and remove
36 while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ] 193 # will be replaced by a file in inetd.d/
37 do 194 if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ]
38 echo -n "$1 (yes/no) " 195 then
39 read -e answer 196 grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
40 done 197 if [ -f "${_inetcnf_tmp}" ]
41 if [ "X${answer}" = "Xyes" ] 198 then
199 if mv "${_inetcnf_tmp}" "${_inetcnf}"
200 then
201 csih_inform "Removed ssh[d] from ${_inetcnf}"
202 else
203 csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
204 fi
205 rm -f "${_inetcnf_tmp}"
206 else
207 csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
208 fi
209 fi
210 fi
211
212 csih_install_config "${_sshd_inetd_conf}" "${SYSCONFDIR}/defaults"
213 if cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
214 then
215 if [ "${_with_comment}" -eq 0 ]
216 then
217 sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
218 else
219 sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
220 fi
221 mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
222 csih_inform "Updated ${_sshd_inetd_conf}"
223 fi
224
225 elif [ -f "${_inetcnf}" ]
42 then 226 then
43 return 0 227 grep -q '^[ \t]*sshd' "${_inetcnf}" && _with_comment=0
44 else 228
45 return 1 229 # check for sshd in top-level inetd.conf file, and remove
230 # will be replaced by a file in inetd.d/
231 if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
232 then
233 grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
234 if [ -f "${_inetcnf_tmp}" ]
235 then
236 if mv "${_inetcnf_tmp}" "${_inetcnf}"
237 then
238 csih_inform "Removed sshd from ${_inetcnf}"
239 else
240 csih_warning "Removing sshd from ${_inetcnf} failed!"
241 fi
242 rm -f "${_inetcnf_tmp}"
243 else
244 csih_warning "Removing sshd from ${_inetcnf} failed!"
245 fi
246 fi
247
248 # Add ssh line to inetd.conf
249 if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
250 then
251 if [ "${_with_comment}" -eq 0 ]
252 then
253 echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
254 else
255 echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
256 fi
257 csih_inform "Added ssh to ${_inetcnf}"
258 fi
46 fi 259 fi
47} 260} # --- End of update_inetd_conf --- #
48 261
49# Check options 262# ======================================================================
263# Routine: install_service
264# Install sshd as a service
265# ======================================================================
266install_service() {
267 local run_service_as
268 local password
269
270 if csih_is_nt
271 then
272 if ! cygrunsrv -Q sshd >/dev/null 2>&1
273 then
274 echo
275 echo
276 csih_warning "The following functions require administrator privileges!"
277 echo
278 echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?"
279 if csih_request "(Say \"no\" if it is already installed as a service)"
280 then
281 csih_inform "Note that the CYGWIN variable must contain at least \"ntsec\""
282 csih_inform "for sshd to be able to change user context without password."
283 csih_get_cygenv "${cygwin_value}"
284
285 if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
286 then
287 csih_inform "On Windows Server 2003, Windows Vista, and above, the"
288 csih_inform "SYSTEM account cannot setuid to other users -- a capability"
289 csih_inform "sshd requires. You need to have or to create a privileged"
290 csih_inform "account. This script will help you do so."
291 echo
292 if ! csih_create_privileged_user "${password_value}"
293 then
294 csih_error_recoverable "There was a serious problem creating a privileged user."
295 csih_request "Do you want to proceed anyway?" || exit 1
296 fi
297 fi
298
299 # never returns empty if NT or above
300 run_service_as=$(csih_service_should_run_as)
301
302 if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
303 then
304 password="${csih_PRIVILEGED_PASSWORD}"
305 if [ -z "${password}" ]
306 then
307 csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
308 password="${csih_value}"
309 fi
310 fi
311
312 # at this point, we either have $run_service_as = "system" and $password is empty,
313 # or $run_service_as is some privileged user and (hopefully) $password contains
314 # the correct password. So, from here out, we use '-z "${password}"' to discriminate
315 # the two cases.
316
317 csih_check_user "${run_service_as}"
318
319 if [ -z "${password}" ]
320 then
321 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a "-D" -y tcpip \
322 -e CYGWIN="${csih_cygenv}"
323 then
324 echo
325 csih_inform "The sshd service has been installed under the LocalSystem"
326 csih_inform "account (also known as SYSTEM). To start the service now, call"
327 csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it"
328 csih_inform "will start automatically after the next reboot."
329 fi
330 else
331 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a "-D" -y tcpip \
332 -e CYGWIN="${csih_cygenv}" -u "${run_service_as}" -w "${password}"
333 then
334 echo
335 csih_inform "The sshd service has been installed under the '${run_service_as}'"
336 csih_inform "account. To start the service now, call \`net start sshd' or"
337 csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically"
338 csih_inform "after the next reboot."
339 fi
340 fi
341
342 # now, if successfully installed, set ownership of the affected files
343 if cygrunsrv -Q sshd >/dev/null 2>&1
344 then
345 chown "${run_service_as}" ${SYSCONFDIR}/ssh*
346 chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty
347 chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog
348 if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
349 then
350 chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log
351 fi
352 else
353 csih_warning "Something went wrong installing the sshd service."
354 fi
355 fi # user allowed us to install as service
356 fi # service not yet installed
357 fi # csih_is_nt
358} # --- End of install_service --- #
359
360# ======================================================================
361# Main Entry Point
362# ======================================================================
363
364# Check how the script has been started. If
365# (1) it has been started by giving the full path and
366# that path is /etc/postinstall, OR
367# (2) Otherwise, if the environment variable
368# SSH_HOST_CONFIG_AUTO_ANSWER_NO is set
369# then set auto_answer to "no". This allows automatic
370# creation of the config files in /etc w/o overwriting
371# them if they already exist. In both cases, color
372# escape sequences are suppressed, so as to prevent
373# cluttering setup's logfiles.
374if [ "$PROGDIR" = "/etc/postinstall" ]
375then
376 csih_auto_answer="no"
377 csih_disable_color
378fi
379if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ]
380then
381 csih_auto_answer="no"
382 csih_disable_color
383fi
50 384
385# ======================================================================
386# Parse options
387# ======================================================================
51while : 388while :
52do 389do
53 case $# in 390 case $# in
@@ -62,14 +399,15 @@ do
62 case "${option}" in 399 case "${option}" in
63 -d | --debug ) 400 -d | --debug )
64 set -x 401 set -x
402 csih_trace_on
65 ;; 403 ;;
66 404
67 -y | --yes ) 405 -y | --yes )
68 auto_answer=yes 406 csih_auto_answer=yes
69 ;; 407 ;;
70 408
71 -n | --no ) 409 -n | --no )
72 auto_answer=no 410 csih_auto_answer=no
73 ;; 411 ;;
74 412
75 -c | --cygwin ) 413 -c | --cygwin )
@@ -87,6 +425,10 @@ do
87 shift 425 shift
88 ;; 426 ;;
89 427
428 --privileged )
429 csih_FORCE_PRIVILEGED_USER=yes
430 ;;
431
90 *) 432 *)
91 echo "usage: ${progname} [OPTION]..." 433 echo "usage: ${progname} [OPTION]..."
92 echo 434 echo
@@ -98,7 +440,9 @@ do
98 echo " --no -n Answer all questions with \"no\" automatically." 440 echo " --no -n Answer all questions with \"no\" automatically."
99 echo " --cygwin -c <options> Use \"options\" as value for CYGWIN environment var." 441 echo " --cygwin -c <options> Use \"options\" as value for CYGWIN environment var."
100 echo " --port -p <n> sshd listens on port n." 442 echo " --port -p <n> sshd listens on port n."
101 echo " --pwd -w <passwd> Use \"pwd\" as password for user 'sshd_server'." 443 echo " --pwd -w <passwd> Use \"pwd\" as password for privileged user."
444 echo " --privileged On Windows NT/2k/XP, require privileged user"
445 echo " instead of LocalSystem for sshd service."
102 echo 446 echo
103 exit 1 447 exit 1
104 ;; 448 ;;
@@ -106,73 +450,34 @@ do
106 esac 450 esac
107done 451done
108 452
109# Check if running on NT 453# ======================================================================
110_sys="`uname`" 454# Action!
111_nt=`expr "${_sys}" : "CYGWIN_NT"` 455# ======================================================================
112# If running on NT, check if running under 2003 Server or later
113if [ ${_nt} -gt 0 ]
114then
115 _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
116fi
117 456
118# Check for running ssh/sshd processes first. Refuse to do anything while 457# Check for running ssh/sshd processes first. Refuse to do anything while
119# some ssh processes are still running 458# some ssh processes are still running
120
121if ps -ef | grep -v grep | grep -q ssh 459if ps -ef | grep -v grep | grep -q ssh
122then 460then
123 echo 461 echo
124 echo "There are still ssh processes running. Please shut them down first." 462 csih_error "There are still ssh processes running. Please shut them down first."
125 echo
126 exit 1
127fi 463fi
128 464
129# Check for ${SYSCONFDIR} directory 465# Check for ${SYSCONFDIR} directory
466csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files."
467chmod 775 "${SYSCONFDIR}"
468setfacl -m u:system:rwx "${SYSCONFDIR}"
130 469
131if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ] 470# Check for /var/log directory
132then 471csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory."
133 echo 472chmod 775 "${LOCALSTATEDIR}/log"
134 echo "${SYSCONFDIR} is existant but not a directory." 473setfacl -m u:system:rwx "${LOCALSTATEDIR}/log"
135 echo "Cannot create global configuration files."
136 echo
137 exit 1
138fi
139
140# Create it if necessary
141
142if [ ! -e "${SYSCONFDIR}" ]
143then
144 mkdir "${SYSCONFDIR}"
145 if [ ! -e "${SYSCONFDIR}" ]
146 then
147 echo
148 echo "Creating ${SYSCONFDIR} directory failed"
149 echo
150 exit 1
151 fi
152fi
153
154# Create /var/log and /var/log/lastlog if not already existing
155
156if [ -e ${LOCALSTATEDIR}/log -a ! -d ${LOCALSTATEDIR}/log ]
157then
158 echo
159 echo "${LOCALSTATEDIR}/log is existant but not a directory."
160 echo "Cannot create ssh host configuration."
161 echo
162 exit 1
163fi
164if [ ! -e ${LOCALSTATEDIR}/log ]
165then
166 mkdir -p ${LOCALSTATEDIR}/log
167fi
168 474
475# Create /var/log/lastlog if not already exists
169if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ] 476if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
170then 477then
171 echo 478 echo
172 echo "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." 479 csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \
173 echo "Cannot create ssh host configuration." 480 "Cannot create ssh host configuration."
174 echo
175 exit 1
176fi 481fi
177if [ ! -e ${LOCALSTATEDIR}/log/lastlog ] 482if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
178then 483then
@@ -181,431 +486,44 @@ then
181fi 486fi
182 487
183# Create /var/empty file used as chroot jail for privilege separation 488# Create /var/empty file used as chroot jail for privilege separation
184if [ -f ${LOCALSTATEDIR}/empty ] 489csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create log directory."
185then 490chmod 755 "${LOCALSTATEDIR}/empty"
186 echo "Creating ${LOCALSTATEDIR}/empty failed!" 491setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty"
187else
188 mkdir -p ${LOCALSTATEDIR}/empty
189 if [ ${_nt} -gt 0 ]
190 then
191 chmod 755 ${LOCALSTATEDIR}/empty
192 fi
193fi
194 492
195# First generate host keys if not already existing 493# host keys
494create_host_keys
196 495
197if [ ! -f "${SYSCONFDIR}/ssh_host_key" ] 496# use 'cmp' program to determine if a config file is identical
198then 497# to the default version of that config file
199 echo "Generating ${SYSCONFDIR}/ssh_host_key" 498csih_check_program_or_error cmp diffutils
200 ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
201fi
202 499
203if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
204then
205 echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
206 ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
207fi
208 500
209if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ] 501# handle ssh_config
502csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults"
503if cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
210then 504then
211 echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
212 ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
213fi
214
215# Check if ssh_config exists. If yes, ask for overwriting
216
217if [ -f "${SYSCONFDIR}/ssh_config" ]
218then
219 if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?"
220 then
221 rm -f "${SYSCONFDIR}/ssh_config"
222 if [ -f "${SYSCONFDIR}/ssh_config" ]
223 then
224 echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected."
225 fi
226 fi
227fi
228
229# Create default ssh_config from skeleton file in /etc/defaults/etc
230
231if [ ! -f "${SYSCONFDIR}/ssh_config" ]
232then
233 echo "Generating ${SYSCONFDIR}/ssh_config file"
234 cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
235 if [ "${port_number}" != "22" ] 505 if [ "${port_number}" != "22" ]
236 then 506 then
507 csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port"
237 echo "Host localhost" >> ${SYSCONFDIR}/ssh_config 508 echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
238 echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config 509 echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
239 fi 510 fi
240fi 511fi
241 512
242# Check if sshd_config exists. If yes, ask for overwriting 513# handle sshd_config (and privsep)
243 514csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults"
244if [ -f "${SYSCONFDIR}/sshd_config" ] 515if ! cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
245then 516then
246 if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?" 517 grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
247 then
248 rm -f "${SYSCONFDIR}/sshd_config"
249 if [ -f "${SYSCONFDIR}/sshd_config" ]
250 then
251 echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected."
252 fi
253 else
254 grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
255 fi
256fi 518fi
519sshd_privsep
257 520
258# Prior to creating or modifying sshd_config, care for privilege separation
259 521
260if [ "${privsep_configured}" != "yes" ]
261then
262 if [ ${_nt} -gt 0 ]
263 then
264 echo "Privilege separation is set to yes by default since OpenSSH 3.3."
265 echo "However, this requires a non-privileged account called 'sshd'."
266 echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
267 echo
268 if request "Should privilege separation be used?"
269 then
270 privsep_used=yes
271 grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
272 net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
273 if [ "${sshd_in_passwd}" != "yes" ]
274 then
275 if [ "${sshd_in_sam}" != "yes" ]
276 then
277 echo "Warning: The following function requires administrator privileges!"
278 if request "Should this script create a local user 'sshd' on this machine?"
279 then
280 dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
281 net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
282 if [ "${sshd_in_sam}" != "yes" ]
283 then
284 echo "Warning: Creating the user 'sshd' failed!"
285 fi
286 fi
287 fi
288 if [ "${sshd_in_sam}" != "yes" ]
289 then
290 echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
291 echo " Privilege separation set to 'no' again!"
292 echo " Check your ${SYSCONFDIR}/sshd_config file!"
293 privsep_used=no
294 else
295 mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
296 fi
297 fi
298 else
299 privsep_used=no
300 fi
301 else
302 # On 9x don't use privilege separation. Since security isn't
303 # available it just adds useless additional processes.
304 privsep_used=no
305 fi
306fi
307
308# Create default sshd_config from skeleton files in /etc/defaults/etc or
309# modify to add the missing privsep configuration option
310
311if [ ! -f "${SYSCONFDIR}/sshd_config" ]
312then
313 echo "Generating ${SYSCONFDIR}/sshd_config file"
314 sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
315 s/^#Port 22/Port ${port_number}/
316 s/^#StrictModes yes/StrictModes no/" \
317 < ${SYSCONFDIR}/defaults/etc/sshd_config \
318 > ${SYSCONFDIR}/sshd_config
319elif [ "${privsep_configured}" != "yes" ]
320then
321 echo >> ${SYSCONFDIR}/sshd_config
322 echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
323fi
324 522
325# Care for services file 523update_services_file
326_my_etcdir="/ssh-host-config.$$" 524update_inetd_conf
327if [ ${_nt} -gt 0 ] 525install_service
328then
329 _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
330 _services="${_my_etcdir}/services"
331 # On NT, 27 spaces, no space after the hash
332 _spaces=" #"
333else
334 _win_etcdir="${WINDIR}"
335 _services="${_my_etcdir}/SERVICES"
336 # On 9x, 18 spaces (95 is very touchy), a space after the hash
337 _spaces=" # "
338fi
339_serv_tmp="${_my_etcdir}/srv.out.$$"
340
341mount -t -f "${_win_etcdir}" "${_my_etcdir}"
342
343# Depends on the above mount
344_wservices=`cygpath -w "${_services}"`
345
346# Remove sshd 22/port from services
347if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
348then
349 grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
350 if [ -f "${_serv_tmp}" ]
351 then
352 if mv "${_serv_tmp}" "${_services}"
353 then
354 echo "Removing sshd from ${_wservices}"
355 else
356 echo "Removing sshd from ${_wservices} failed!"
357 fi
358 rm -f "${_serv_tmp}"
359 else
360 echo "Removing sshd from ${_wservices} failed!"
361 fi
362fi
363
364# Add ssh 22/tcp and ssh 22/udp to services
365if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
366then
367 if awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh 22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}"
368 then
369 if mv "${_serv_tmp}" "${_services}"
370 then
371 echo "Added ssh to ${_wservices}"
372 else
373 echo "Adding ssh to ${_wservices} failed!"
374 fi
375 rm -f "${_serv_tmp}"
376 else
377 echo "WARNING: Adding ssh to ${_wservices} failed!"
378 fi
379fi
380
381umount "${_my_etcdir}"
382
383# Care for inetd.conf file
384_inetcnf="${SYSCONFDIR}/inetd.conf"
385_inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
386
387if [ -f "${_inetcnf}" ]
388then
389 # Check if ssh service is already in use as sshd
390 with_comment=1
391 grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0
392 # Remove sshd line from inetd.conf
393 if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
394 then
395 grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
396 if [ -f "${_inetcnf_tmp}" ]
397 then
398 if mv "${_inetcnf_tmp}" "${_inetcnf}"
399 then
400 echo "Removed sshd from ${_inetcnf}"
401 else
402 echo "Removing sshd from ${_inetcnf} failed!"
403 fi
404 rm -f "${_inetcnf_tmp}"
405 else
406 echo "Removing sshd from ${_inetcnf} failed!"
407 fi
408 fi
409
410 # Add ssh line to inetd.conf
411 if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
412 then
413 if [ "${with_comment}" -eq 0 ]
414 then
415 echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
416 else
417 echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
418 fi
419 echo "Added ssh to ${_inetcnf}"
420 fi
421fi
422
423# On NT ask if sshd should be installed as service
424if [ ${_nt} -gt 0 ]
425then
426 # But only if it is not already installed
427 if ! cygrunsrv -Q sshd > /dev/null 2>&1
428 then
429 echo
430 echo
431 echo "Warning: The following functions require administrator privileges!"
432 echo
433 echo "Do you want to install sshd as service?"
434 if request "(Say \"no\" if it's already installed as service)"
435 then
436 if [ $_nt2003 -gt 0 ]
437 then
438 grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
439 if [ "${sshd_server_in_passwd}" = "yes" ]
440 then
441 # Drop sshd_server from passwd since it could have wrong settings
442 grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
443 rm -f ${SYSCONFDIR}/passwd
444 mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
445 chmod g-w,o-w ${SYSCONFDIR}/passwd
446 fi
447 net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
448 if [ "${sshd_server_in_sam}" != "yes" ]
449 then
450 echo
451 echo "You appear to be running Windows 2003 Server or later. On 2003 and"
452 echo "later systems, it's not possible to use the LocalSystem account"
453 echo "if sshd should allow passwordless logon (e. g. public key authentication)."
454 echo "If you want to enable that functionality, it's required to create a new"
455 echo "account 'sshd_server' with special privileges, which is then used to run"
456 echo "the sshd service under."
457 echo
458 echo "Should this script create a new local account 'sshd_server' which has"
459 if request "the required privileges?"
460 then
461 _admingroup=`mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' `
462 if [ -z "${_admingroup}" ]
463 then
464 echo "mkgroup -l produces no group with SID S-1-5-32-544 (Local administrators group)."
465 exit 1
466 fi
467 dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
468 while [ "${sshd_server_in_sam}" != "yes" ]
469 do
470 if [ -n "${password_value}" ]
471 then
472 _password="${password_value}"
473 # Allow to ask for password if first try fails
474 password_value=""
475 else
476 echo
477 echo "Please enter a password for new user 'sshd_server'. Please be sure that"
478 echo "this password matches the password rules given on your system."
479 echo -n "Entering no password will exit the configuration. PASSWORD="
480 read -e _password
481 if [ -z "${_password}" ]
482 then
483 echo
484 echo "Exiting configuration. No user sshd_server has been created,"
485 echo "no sshd service installed."
486 exit 1
487 fi
488 fi
489 net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
490 if [ "${sshd_server_in_sam}" != "yes" ]
491 then
492 echo "Creating the user 'sshd_server' failed! Reason:"
493 cat /tmp/nu.$$
494 rm /tmp/nu.$$
495 fi
496 done
497 net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
498 if [ "${sshd_server_in_admingroup}" != "yes" ]
499 then
500 echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
501 echo "Please add sshd_server to local group ${_admingroup} before"
502 echo "starting the sshd service!"
503 echo
504 fi
505 passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
506 if [ "${passwd_has_expiry_flags}" != "yes" ]
507 then
508 echo
509 echo "WARNING: User sshd_server has password expiry set to system default."
510 echo "Please check that password never expires or set it to your needs."
511 elif ! passwd -e sshd_server
512 then
513 echo
514 echo "WARNING: Setting password expiry for user sshd_server failed!"
515 echo "Please check that password never expires or set it to your needs."
516 fi
517 editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
518 editrights -a SeCreateTokenPrivilege -u sshd_server &&
519 editrights -a SeTcbPrivilege -u sshd_server &&
520 editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
521 editrights -a SeDenyNetworkLogonRight -u sshd_server &&
522 editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
523 editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
524 editrights -a SeServiceLogonRight -u sshd_server &&
525 sshd_server_got_all_rights="yes"
526 if [ "${sshd_server_got_all_rights}" != "yes" ]
527 then
528 echo
529 echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
530 echo "Can't create sshd service!"
531 exit 1
532 fi
533 echo
534 echo "User 'sshd_server' has been created with password '${_password}'."
535 echo "If you change the password, please keep in mind to change the password"
536 echo "for the sshd service, too."
537 echo
538 echo "Also keep in mind that the user sshd_server needs read permissions on all"
539 echo "users' .ssh/authorized_keys file to allow public key authentication for"
540 echo "these users!. (Re-)running ssh-user-config for each user will set the"
541 echo "required permissions correctly."
542 echo
543 fi
544 fi
545 if [ "${sshd_server_in_sam}" = "yes" ]
546 then
547 mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
548 fi
549 fi
550 if [ -n "${cygwin_value}" ]
551 then
552 _cygwin="${cygwin_value}"
553 else
554 echo
555 echo "Which value should the environment variable CYGWIN have when"
556 echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
557 echo "able to change user context without password."
558 echo -n "Default is \"ntsec\". CYGWIN="
559 read -e _cygwin
560 fi
561 [ -z "${_cygwin}" ] && _cygwin="ntsec"
562 if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
563 then
564 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}" -y tcpip
565 then
566 echo
567 echo "The service has been installed under sshd_server account."
568 echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
569 fi
570 else
571 if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}" -y tcpip
572 then
573 echo
574 echo "The service has been installed under LocalSystem account."
575 echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
576 fi
577 fi
578 fi
579 # Now check if sshd has been successfully installed. This allows to
580 # set the ownership of the affected files correctly.
581 if cygrunsrv -Q sshd > /dev/null 2>&1
582 then
583 if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
584 then
585 _user="sshd_server"
586 else
587 _user="system"
588 fi
589 chown "${_user}" ${SYSCONFDIR}/ssh*
590 chown "${_user}".544 ${LOCALSTATEDIR}/empty
591 chown "${_user}".544 ${LOCALSTATEDIR}/log/lastlog
592 if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
593 then
594 chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
595 fi
596 fi
597 if ! ( mount | egrep -q 'on /(|usr/(bin|lib)) type system' )
598 then
599 echo
600 echo "Warning: It appears that you have user mode mounts (\"Just me\""
601 echo "chosen during install.) Any daemons installed as services will"
602 echo "fail to function unless system mounts are used. To change this,"
603 echo "re-run setup.exe and choose \"All users\"."
604 echo
605 echo "For more information, see http://cygwin.com/faq/faq0.html#TOC33"
606 fi
607 fi
608fi
609 526
610echo 527echo
611echo "Host configuration finished. Have fun!" 528csih_inform "Host configuration finished. Have fun!"
529
diff --git a/contrib/cygwin/ssh-user-config b/contrib/cygwin/ssh-user-config
index 9482efe9e..f210bd556 100644
--- a/contrib/cygwin/ssh-user-config
+++ b/contrib/cygwin/ssh-user-config
@@ -1,52 +1,235 @@
1#!/bin/sh 1#!/bin/bash
2# 2#
3# ssh-user-config, Copyright 2000, 2001, 2002, 2003, Red Hat Inc. 3# ssh-user-config, Copyright 2000, 2001, 2002, 2003, Red Hat Inc.
4# 4#
5# This file is part of the Cygwin port of OpenSSH. 5# This file is part of the Cygwin port of OpenSSH.
6 6
7# ======================================================================
8# Initialization
9# ======================================================================
10PROGNAME=$(basename -- $0)
11_tdir=$(dirname -- $0)
12PROGDIR=$(cd $_tdir && pwd)
13
14CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
15
16# Subdirectory where the new package is being installed
17PREFIX=/usr
18
7# Directory where the config files are stored 19# Directory where the config files are stored
8SYSCONFDIR=/etc 20SYSCONFDIR=/etc
9 21
10progname=$0 22source ${CSIH_SCRIPT}
11auto_answer="" 23
12auto_passphrase="no" 24auto_passphrase="no"
13passphrase="" 25passphrase=""
26pwdhome=
27with_passphrase=
28
29# ======================================================================
30# Routine: create_ssh1_identity
31# optionally create ~/.ssh/identity[.pub]
32# optionally add result to ~/.ssh/authorized_keys
33# ======================================================================
34create_ssh1_identity() {
35 if [ ! -f "${pwdhome}/.ssh/identity" ]
36 then
37 if csih_request "Shall I create an SSH1 RSA identity file for you?"
38 then
39 csih_inform "Generating ${pwdhome}/.ssh/identity"
40 if [ "${with_passphrase}" = "yes" ]
41 then
42 ssh-keygen -t rsa1 -N "${passphrase}" -f "${pwdhome}/.ssh/identity" > /dev/null
43 else
44 ssh-keygen -t rsa1 -f "${pwdhome}/.ssh/identity" > /dev/null
45 fi
46 if csih_request "Do you want to use this identity to login to this machine?"
47 then
48 csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys"
49 cat "${pwdhome}/.ssh/identity.pub" >> "${pwdhome}/.ssh/authorized_keys"
50 fi
51 fi
52 fi
53} # === End of create_ssh1_identity() === #
54readonly -f create_ssh1_identity
55
56# ======================================================================
57# Routine: create_ssh2_rsa_identity
58# optionally create ~/.ssh/id_rsa[.pub]
59# optionally add result to ~/.ssh/authorized_keys
60# ======================================================================
61create_ssh2_rsa_identity() {
62 if [ ! -f "${pwdhome}/.ssh/id_rsa" ]
63 then
64 if csih_request "Shall I create an SSH2 RSA identity file for you?"
65 then
66 csih_inform "Generating ${pwdhome}/.ssh/id_rsa"
67 if [ "${with_passphrase}" = "yes" ]
68 then
69 ssh-keygen -t rsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_rsa" > /dev/null
70 else
71 ssh-keygen -t rsa -f "${pwdhome}/.ssh/id_rsa" > /dev/null
72 fi
73 if csih_request "Do you want to use this identity to login to this machine?"
74 then
75 csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys"
76 cat "${pwdhome}/.ssh/id_rsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
77 fi
78 fi
79 fi
80} # === End of create_ssh2_rsa_identity() === #
81readonly -f create_ssh2_rsa_identity
82
83# ======================================================================
84# Routine: create_ssh2_dsa_identity
85# optionally create ~/.ssh/id_dsa[.pub]
86# optionally add result to ~/.ssh/authorized_keys
87# ======================================================================
88create_ssh2_dsa_identity() {
89 if [ ! -f "${pwdhome}/.ssh/id_dsa" ]
90 then
91 if csih_request "Shall I create an SSH2 DSA identity file for you?"
92 then
93 csih_inform "Generating ${pwdhome}/.ssh/id_dsa"
94 if [ "${with_passphrase}" = "yes" ]
95 then
96 ssh-keygen -t dsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_dsa" > /dev/null
97 else
98 ssh-keygen -t dsa -f "${pwdhome}/.ssh/id_dsa" > /dev/null
99 fi
100 if csih_request "Do you want to use this identity to login to this machine?"
101 then
102 csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys"
103 cat "${pwdhome}/.ssh/id_dsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
104 fi
105 fi
106 fi
107} # === End of create_ssh2_dsa_identity() === #
108readonly -f create_ssh2_dsa_identity
109
110# ======================================================================
111# Routine: check_user_homedir
112# Perform various checks on the user's home directory
113# SETS GLOBAL VARIABLE:
114# pwdhome
115# ======================================================================
116check_user_homedir() {
117 local uid=$(id -u)
118 pwdhome=$(awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd)
119 if [ "X${pwdhome}" = "X" ]
120 then
121 csih_error_multiline \
122 "There is no home directory set for you in ${SYSCONFDIR}/passwd." \
123 'Setting $HOME is not sufficient!'
124 fi
125
126 if [ ! -d "${pwdhome}" ]
127 then
128 csih_error_multiline \
129 "${pwdhome} is set in ${SYSCONFDIR}/passwd as your home directory" \
130 'but it is not a valid directory. Cannot create user identity files.'
131 fi
132
133 # If home is the root dir, set home to empty string to avoid error messages
134 # in subsequent parts of that script.
135 if [ "X${pwdhome}" = "X/" ]
136 then
137 # But first raise a warning!
138 csih_warning "Your home directory in ${SYSCONFDIR}/passwd is set to root (/). This is not recommended!"
139 if csih_request "Would you like to proceed anyway?"
140 then
141 pwdhome=''
142 else
143 csih_warning "Exiting. Configuration is not complete"
144 exit 1
145 fi
146 fi
147
148 if [ -d "${pwdhome}" -a csih_is_nt -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ]
149 then
150 echo
151 csih_warning 'group and other have been revoked write permission to your home'
152 csih_warning "directory ${pwdhome}."
153 csih_warning 'This is required by OpenSSH to allow public key authentication using'
154 csih_warning 'the key files stored in your .ssh subdirectory.'
155 csih_warning 'Revert this change ONLY if you know what you are doing!'
156 echo
157 fi
158} # === End of check_user_homedir() === #
159readonly -f check_user_homedir
14 160
15request() 161# ======================================================================
16{ 162# Routine: check_user_dot_ssh_dir
17 if [ "${auto_answer}" = "yes" ] 163# Perform various checks on the ~/.ssh directory
164# PREREQUISITE:
165# pwdhome -- check_user_homedir()
166# ======================================================================
167check_user_dot_ssh_dir() {
168 if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ]
18 then 169 then
19 return 0 170 csih_error "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files."
20 elif [ "${auto_answer}" = "no" ] 171 fi
172
173 if [ ! -e "${pwdhome}/.ssh" ]
21 then 174 then
22 return 1 175 mkdir "${pwdhome}/.ssh"
176 if [ ! -e "${pwdhome}/.ssh" ]
177 then
178 csih_error "Creating users ${pwdhome}/.ssh directory failed"
179 fi
23 fi 180 fi
181} # === End of check_user_dot_ssh_dir() === #
182readonly -f check_user_dot_ssh_dir
24 183
25 answer="" 184# ======================================================================
26 while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ] 185# Routine: fix_authorized_keys_perms
27 do 186# Corrects the permissions of ~/.ssh/authorized_keys
28 echo -n "$1 (yes/no) " 187# PREREQUISITE:
29 read answer 188# pwdhome -- check_user_homedir()
30 done 189# ======================================================================
31 if [ "X${answer}" = "Xyes" ] 190fix_authorized_keys_perms() {
191 if [ csih_is_nt -a -e "${pwdhome}/.ssh/authorized_keys" ]
32 then 192 then
33 return 0 193 if ! setfacl -m "u::rw-,g::---,o::---" "${pwdhome}/.ssh/authorized_keys"
34 else 194 then
35 return 1 195 csih_warning "Setting correct permissions to ${pwdhome}/.ssh/authorized_keys"
196 csih_warning "failed. Please care for the correct permissions. The minimum requirement"
197 csih_warning "is, the owner needs read permissions."
198 echo
199 fi
36 fi 200 fi
37} 201} # === End of fix_authorized_keys_perms() === #
202readonly -f fix_authorized_keys_perms
203
204
205# ======================================================================
206# Main Entry Point
207# ======================================================================
38 208
39# Check if running on NT 209# Check how the script has been started. If
40_sys="`uname -a`" 210# (1) it has been started by giving the full path and
41_nt=`expr "$_sys" : "CYGWIN_NT"` 211# that path is /etc/postinstall, OR
42# If running on NT, check if running under 2003 Server or later 212# (2) Otherwise, if the environment variable
43if [ $_nt -gt 0 ] 213# SSH_USER_CONFIG_AUTO_ANSWER_NO is set
214# then set auto_answer to "no". This allows automatic
215# creation of the config files in /etc w/o overwriting
216# them if they already exist. In both cases, color
217# escape sequences are suppressed, so as to prevent
218# cluttering setup's logfiles.
219if [ "$PROGDIR" = "/etc/postinstall" ]
44then 220then
45 _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'` 221 csih_auto_answer="no"
222 csih_disable_color
223fi
224if [ -n "${SSH_USER_CONFIG_AUTO_ANSWER_NO}" ]
225then
226 csih_auto_answer="no"
227 csih_disable_color
46fi 228fi
47 229
48# Check options 230# ======================================================================
49 231# Parse options
232# ======================================================================
50while : 233while :
51do 234do
52 case $# in 235 case $# in
@@ -61,14 +244,15 @@ do
61 case "$option" in 244 case "$option" in
62 -d | --debug ) 245 -d | --debug )
63 set -x 246 set -x
247 csih_trace_on
64 ;; 248 ;;
65 249
66 -y | --yes ) 250 -y | --yes )
67 auto_answer=yes 251 csih_auto_answer=yes
68 ;; 252 ;;
69 253
70 -n | --no ) 254 -n | --no )
71 auto_answer=no 255 csih_auto_answer=no
72 ;; 256 ;;
73 257
74 -p | --passphrase ) 258 -p | --passphrase )
@@ -77,8 +261,12 @@ do
77 shift 261 shift
78 ;; 262 ;;
79 263
264 --privileged )
265 csih_FORCE_PRIVILEGED_USER=yes
266 ;;
267
80 *) 268 *)
81 echo "usage: ${progname} [OPTION]..." 269 echo "usage: ${PROGNAME} [OPTION]..."
82 echo 270 echo
83 echo "This script creates an OpenSSH user configuration." 271 echo "This script creates an OpenSSH user configuration."
84 echo 272 echo
@@ -87,6 +275,8 @@ do
87 echo " --yes -y Answer all questions with \"yes\" automatically." 275 echo " --yes -y Answer all questions with \"yes\" automatically."
88 echo " --no -n Answer all questions with \"no\" automatically." 276 echo " --no -n Answer all questions with \"no\" automatically."
89 echo " --passphrase -p word Use \"word\" as passphrase automatically." 277 echo " --passphrase -p word Use \"word\" as passphrase automatically."
278 echo " --privileged On Windows NT/2k/XP, assume privileged user"
279 echo " instead of LocalSystem for sshd service."
90 echo 280 echo
91 exit 1 281 exit 1
92 ;; 282 ;;
@@ -94,157 +284,27 @@ do
94 esac 284 esac
95done 285done
96 286
97# Ask user if user identity should be generated 287# ======================================================================
288# Action!
289# ======================================================================
98 290
291# Check passwd file
99if [ ! -f ${SYSCONFDIR}/passwd ] 292if [ ! -f ${SYSCONFDIR}/passwd ]
100then 293then
101 echo "${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file" 294 csih_error_multiline \
102 echo 'first using mkpasswd. Check if it contains an entry for you and' 295 "${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file" \
103 echo 'please care for the home directory in your entry as well.' 296 'first using mkpasswd. Check if it contains an entry for you and' \
104 exit 1 297 'please care for the home directory in your entry as well.'
105fi
106
107uid=`id -u`
108pwdhome=`awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd`
109
110if [ "X${pwdhome}" = "X" ]
111then
112 echo "There is no home directory set for you in ${SYSCONFDIR}/passwd."
113 echo 'Setting $HOME is not sufficient!'
114 exit 1
115fi
116
117if [ ! -d "${pwdhome}" ]
118then
119 echo "${pwdhome} is set in ${SYSCONFDIR}/passwd as your home directory"
120 echo 'but it is not a valid directory. Cannot create user identity files.'
121 exit 1
122fi
123
124# If home is the root dir, set home to empty string to avoid error messages
125# in subsequent parts of that script.
126if [ "X${pwdhome}" = "X/" ]
127then
128 # But first raise a warning!
129 echo "Your home directory in ${SYSCONFDIR}/passwd is set to root (/). This is not recommended!"
130 if request "Would you like to proceed anyway?"
131 then
132 pwdhome=''
133 else
134 exit 1
135 fi
136fi
137
138if [ -d "${pwdhome}" -a $_nt -gt 0 -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ]
139then
140 echo
141 echo 'WARNING: group and other have been revoked write permission to your home'
142 echo " directory ${pwdhome}."
143 echo ' This is required by OpenSSH to allow public key authentication using'
144 echo ' the key files stored in your .ssh subdirectory.'
145 echo ' Revert this change ONLY if you know what you are doing!'
146 echo
147fi
148
149if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ]
150then
151 echo "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files."
152 exit 1
153fi
154
155if [ ! -e "${pwdhome}/.ssh" ]
156then
157 mkdir "${pwdhome}/.ssh"
158 if [ ! -e "${pwdhome}/.ssh" ]
159 then
160 echo "Creating users ${pwdhome}/.ssh directory failed"
161 exit 1
162 fi
163fi
164
165if [ $_nt -gt 0 ]
166then
167 _user="system"
168 if [ $_nt2003 -gt 0 ]
169 then
170 grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && _user="sshd_server"
171 fi
172 if ! setfacl -m "u::rwx,u:${_user}:r--,g::---,o::---" "${pwdhome}/.ssh"
173 then
174 echo "${pwdhome}/.ssh couldn't be given the correct permissions."
175 echo "Please try to solve this problem first."
176 exit 1
177 fi
178fi
179
180if [ ! -f "${pwdhome}/.ssh/identity" ]
181then
182 if request "Shall I create an SSH1 RSA identity file for you?"
183 then
184 echo "Generating ${pwdhome}/.ssh/identity"
185 if [ "${with_passphrase}" = "yes" ]
186 then
187 ssh-keygen -t rsa1 -N "${passphrase}" -f "${pwdhome}/.ssh/identity" > /dev/null
188 else
189 ssh-keygen -t rsa1 -f "${pwdhome}/.ssh/identity" > /dev/null
190 fi
191 if request "Do you want to use this identity to login to this machine?"
192 then
193 echo "Adding to ${pwdhome}/.ssh/authorized_keys"
194 cat "${pwdhome}/.ssh/identity.pub" >> "${pwdhome}/.ssh/authorized_keys"
195 fi
196 fi
197fi 298fi
198 299
199if [ ! -f "${pwdhome}/.ssh/id_rsa" ] 300check_user_homedir
200then 301check_user_dot_ssh_dir
201 if request "Shall I create an SSH2 RSA identity file for you?" 302create_ssh1_identity
202 then 303create_ssh2_rsa_identity
203 echo "Generating ${pwdhome}/.ssh/id_rsa" 304create_ssh2_dsa_identity
204 if [ "${with_passphrase}" = "yes" ] 305fix_authorized_keys_perms
205 then
206 ssh-keygen -t rsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_rsa" > /dev/null
207 else
208 ssh-keygen -t rsa -f "${pwdhome}/.ssh/id_rsa" > /dev/null
209 fi
210 if request "Do you want to use this identity to login to this machine?"
211 then
212 echo "Adding to ${pwdhome}/.ssh/authorized_keys"
213 cat "${pwdhome}/.ssh/id_rsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
214 fi
215 fi
216fi
217 306
218if [ ! -f "${pwdhome}/.ssh/id_dsa" ] 307echo
219then 308csih_inform "Configuration finished. Have fun!"
220 if request "Shall I create an SSH2 DSA identity file for you?"
221 then
222 echo "Generating ${pwdhome}/.ssh/id_dsa"
223 if [ "${with_passphrase}" = "yes" ]
224 then
225 ssh-keygen -t dsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_dsa" > /dev/null
226 else
227 ssh-keygen -t dsa -f "${pwdhome}/.ssh/id_dsa" > /dev/null
228 fi
229 if request "Do you want to use this identity to login to this machine?"
230 then
231 echo "Adding to ${pwdhome}/.ssh/authorized_keys"
232 cat "${pwdhome}/.ssh/id_dsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
233 fi
234 fi
235fi
236 309
237if [ $_nt -gt 0 -a -e "${pwdhome}/.ssh/authorized_keys" ]
238then
239 if ! setfacl -m "u::rw-,u:${_user}:r--,g::---,o::---" "${pwdhome}/.ssh/authorized_keys"
240 then
241 echo
242 echo "WARNING: Setting correct permissions to ${pwdhome}/.ssh/authorized_keys"
243 echo "failed. Please care for the correct permissions. The minimum requirement"
244 echo "is, the owner and ${_user} both need read permissions."
245 echo
246 fi
247fi
248 310
249echo
250echo "Configuration finished. Have fun!"
diff --git a/contrib/cygwin/sshd-inetd b/contrib/cygwin/sshd-inetd
new file mode 100644
index 000000000..aa6bf073f
--- /dev/null
+++ b/contrib/cygwin/sshd-inetd
@@ -0,0 +1,4 @@
1# This file can be used to enable sshd as a slave of the inetd service
2# To do so, the line below should be uncommented.
3@COMMENT@ ssh stream tcp nowait root /usr/sbin/sshd sshd -i
4
diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
index 0ce8daec9..901176dbb 100644
--- a/contrib/gnome-ssh-askpass2.c
+++ b/contrib/gnome-ssh-askpass2.c
@@ -111,6 +111,7 @@ passphrase_dialog(char *message)
111 111
112 gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); 112 gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH");
113 gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); 113 gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
114 gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
114 gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label), 115 gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label),
115 TRUE); 116 TRUE);
116 117
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec
index 34ec6b7e1..bb9e4d616 100644
--- a/contrib/redhat/openssh.spec
+++ b/contrib/redhat/openssh.spec
@@ -1,4 +1,4 @@
1%define ver 4.7p1 1%define ver 5.1p1
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
@@ -376,6 +376,7 @@ fi
376%attr(0755,root,root) %{_sbindir}/sshd 376%attr(0755,root,root) %{_sbindir}/sshd
377%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server 377%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server
378%attr(0644,root,root) %{_mandir}/man8/sshd.8* 378%attr(0644,root,root) %{_mandir}/man8/sshd.8*
379%attr(0644,root,root) %{_mandir}/man5/moduli.5*
379%attr(0644,root,root) %{_mandir}/man5/sshd_config.5* 380%attr(0644,root,root) %{_mandir}/man5/sshd_config.5*
380%attr(0644,root,root) %{_mandir}/man8/sftp-server.8* 381%attr(0644,root,root) %{_mandir}/man8/sftp-server.8*
381%attr(0755,root,root) %dir %{_sysconfdir}/ssh 382%attr(0755,root,root) %dir %{_sysconfdir}/ssh
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index 1555b5d37..acd36d398 100644
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -11,7 +11,7 @@ if [ "-i" = "$1" ]; then
11 shift 11 shift
12 # check if we have 2 parameters left, if so the first is the new ID file 12 # check if we have 2 parameters left, if so the first is the new ID file
13 if [ -n "$2" ]; then 13 if [ -n "$2" ]; then
14 if expr "$1" : ".*\.pub" ; then 14 if expr "$1" : ".*\.pub" > /dev/null ; then
15 ID_FILE="$1" 15 ID_FILE="$1"
16 else 16 else
17 ID_FILE="$1.pub" 17 ID_FILE="$1.pub"
diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec
index 1f5230586..7bd9e0569 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: 4.7p1 16Version: 5.1p1
17URL: http://www.openssh.com/ 17URL: http://www.openssh.com/
18Release: 1 18Release: 1
19Source0: openssh-%{version}.tar.gz 19Source0: openssh-%{version}.tar.gz
@@ -201,7 +201,7 @@ fi
201%files 201%files
202%defattr(-,root,root) 202%defattr(-,root,root)
203%doc ChangeLog OVERVIEW README* 203%doc ChangeLog OVERVIEW README*
204%doc RFC.nroff TODO CREDITS LICENCE 204%doc TODO CREDITS LICENCE
205%attr(0755,root,root) %dir %{_sysconfdir}/ssh 205%attr(0755,root,root) %dir %{_sysconfdir}/ssh
206%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config 206%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config
207%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config 207%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config
@@ -228,6 +228,7 @@ fi
228%attr(0644,root,root) %doc %{_mandir}/man1/ssh-agent.1* 228%attr(0644,root,root) %doc %{_mandir}/man1/ssh-agent.1*
229%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keygen.1* 229%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keygen.1*
230%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keyscan.1* 230%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keyscan.1*
231%attr(0644,root,root) %doc %{_mandir}/man5/moduli.5*
231%attr(0644,root,root) %doc %{_mandir}/man5/ssh_config.5* 232%attr(0644,root,root) %doc %{_mandir}/man5/ssh_config.5*
232%attr(0644,root,root) %doc %{_mandir}/man5/sshd_config.5* 233%attr(0644,root,root) %doc %{_mandir}/man5/sshd_config.5*
233%attr(0644,root,root) %doc %{_mandir}/man8/sftp-server.8* 234%attr(0644,root,root) %doc %{_mandir}/man8/sftp-server.8*
diff --git a/defines.h b/defines.h
index 5e7d6769d..a8203ebbb 100644
--- a/defines.h
+++ b/defines.h
@@ -25,7 +25,7 @@
25#ifndef _DEFINES_H 25#ifndef _DEFINES_H
26#define _DEFINES_H 26#define _DEFINES_H
27 27
28/* $Id: defines.h,v 1.143 2007/08/09 04:37:52 dtucker Exp $ */ 28/* $Id: defines.h,v 1.151 2008/07/04 13:10:49 djm Exp $ */
29 29
30 30
31/* Constants */ 31/* Constants */
@@ -431,10 +431,6 @@ struct winsize {
431# define __attribute__(x) 431# define __attribute__(x)
432#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ 432#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
433 433
434#ifndef __dead
435# define __dead __attribute__((noreturn))
436#endif
437
438#if !defined(HAVE_ATTRIBUTE__SENTINEL__) && !defined(__sentinel__) 434#if !defined(HAVE_ATTRIBUTE__SENTINEL__) && !defined(__sentinel__)
439# define __sentinel__ 435# define __sentinel__
440#endif 436#endif
@@ -540,6 +536,10 @@ struct winsize {
540# undef HAVE_UPDWTMPX 536# undef HAVE_UPDWTMPX
541#endif 537#endif
542 538
539#if defined(BROKEN_SHADOW_EXPIRE) && defined(HAS_SHADOW_EXPIRE)
540# undef HAS_SHADOW_EXPIRE
541#endif
542
543#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \ 543#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
544 defined(SYSLOG_R_SAFE_IN_SIGHAND) 544 defined(SYSLOG_R_SAFE_IN_SIGHAND)
545# define DO_LOG_SAFE_IN_SIGHAND 545# define DO_LOG_SAFE_IN_SIGHAND
@@ -563,11 +563,6 @@ struct winsize {
563# define CUSTOM_SSH_AUDIT_EVENTS 563# define CUSTOM_SSH_AUDIT_EVENTS
564#endif 564#endif
565 565
566/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */
567#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f)
568# define OPENSSL_free(x) Free(x)
569#endif
570
571#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) 566#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
572# define __func__ __FUNCTION__ 567# define __func__ __FUNCTION__
573#elif !defined(HAVE___func__) 568#elif !defined(HAVE___func__)
@@ -591,6 +586,15 @@ struct winsize {
591# define SSH_SYSFDMAX 10000 586# define SSH_SYSFDMAX 10000
592#endif 587#endif
593 588
589#ifdef FSID_HAS_VAL
590/* encode f_fsid into a 64 bit value */
591#define FSID_TO_ULONG(f) \
592 ((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \
593 ((f).val[1] & 0xffffffffUL))
594#else
595# define FSID_TO_ULONG(f) ((f))
596#endif
597
594#if defined(__Lynx__) 598#if defined(__Lynx__)
595 /* 599 /*
596 * LynxOS defines these in param.h which we do not want to include since 600 * LynxOS defines these in param.h which we do not want to include since
@@ -694,9 +698,11 @@ struct winsize {
694# define CUSTOM_SYS_AUTH_PASSWD 1 698# define CUSTOM_SYS_AUTH_PASSWD 1
695#endif 699#endif
696 700
701#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID)
702# define CUSTOM_SYS_AUTH_PASSWD 1
703#endif
697#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF) 704#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF)
698# define USE_LIBIAF 705# define USE_LIBIAF
699# define CUSTOM_SYS_AUTH_PASSWD 1
700#endif 706#endif
701 707
702/* HP-UX 11.11 */ 708/* HP-UX 11.11 */
@@ -728,4 +734,8 @@ struct winsize {
728# endif 734# endif
729#endif 735#endif
730 736
737#ifndef EWOULDBLOCK
738# define EWOULDBLOCK EAGAIN
739#endif
740
731#endif /* _DEFINES_H */ 741#endif /* _DEFINES_H */
diff --git a/dh.c b/dh.c
index 78e230b9f..b76605325 100644
--- a/dh.c
+++ b/dh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dh.c,v 1.44 2006/11/07 13:02:07 markus Exp $ */ 1/* $OpenBSD: dh.c,v 1.47 2008/06/26 09:19:39 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * 4 *
@@ -46,6 +46,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
46 char *cp, *arg; 46 char *cp, *arg;
47 char *strsize, *gen, *prime; 47 char *strsize, *gen, *prime;
48 const char *errstr = NULL; 48 const char *errstr = NULL;
49 long long n;
49 50
50 cp = line; 51 cp = line;
51 if ((arg = strdelim(&cp)) == NULL) 52 if ((arg = strdelim(&cp)) == NULL)
@@ -62,12 +63,24 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
62 arg = strsep(&cp, " "); /* type */ 63 arg = strsep(&cp, " "); /* type */
63 if (cp == NULL || *arg == '\0') 64 if (cp == NULL || *arg == '\0')
64 goto fail; 65 goto fail;
66 /* Ensure this is a safe prime */
67 n = strtonum(arg, 0, 5, &errstr);
68 if (errstr != NULL || n != MODULI_TYPE_SAFE)
69 goto fail;
65 arg = strsep(&cp, " "); /* tests */ 70 arg = strsep(&cp, " "); /* tests */
66 if (cp == NULL || *arg == '\0') 71 if (cp == NULL || *arg == '\0')
67 goto fail; 72 goto fail;
73 /* Ensure prime has been tested and is not composite */
74 n = strtonum(arg, 0, 0x1f, &errstr);
75 if (errstr != NULL ||
76 (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE))
77 goto fail;
68 arg = strsep(&cp, " "); /* tries */ 78 arg = strsep(&cp, " "); /* tries */
69 if (cp == NULL || *arg == '\0') 79 if (cp == NULL || *arg == '\0')
70 goto fail; 80 goto fail;
81 n = strtonum(arg, 0, 1<<30, &errstr);
82 if (errstr != NULL || n == 0)
83 goto fail;
71 strsize = strsep(&cp, " "); /* size */ 84 strsize = strsep(&cp, " "); /* size */
72 if (cp == NULL || *strsize == '\0' || 85 if (cp == NULL || *strsize == '\0' ||
73 (dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || 86 (dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
@@ -153,7 +166,7 @@ choose_dh(int min, int wantbits, int max)
153 } 166 }
154 167
155 linenum = 0; 168 linenum = 0;
156 which = arc4random() % bestcount; 169 which = arc4random_uniform(bestcount);
157 while (fgets(line, sizeof(line), f)) { 170 while (fgets(line, sizeof(line), f)) {
158 if (!parse_prime(linenum, line, &dhg)) 171 if (!parse_prime(linenum, line, &dhg))
159 continue; 172 continue;
@@ -185,7 +198,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
185 BIGNUM *tmp; 198 BIGNUM *tmp;
186 199
187 if (dh_pub->neg) { 200 if (dh_pub->neg) {
188 logit("invalid public DH value: negativ"); 201 logit("invalid public DH value: negative");
189 return 0; 202 return 0;
190 } 203 }
191 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */ 204 if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
@@ -193,8 +206,10 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
193 return 0; 206 return 0;
194 } 207 }
195 208
196 if ((tmp = BN_new()) == NULL) 209 if ((tmp = BN_new()) == NULL) {
197 return (-1); 210 error("%s: BN_new failed", __func__);
211 return 0;
212 }
198 if (!BN_sub(tmp, dh->p, BN_value_one()) || 213 if (!BN_sub(tmp, dh->p, BN_value_one()) ||
199 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ 214 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
200 BN_clear_free(tmp); 215 BN_clear_free(tmp);
diff --git a/dh.h b/dh.h
index 8e580ee87..dfc1480ea 100644
--- a/dh.h
+++ b/dh.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: dh.h,v 1.9 2006/03/25 22:22:43 djm Exp $ */ 1/* $OpenBSD: dh.h,v 1.10 2008/06/26 09:19:40 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Niels Provos. All rights reserved. 4 * Copyright (c) 2000 Niels Provos. All rights reserved.
@@ -46,4 +46,28 @@ int dh_estimate(int);
46#define DH_GRP_MIN 1024 46#define DH_GRP_MIN 1024
47#define DH_GRP_MAX 8192 47#define DH_GRP_MAX 8192
48 48
49/*
50 * Values for "type" field of moduli(5)
51 * Specifies the internal structure of the prime modulus.
52 */
53#define MODULI_TYPE_UNKNOWN (0)
54#define MODULI_TYPE_UNSTRUCTURED (1)
55#define MODULI_TYPE_SAFE (2)
56#define MODULI_TYPE_SCHNORR (3)
57#define MODULI_TYPE_SOPHIE_GERMAIN (4)
58#define MODULI_TYPE_STRONG (5)
59
60/*
61 * Values for "tests" field of moduli(5)
62 * Specifies the methods used in checking for primality.
63 * Usually, more than one test is used.
64 */
65#define MODULI_TESTS_UNTESTED (0x00)
66#define MODULI_TESTS_COMPOSITE (0x01)
67#define MODULI_TESTS_SIEVE (0x02)
68#define MODULI_TESTS_MILLER_RABIN (0x04)
69#define MODULI_TESTS_JACOBI (0x08)
70#define MODULI_TESTS_ELLIPTIC (0x10)
71
72
49#endif 73#endif
diff --git a/dns.c b/dns.c
index a89176f88..a7da03fa3 100644
--- a/dns.c
+++ b/dns.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dns.c,v 1.24 2007/01/03 03:01:40 stevesk Exp $ */ 1/* $OpenBSD: dns.c,v 1.25 2008/06/12 00:03:49 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003 Wesley Griffin. All rights reserved. 4 * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -145,11 +145,20 @@ is_numeric_hostname(const char *hostname)
145{ 145{
146 struct addrinfo hints, *ai; 146 struct addrinfo hints, *ai;
147 147
148 /*
149 * We shouldn't ever get a null host but if we do then log an error
150 * and return -1 which stops DNS key fingerprint processing.
151 */
152 if (hostname == NULL) {
153 error("is_numeric_hostname called with NULL hostname");
154 return -1;
155 }
156
148 memset(&hints, 0, sizeof(hints)); 157 memset(&hints, 0, sizeof(hints));
149 hints.ai_socktype = SOCK_DGRAM; 158 hints.ai_socktype = SOCK_DGRAM;
150 hints.ai_flags = AI_NUMERICHOST; 159 hints.ai_flags = AI_NUMERICHOST;
151 160
152 if (getaddrinfo(hostname, "0", &hints, &ai) == 0) { 161 if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) {
153 freeaddrinfo(ai); 162 freeaddrinfo(ai);
154 return -1; 163 return -1;
155 } 164 }
diff --git a/groupaccess.c b/groupaccess.c
index e73f62b22..2381aeb15 100644
--- a/groupaccess.c
+++ b/groupaccess.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: groupaccess.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: groupaccess.c,v 1.13 2008/07/04 03:44:59 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Kevin Steves. All rights reserved. 3 * Copyright (c) 2001 Kevin Steves. All rights reserved.
4 * 4 *
@@ -31,6 +31,7 @@
31#include <grp.h> 31#include <grp.h>
32#include <unistd.h> 32#include <unistd.h>
33#include <stdarg.h> 33#include <stdarg.h>
34#include <string.h>
34 35
35#include "xmalloc.h" 36#include "xmalloc.h"
36#include "groupaccess.h" 37#include "groupaccess.h"
@@ -88,6 +89,30 @@ ga_match(char * const *groups, int n)
88} 89}
89 90
90/* 91/*
92 * Return 1 if one of user's groups matches group_pattern list.
93 * Return 0 on negated or no match.
94 */
95int
96ga_match_pattern_list(const char *group_pattern)
97{
98 int i, found = 0;
99 size_t len = strlen(group_pattern);
100
101 for (i = 0; i < ngroups; i++) {
102 switch (match_pattern_list(groups_byname[i],
103 group_pattern, len, 0)) {
104 case -1:
105 return 0; /* Negated match wins */
106 case 0:
107 continue;
108 case 1:
109 found = 1;
110 }
111 }
112 return found;
113}
114
115/*
91 * Free memory allocated for group access list. 116 * Free memory allocated for group access list.
92 */ 117 */
93void 118void
diff --git a/groupaccess.h b/groupaccess.h
index 04b449894..000578e76 100644
--- a/groupaccess.h
+++ b/groupaccess.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: groupaccess.h,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: groupaccess.h,v 1.8 2008/07/04 03:44:59 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 Kevin Steves. All rights reserved. 4 * Copyright (c) 2001 Kevin Steves. All rights reserved.
@@ -29,6 +29,7 @@
29 29
30int ga_init(const char *, gid_t); 30int ga_init(const char *, gid_t);
31int ga_match(char * const *, int); 31int ga_match(char * const *, int);
32int ga_match_pattern_list(const char *);
32void ga_free(void); 33void ga_free(void);
33 34
34#endif 35#endif
diff --git a/gss-serv.c b/gss-serv.c
index bc498fd47..2ec7ea19c 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gss-serv.c,v 1.21 2007/06/12 08:20:00 djm Exp $ */ 1/* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -35,6 +35,7 @@
35#include <string.h> 35#include <string.h>
36#include <unistd.h> 36#include <unistd.h>
37 37
38#include "openbsd-compat/sys-queue.h"
38#include "xmalloc.h" 39#include "xmalloc.h"
39#include "buffer.h" 40#include "buffer.h"
40#include "key.h" 41#include "key.h"
diff --git a/includes.h b/includes.h
index 9fcf1b023..f1b47f666 100644
--- a/includes.h
+++ b/includes.h
@@ -149,6 +149,8 @@
149# include <sys/syslog.h> 149# include <sys/syslog.h>
150#endif 150#endif
151 151
152#include <errno.h>
153
152/* 154/*
153 * On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations 155 * On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations
154 * of getspnam when _INCLUDE__STDC__ is defined, so we unset it here. 156 * of getspnam when _INCLUDE__STDC__ is defined, so we unset it here.
diff --git a/key.c b/key.c
index 8fef9b40f..2ea13d27d 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.69 2007/07/12 05:48:05 ray Exp $ */ 1/* $OpenBSD: key.c,v 1.78 2008/07/07 23:32:51 stevesk 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
@@ -11,6 +11,7 @@
11 * 11 *
12 * 12 *
13 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 13 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
14 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
14 * 15 *
15 * Redistribution and use in source and binary forms, with or without 16 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions 17 * modification, are permitted provided that the following conditions
@@ -35,9 +36,11 @@
35 36
36#include "includes.h" 37#include "includes.h"
37 38
39#include <sys/param.h>
38#include <sys/types.h> 40#include <sys/types.h>
39 41
40#include <openssl/evp.h> 42#include <openssl/evp.h>
43#include <openbsd-compat/openssl-compat.h>
41 44
42#include <stdarg.h> 45#include <stdarg.h>
43#include <stdio.h> 46#include <stdio.h>
@@ -171,6 +174,7 @@ key_equal(const Key *a, const Key *b)
171 default: 174 default:
172 fatal("key_equal: bad key type %d", a->type); 175 fatal("key_equal: bad key type %d", a->type);
173 } 176 }
177 /* NOTREACHED */
174} 178}
175 179
176u_char* 180u_char*
@@ -294,6 +298,114 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
294 return retval; 298 return retval;
295} 299}
296 300
301/*
302 * Draw an ASCII-Art representing the fingerprint so human brain can
303 * profit from its built-in pattern recognition ability.
304 * This technique is called "random art" and can be found in some
305 * scientific publications like this original paper:
306 *
307 * "Hash Visualization: a New Technique to improve Real-World Security",
308 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
309 * Techniques and E-Commerce (CrypTEC '99)
310 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
311 *
312 * The subject came up in a talk by Dan Kaminsky, too.
313 *
314 * If you see the picture is different, the key is different.
315 * If the picture looks the same, you still know nothing.
316 *
317 * The algorithm used here is a worm crawling over a discrete plane,
318 * leaving a trace (augmenting the field) everywhere it goes.
319 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
320 * makes the respective movement vector be ignored for this turn.
321 * Graphs are not unambiguous, because circles in graphs can be
322 * walked in either direction.
323 */
324
325/*
326 * Field sizes for the random art. Have to be odd, so the starting point
327 * can be in the exact middle of the picture, and FLDBASE should be >=8 .
328 * Else pictures would be too dense, and drawing the frame would
329 * fail, too, because the key type would not fit in anymore.
330 */
331#define FLDBASE 8
332#define FLDSIZE_Y (FLDBASE + 1)
333#define FLDSIZE_X (FLDBASE * 2 + 1)
334static char *
335key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
336{
337 /*
338 * Chars to be used after each other every time the worm
339 * intersects with itself. Matter of taste.
340 */
341 char *augmentation_string = " .o+=*BOX@%&#/^SE";
342 char *retval, *p;
343 u_char field[FLDSIZE_X][FLDSIZE_Y];
344 u_int i, b;
345 int x, y;
346 size_t len = strlen(augmentation_string) - 1;
347
348 retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
349
350 /* initialize field */
351 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
352 x = FLDSIZE_X / 2;
353 y = FLDSIZE_Y / 2;
354
355 /* process raw key */
356 for (i = 0; i < dgst_raw_len; i++) {
357 int input;
358 /* each byte conveys four 2-bit move commands */
359 input = dgst_raw[i];
360 for (b = 0; b < 4; b++) {
361 /* evaluate 2 bit, rest is shifted later */
362 x += (input & 0x1) ? 1 : -1;
363 y += (input & 0x2) ? 1 : -1;
364
365 /* assure we are still in bounds */
366 x = MAX(x, 0);
367 y = MAX(y, 0);
368 x = MIN(x, FLDSIZE_X - 1);
369 y = MIN(y, FLDSIZE_Y - 1);
370
371 /* augment the field */
372 field[x][y]++;
373 input = input >> 2;
374 }
375 }
376
377 /* mark starting point and end point*/
378 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
379 field[x][y] = len;
380
381 /* fill in retval */
382 snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k));
383 p = strchr(retval, '\0');
384
385 /* output upper border */
386 for (i = p - retval - 1; i < FLDSIZE_X; i++)
387 *p++ = '-';
388 *p++ = '+';
389 *p++ = '\n';
390
391 /* output content */
392 for (y = 0; y < FLDSIZE_Y; y++) {
393 *p++ = '|';
394 for (x = 0; x < FLDSIZE_X; x++)
395 *p++ = augmentation_string[MIN(field[x][y], len)];
396 *p++ = '|';
397 *p++ = '\n';
398 }
399
400 /* output lower border */
401 *p++ = '+';
402 for (i = 0; i < FLDSIZE_X; i++)
403 *p++ = '-';
404 *p++ = '+';
405
406 return retval;
407}
408
297char * 409char *
298key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) 410key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
299{ 411{
@@ -311,6 +423,9 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
311 case SSH_FP_BUBBLEBABBLE: 423 case SSH_FP_BUBBLEBABBLE:
312 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 424 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
313 break; 425 break;
426 case SSH_FP_RANDOMART:
427 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k);
428 break;
314 default: 429 default:
315 fatal("key_fingerprint_ex: bad digest representation %d", 430 fatal("key_fingerprint_ex: bad digest representation %d",
316 dgst_rep); 431 dgst_rep);
diff --git a/key.h b/key.h
index 6873dd793..14aac79c2 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: key.h,v 1.27 2008/06/11 21:01:35 grunk 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.
@@ -42,7 +42,8 @@ enum fp_type {
42}; 42};
43enum fp_rep { 43enum fp_rep {
44 SSH_FP_HEX, 44 SSH_FP_HEX,
45 SSH_FP_BUBBLEBABBLE 45 SSH_FP_BUBBLEBABBLE,
46 SSH_FP_RANDOMART
46}; 47};
47 48
48/* key is stored in external hardware */ 49/* key is stored in external hardware */
diff --git a/log.c b/log.c
index fae5b043f..4a8239b93 100644
--- a/log.c
+++ b/log.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: log.c,v 1.40 2007/05/17 07:50:31 djm Exp $ */ 1/* $OpenBSD: log.c,v 1.41 2008/06/10 04:50:25 dtucker 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
@@ -114,6 +114,17 @@ log_facility_number(char *name)
114 return SYSLOG_FACILITY_NOT_SET; 114 return SYSLOG_FACILITY_NOT_SET;
115} 115}
116 116
117const char *
118log_facility_name(SyslogFacility facility)
119{
120 u_int i;
121
122 for (i = 0; log_facilities[i].name; i++)
123 if (log_facilities[i].val == facility)
124 return log_facilities[i].name;
125 return NULL;
126}
127
117LogLevel 128LogLevel
118log_level_number(char *name) 129log_level_number(char *name)
119{ 130{
@@ -126,6 +137,17 @@ log_level_number(char *name)
126 return SYSLOG_LEVEL_NOT_SET; 137 return SYSLOG_LEVEL_NOT_SET;
127} 138}
128 139
140const char *
141log_level_name(LogLevel level)
142{
143 u_int i;
144
145 for (i = 0; log_levels[i].name != NULL; i++)
146 if (log_levels[i].val == level)
147 return log_levels[i].name;
148 return NULL;
149}
150
129/* Error messages that should be logged. */ 151/* Error messages that should be logged. */
130 152
131void 153void
diff --git a/log.h b/log.h
index 7a8c57079..650582791 100644
--- a/log.h
+++ b/log.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: log.h,v 1.15 2006/08/18 09:13:25 deraadt Exp $ */ 1/* $OpenBSD: log.h,v 1.17 2008/06/13 00:12:02 dtucker Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -49,11 +49,15 @@ typedef enum {
49void log_init(char *, LogLevel, SyslogFacility, int); 49void log_init(char *, LogLevel, SyslogFacility, int);
50 50
51SyslogFacility log_facility_number(char *); 51SyslogFacility log_facility_number(char *);
52LogLevel log_level_number(char *); 52const char * log_facility_name(SyslogFacility);
53LogLevel log_level_number(char *);
54const char * log_level_name(LogLevel);
53 55
54void fatal(const char *, ...) __dead __attribute__((format(printf, 1, 2))); 56void fatal(const char *, ...) __attribute__((noreturn))
57 __attribute__((format(printf, 1, 2)));
55void error(const char *, ...) __attribute__((format(printf, 1, 2))); 58void error(const char *, ...) __attribute__((format(printf, 1, 2)));
56void sigdie(const char *, ...) __attribute__((format(printf, 1, 2))); 59void sigdie(const char *, ...) __attribute__((noreturn))
60 __attribute__((format(printf, 1, 2)));
57void logit(const char *, ...) __attribute__((format(printf, 1, 2))); 61void logit(const char *, ...) __attribute__((format(printf, 1, 2)));
58void verbose(const char *, ...) __attribute__((format(printf, 1, 2))); 62void verbose(const char *, ...) __attribute__((format(printf, 1, 2)));
59void debug(const char *, ...) __attribute__((format(printf, 1, 2))); 63void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
@@ -61,5 +65,5 @@ void debug2(const char *, ...) __attribute__((format(printf, 1, 2)));
61void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); 65void debug3(const char *, ...) __attribute__((format(printf, 1, 2)));
62 66
63void do_log(LogLevel, const char *, va_list); 67void do_log(LogLevel, const char *, va_list);
64void cleanup_exit(int) __dead; 68void cleanup_exit(int) __attribute__((noreturn));
65#endif 69#endif
diff --git a/mac.c b/mac.c
index 34464659a..fabc3ed66 100644
--- a/mac.c
+++ b/mac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mac.c,v 1.14 2007/06/07 19:37:34 pvalchev Exp $ */ 1/* $OpenBSD: mac.c,v 1.15 2008/06/13 00:51:47 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -128,7 +128,7 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
128 128
129 if (mac->mac_len > sizeof(m)) 129 if (mac->mac_len > sizeof(m))
130 fatal("mac_compute: mac too long %u %lu", 130 fatal("mac_compute: mac too long %u %lu",
131 mac->mac_len, sizeof(m)); 131 mac->mac_len, (u_long)sizeof(m));
132 132
133 switch (mac->type) { 133 switch (mac->type) {
134 case SSH_EVP: 134 case SSH_EVP:
diff --git a/match.c b/match.c
index e3c993073..238947778 100644
--- a/match.c
+++ b/match.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: match.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: match.c,v 1.27 2008/06/10 23:06:19 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
@@ -183,7 +183,8 @@ match_hostname(const char *host, const char *pattern, u_int len)
183 183
184/* 184/*
185 * returns 0 if we get a negative match for the hostname or the ip 185 * returns 0 if we get a negative match for the hostname or the ip
186 * or if we get no match at all. returns 1 otherwise. 186 * or if we get no match at all. returns -1 on error, or 1 on
187 * successful match.
187 */ 188 */
188int 189int
189match_host_and_ip(const char *host, const char *ipaddr, 190match_host_and_ip(const char *host, const char *ipaddr,
@@ -191,9 +192,12 @@ match_host_and_ip(const char *host, const char *ipaddr,
191{ 192{
192 int mhost, mip; 193 int mhost, mip;
193 194
194 /* negative ipaddr match */ 195 /* error in ipaddr match */
195 if ((mip = match_hostname(ipaddr, patterns, strlen(patterns))) == -1) 196 if ((mip = addr_match_list(ipaddr, patterns)) == -2)
197 return -1;
198 else if (mip == -1) /* negative ip address match */
196 return 0; 199 return 0;
200
197 /* negative hostname match */ 201 /* negative hostname match */
198 if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1) 202 if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1)
199 return 0; 203 return 0;
diff --git a/match.h b/match.h
index d1d538654..18f683070 100644
--- a/match.h
+++ b/match.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: match.h,v 1.13 2006/03/25 22:22:43 djm Exp $ */ 1/* $OpenBSD: match.h,v 1.14 2008/06/10 03:57:27 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -21,4 +21,7 @@ int match_host_and_ip(const char *, const char *, const char *);
21int match_user(const char *, const char *, const char *, const char *); 21int match_user(const char *, const char *, const char *, const char *);
22char *match_list(const char *, const char *, u_int *); 22char *match_list(const char *, const char *, u_int *);
23 23
24/* addrmatch.c */
25int addr_match_list(const char *, const char *);
26
24#endif 27#endif
diff --git a/misc.c b/misc.c
index 625a34368..8b303f16f 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.65 2006/11/23 01:35:11 ray Exp $ */ 1/* $OpenBSD: misc.c,v 1.69 2008/06/13 01:38:23 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -42,6 +42,7 @@
42 42
43#include <errno.h> 43#include <errno.h>
44#include <fcntl.h> 44#include <fcntl.h>
45#include <netdb.h>
45#ifdef HAVE_PATHS_H 46#ifdef HAVE_PATHS_H
46# include <paths.h> 47# include <paths.h>
47#include <pwd.h> 48#include <pwd.h>
@@ -120,6 +121,14 @@ unset_nonblock(int fd)
120 return (0); 121 return (0);
121} 122}
122 123
124const char *
125ssh_gai_strerror(int gaierr)
126{
127 if (gaierr == EAI_SYSTEM)
128 return strerror(errno);
129 return gai_strerror(gaierr);
130}
131
123/* disable nagle on socket */ 132/* disable nagle on socket */
124void 133void
125set_nodelay(int fd) 134set_nodelay(int fd)
@@ -525,7 +534,7 @@ tilde_expand_filename(const char *filename, uid_t uid)
525 if ((pw = getpwnam(user)) == NULL) 534 if ((pw = getpwnam(user)) == NULL)
526 fatal("tilde_expand_filename: No such user %s", user); 535 fatal("tilde_expand_filename: No such user %s", user);
527 } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ 536 } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
528 fatal("tilde_expand_filename: No such uid %d", uid); 537 fatal("tilde_expand_filename: No such uid %ld", (long)uid);
529 538
530 if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret)) 539 if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
531 fatal("tilde_expand_filename: Path too long"); 540 fatal("tilde_expand_filename: Path too long");
@@ -823,3 +832,23 @@ put_u16(void *vp, u_int16_t v)
823 p[0] = (u_char)(v >> 8) & 0xff; 832 p[0] = (u_char)(v >> 8) & 0xff;
824 p[1] = (u_char)v & 0xff; 833 p[1] = (u_char)v & 0xff;
825} 834}
835
836void
837ms_subtract_diff(struct timeval *start, int *ms)
838{
839 struct timeval diff, finish;
840
841 gettimeofday(&finish, NULL);
842 timersub(&finish, start, &diff);
843 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
844}
845
846void
847ms_to_timeval(struct timeval *tv, int ms)
848{
849 if (ms < 0)
850 ms = 0;
851 tv->tv_sec = ms / 1000;
852 tv->tv_usec = (ms % 1000) * 1000;
853}
854
diff --git a/misc.h b/misc.h
index f175b4426..5da170d2f 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.h,v 1.36 2006/08/18 10:27:16 djm Exp $ */ 1/* $OpenBSD: misc.h,v 1.38 2008/06/12 20:38:28 dtucker Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -33,8 +33,11 @@ char *tilde_expand_filename(const char *, uid_t);
33char *percent_expand(const char *, ...) __attribute__((__sentinel__)); 33char *percent_expand(const char *, ...) __attribute__((__sentinel__));
34char *tohex(const void *, size_t); 34char *tohex(const void *, size_t);
35void sanitise_stdfd(void); 35void sanitise_stdfd(void);
36void ms_subtract_diff(struct timeval *, int *);
37void ms_to_timeval(struct timeval *, int);
36 38
37struct passwd *pwcopy(struct passwd *); 39struct passwd *pwcopy(struct passwd *);
40const char *ssh_gai_strerror(int);
38 41
39typedef struct arglist arglist; 42typedef struct arglist arglist;
40struct arglist { 43struct arglist {
diff --git a/moduli b/moduli
index a12de2192..65d2814a6 100644
--- a/moduli
+++ b/moduli
@@ -1,189 +1,174 @@
1# $OpenBSD: moduli,v 1.3 2005/01/24 10:29:06 dtucker Exp $ 1# $OpenBSD: moduli,v 1.4 2008/01/01 08:51:20 dtucker Exp $
2# Time Type Tests Tries Size Generator Modulus 2# Time Type Tests Tries Size Generator Modulus
320040225025212 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7AFFE86A7 320060827013849 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE261778F3
420040225025304 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B01F83CB 420060827013906 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE261CC47B
520040225025357 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B03F2B73 520060827013924 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2621AFA3
620040225025411 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B041C8C7 620060827014045 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26551B8B
720040225025444 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0546E93 720060827014056 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26556A27
820040225025458 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0573767 820060827014115 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE265B7273
920040225025522 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0629E73 920060827014137 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26644D77
1020040225025545 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B06CD95B 1020060827014203 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26717773
1120040225025616 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B07C93A3 1120060827014214 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26722EBB
1220040225025655 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B093C72B 1220060827014312 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26961C8B
1320040225025710 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B096450B 1320060827014407 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26BA7BBF
1420040225025750 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0AF2C83 1420060827014418 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26BAC107
1520040225025830 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0C7F1FF 1520060827014436 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26C05207
1620040225025845 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0CB565B 1620060827014515 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26D48C73
1720040225025858 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0CD8557 1720060827014527 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26D65CD7
1820040225025915 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0D20473 1820060827014538 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26D7096F
1920040225025934 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0D924F7 1920060827014607 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26E3760B
2020040225025952 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0DFD8BB 2020060827014626 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26EAF29F
2120040225030015 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0E8E59F 2120060827014637 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26EBCF4F
2220040225030039 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0F43B0B 2220060827014653 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26F0D6BB
2320040225030104 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0FEB103 2320060827014732 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27088963
2420040225030130 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B10AC3DB 2420060827014835 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27320A73
2520040225030149 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1122527 2520060827014915 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27486FA3
2620040225030214 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B11E494B 2620060827014926 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2748FD9F
2720040225030245 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B12E727B 2720060827014940 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE274BB323
2820040225030319 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1416743 2820060827014956 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE274F8F7F
2920040225030347 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1507F2B 2920060827015028 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE275C008F
3020040225030404 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1560FE3 3020060827015112 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2776D9EF
3120040225030418 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1591CF7 3120060827015134 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27809AA3
3220040225030432 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B15B57FF 3220060827015146 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27826DFB
3320040225030455 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B165D0AF 3320060827015200 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2785363F
3420040225030511 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B169C97F 3420060827015231 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27951F4F
3520040225030551 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B182715B 3520060827015246 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27991903
3620040225030621 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1920737 3620060827015300 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE279C7B37
3720040225030648 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B19FB54B 3720060827015329 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27AB4843
3820040225030718 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1AFAE87 3820060827015347 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27B0F9D7
3920040225030736 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1B5A7AF 3920060827015359 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27B24D5B
4020040225030753 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1BC3C47 4020060827015430 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27C2CE27
4120040225030815 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1C6AF33 4120060827015449 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27CA3BA3
4220040225030831 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1CAD9FB 4220060827015546 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27E90A07
4320040225030902 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1DC6A8F 4320060827015607 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27F116BF
4420040225035226 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844800C47CAB 4420060827015630 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27FBB66F
4520040225035359 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844800D3866B 4520060827015649 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2803E313
4620040225035635 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844800F43DFF 4620060827024302 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AD6C361B
4720040225035846 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448010B4D93 4720060827024350 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AD6F7E93
4820040225040147 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448013094F3 4820060827024537 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AD7DE4BB
4920040225040301 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448013AA0FB 4920060827025000 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6ADB6D4D7
5020040225040619 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480163EC83 5020060827025429 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6ADEF2D8B
5120040225040718 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448016AEB8F 5120060827025612 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6ADFCCB13
5220040225041023 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480190871F 5220060827030138 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AE41E89B
5320040225041328 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844801B5F1B3 5320060827030223 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AE44A263
5420040225041740 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844801ED6FBB 5420060827030555 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AE6FD2A7
5520040225041921 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844801FEC44F 5520060827031244 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AECC68C3
5620040225042229 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802245FF7 5620060827031437 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AEDFB4EB
5720040225042513 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480246F93B 5720060827031602 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AEEB07E7
5820040225042547 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802473F4F 5820060827032434 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AF5B1533
5920040225042707 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480253B03B 5920060827032933 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AF99D5D3
6020040225043111 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480287CD9B 6020060827033028 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AF9CF037
6120040225043513 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802BC32FB 6120060827033120 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFA14BBF
6220040225043609 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802C2125B 6220060827033331 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFB9FD2B
6320040225043847 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802E1B733 6320060827033555 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFD32F8B
6420040225043925 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802E2E963 6420060827033806 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFEBB7DB
6520040225044335 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448031AC423 6520060827034045 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B009C8D3
6620040225045303 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803A10E07 6620060827034214 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0177447
6720040225045443 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803B0EF43 6720060827034316 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B01EFC27
6820040225045518 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803B15033 6820060827034514 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0313F9B
6920040225045923 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803E58317 6920060827035109 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B07D542B
7020040225050120 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803F9EB4F 7020060827035412 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0A3485F
7120040225050333 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448041304B3 7120060827035525 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0AAF3BB
7220040225050524 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804279B2F 7220060827035829 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0CFE04F
7320040225050559 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804281047 7320060827040101 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0E988E7
7420040225050810 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448043F454F 7420060827040504 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B11D001B
7520040225051113 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804672F1F 7520060827040746 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B13A45DF
7620040225051335 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804809CB3 7620060827041350 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B188B89F
7720040225051442 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480489545F 7720060827041513 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B193B2EB
7820040225052303 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804FE918B 7820060827041621 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B19B9807
7920040225062215 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6B9F68B3E7 7920060827041657 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B19C0107
8020040225063823 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6B9FD47307 8020060827041817 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B1A6BE4B
8120040225064402 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6B9FF43C0F 8120060827052122 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C77E8ED3
8220040225065646 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA04740DB 8220060827055248 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8549C07
8320040225065825 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA04B01BF 8320060827055453 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C85B17DF
8420040225070116 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA056DD47 8420060827060456 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C899BBE7
8520040225074027 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA172E1B3 8520060827061203 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8C362B3
8620040225080343 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA217422F 8620060827061433 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8CC69F7
8720040225081159 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA24927DB 8720060827061904 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8E44BC7
8820040225081331 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA24C058B 8820060827062255 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8F6B23F
8920040225082528 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA2993EBF 8920060827063052 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C926C817
9020040225084537 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3242BE3 9020060827063354 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9351ABF
9120040225085012 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA33EF643 9120060827063925 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9541A43
9220040225085829 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3729D77 9220060827064904 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C98CFAE7
9320040225090710 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3AC0143 9320060827070314 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9E30823
9420040225091002 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3B8AE6B 9420060827070806 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9F90C33
9520040225092648 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA42B65D7 9520060827071119 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA04D477
9620040225093120 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA4442793 9620060827072534 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA5A1ADB
9720040225093517 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA459441F 9720060827073212 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA7E88A3
9820040225094409 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA491BE4B 9820060827073641 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA93A193
9920040225095209 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA4C4E437 9920060827073850 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA999B57
10020040225095548 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA4D5D7AB 10020060827080040 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CB21505F
10120040225100531 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA51404EB 10120060827080817 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CB4C2F97
10220040225100644 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5145C87 10220060827083711 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC0FAA7F
10320040225101834 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5609CBB 10320060827084308 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC30FD83
10420040225102317 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA57AC86F 10420060827084830 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC4EFB67
10520040225103220 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5B631A3 10520060827085653 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC8152FB
10620040225103355 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5B98D2F 10620060827090522 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CCB5AE6B
10720040225103756 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5CEBAFB 10720060827092253 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CD252FCB
10820040225104020 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5D77CDF 10820060827095916 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CE117E2F
10920040225104557 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5F6FD9F 10920060827100246 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CE2087CB
11020040225110302 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA66A70DF 11020060827102041 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CE925537
11120040225110515 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA6721A43 11120060827102556 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CEAF2A27
11220040225110913 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA6879A53 11220060827103749 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CEF9826F
11320040225111338 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA69FE2FB 11320060827103917 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CEFBC467
11420040225111911 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA6C04F47 11420060827104611 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CF24A6E3
11520040225112902 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA7007CD3 11520060827130320 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFA80B3F
11620040225143208 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8968A91B 11620060827132001 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFC2F2A3
11720040225144922 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8987DF6B 11720060827132659 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFC83DE3
11820040225150309 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD899E0F8B 11820060827133231 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFCAE263
11920040225161716 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8A3A91CF 11920060827134212 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFD5D943
12020040225163012 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8A4CED2B 12020060827135606 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFEAD4AB
12120040225175457 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8B02C5DB 12120060827142452 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F01CBFBB
12220040225182539 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8B3E9D13 12220060827185212 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F24CFF67
12320040225194030 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8BDE269B 12320060827190158 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F2599507
12420040225201420 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C203553 12420060827202730 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F305315B
12520040225203219 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C40B747 12520060827213252 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F38A5B63
12620040225203908 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C46ED83 12620060827214322 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F3987FC7
12720040225210230 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C72586B 12720060827214825 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F39A3CDB
12820040225212746 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8CA15F2F 12820060827232520 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F46375AB
12920040225214624 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8CC34833 12920060828030405 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F62B17EB
13020040225223007 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8D1B23AB 13020060828043230 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F6E0BB4F
13120040225234913 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8DC36C9B 13120060828081338 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F8A9B0EF
13220040226001353 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8DF174B3 13220060828083613 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F8D164EF
13320040226004101 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8E24518B 13320060828090529 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F906488B
13420040226010652 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8E543397 13420060828100621 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F97FF4CB
13520040226015415 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8EB6152F 13520060828121421 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FA80824B
13620040226022931 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8EFD1773 13620060828141024 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FB659087
13720040226025740 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8F3376D7 13720060828142059 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FB739E8F
13820040226053010 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD90786CE3 13820060828170552 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FCC5CE57
13920040226054156 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD908AC36B 13920060828171327 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FCCCF9D3
14020040226081600 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD91D61A43 14020060828185943 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDA67727
14120040226083039 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD91ED4AE3 14120060828190537 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDAAC673
14220040226092910 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9265F7DB 14220060828191202 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDAFC737
14320040226112913 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD93696533 14320060828192613 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDC50FBB
14420040226115826 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD93A210A3 14420060828193738 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDD6023F
14520040226135326 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD949596D7 14520060828204936 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FE68405F
14620040226145128 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD95096CCF 14620060829063416 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE57DE9222B
14720040226153142 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD95582C7B 14720060829082327 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE57E5385E7
14820040226164905 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD95FACE7B 14820060829092010 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE57E8501A3
14920040226171921 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9633F443 14920060830004204 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5825F180F
15020040226182347 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD96BAC3A7 15020060830013522 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5828DFA2B
15120040226200555 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD97972EFB 15120060830124707 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58555C9EB
15220040226202801 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD97C0B5C3 15220060830180312 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE586989437
15320040226214755 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9868011B 15320060831041205 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5891334BF
15420040226215843 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9876E7FB 15420060831102341 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58A8F8B27
15520040226220422 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD987B4983 15520060831234001 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58DD7278B
15620040226222346 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD989D61D3 15620060901032352 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58EBE93EB
15720040227091438 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC5737ECF 15720060901061345 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58F693A3F
15820040227101541 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC5AE7363 15820060901123055 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE590F80AE7
15920040227160657 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC7295F4F 15920060901191922 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE592994C63
16020040227180410 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC7A46573 16020060901203957 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE592E5D92F
16120040227225950 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC8E6D5E3 16120060901210250 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE592F4A5F3
16220040227233727 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC9079B33 16220060901225047 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5935D124B
16320040228032633 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCA006227 16320060902020657 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5942520CB
16420040228060859 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCAAE6E63 16420060902070624 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59553E03F
16520040228101703 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCBBC54FB 16520060902095300 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE595F6EC6B
16620040228192850 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCE191D13 16620060902113306 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE596599BEF
16720040229084451 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD1804AF3 16720060902142302 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59703582B
16820040229164933 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD3887E07 16820060902210839 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE598A695F7
16920040229210220 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD49457B7 16920060903073325 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59B315E9B
17020040229222958 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD4EA3223 17020060903095626 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59BBD7153
17120040301003324 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD566C79B 17120060903162601 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59D48AEE3
17220040301030228 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD6032D8F
17320040301040042 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD63B1113
17420040301073501 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD71C4A67
17520040301133631 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD8A0BBD3
17620040301165652 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD96E4053
17720040301184021 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD9D662FB
17820040302045553 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDC5FE8E3
17920040302112648 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDDFE9D13
18020040302120026 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDE1A5AD3
18120040302130757 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDE5E4073
18220040302142004 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDEA4AA9B
18320040302145603 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDEC2C32B
18420040302212946 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFE0652EC7
18520040303003544 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFE127CF63
18620040303072925 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFE2D793F3
18720040305011518 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E4CE974B 17220040305011518 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E4CE974B
18820040305043124 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E5050933 17320040305043124 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E5050933
18920040305084728 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E54C7783 17420040305084728 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E54C7783
@@ -198,3 +183,6 @@
19820040319025848 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080FD81741B 18320040319025848 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080FD81741B
19920040323194658 2 6 100 6143 5 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C708105AF04AF 18420040323194658 2 6 100 6143 5 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C708105AF04AF
20020040324041535 2 6 100 6143 5 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C70810643E737 18520040324041535 2 6 100 6143 5 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C70810643E737
18620061002171426 2 6 100 8191 2 D2D64D8CC6FDFA9897C8AE805EA7CB972D7A10F5A268EB5B33B0CCE2C75E480365A49070185D8B316872BAF0F3AAF94498A8E0007A13D574C905441F19D4B0D55A83E2A70C09F7B3E353DEA76F5FEB4191E31F4A52D0BC643B9FD1959BDF8B99C13F245B5D9E8589D6C18A844814486F25A8E189B964A9E72675DDE4D759C901C09F7C24CB3E939B54D2009AE9331446C1EDE5FA9D0A33B36F6A6C9B55E956A94169FBE9C1A24EC9A3E497371F4131F2B1E4FB25A1BB27B23A6661155F37C6EC913E5CB207AD894C2319852C556CA040C6B72DE6E913BCF419E5914507119F771206FAB25B1D6BAD57AFEAF74D807CC576549CD979B0AAC13F5D2B637CCF4A54D2D903A4B29C16B9E8BEE8AD6200D24E4E3E97EB25B2DD13C31AE2A4F27D6EFBFA113F9334F92204FCFFCAA5EBDCCBA986C5B6E665FE71D6654ACA3C8051424133597FD65A18BB2AA24FFDD8B09A8758D984E09BE1F55B16A37B36B058295B1E9942A89D386D4B4DB58C516429248052D97DE42BFC32AB14F13D7F963E86867B8B7245062061C9F315EA94C38FCC0E118373BEFC41D1004CF0FA6D951E20BAC5D2C15F5796163469B88A75FE5F5D2C69C949DA47DAC75D22869F37FAB2490791FA5A5854360EAA13701CEE40EC371797272A12746ABA9CB303224B82F8CCE3F62C0D3EA0D62BF3B2C387E015B1A96A4C4A2A73ADA521B0536B81A536A5119EC559D524BA7F2B25A094A164A4EEBB8ADA886DCBA9647FC4D2D4A91BA0DB32805EDA75B61E09F44BC49862D70B8F28C8E630CD6F0DF245535D79DCD75ECBDE51B29AA6DD3F59736E5028E3AB1E75CFCDA1FF9E6F8D52027A4BC218FC9A9E660BF7EB14D300F4199C04B24725405AFA6535DF0837FEF33C0F8B57B9BDFFB1D956E7B40E822FF40603FB5417523B115FE5864094001CEF2526395C19532F153C4630B95E9835FAC985E1C9DF62188DBA12D5B8BEEB414FFD90AFEDF8F986DF33EF5BC7F7C16ACDC4D40A00822CE17A9724066EED89127195BB9D037CB7FB74AA7178A1A4CBECC5D9F67747AA74156C70E54BABA8641A55B93637385A0D1D56E5220867B5A11ED44CFC405AC238DC39690A966A2DE238FFA1E3B3C859D988DE14916C32AB2A2CB35C57F3609C34F1E8E4B5FAC2F446E0EB78CFD64DD7A3570677D373E8FEC6FF47D5471577D92F22B115D03F302C8CD1A43FCDCEBBA823EE942D7733FF7F78672BEAACCEA279744CC14D60E3912E81A14421989CF5B2C10FD1CDB6CA95E2CA8C574AA6C4F3856602A0D32A9978697752878C0DCB50EF5463EE61C83F776AB9D8098755AF00D2972D3E5E502C39A9CE52C8588472C1D3242CA658290F472D48CB0876752643C2F63CFEB66DF6E93C8BE2404DFA10AB3D8EEF214C371DC0EC29755C086574B1AA92A892B517F6E01056DD5EFEB2437E23100E487E3D4B
18720061005090403 2 6 100 8191 5 D2D64D8CC6FDFA9897C8AE805EA7CB972D7A10F5A268EB5B33B0CCE2C75E480365A49070185D8B316872BAF0F3AAF94498A8E0007A13D574C905441F19D4B0D55A83E2A70C09F7B3E353DEA76F5FEB4191E31F4A52D0BC643B9FD1959BDF8B99C13F245B5D9E8589D6C18A844814486F25A8E189B964A9E72675DDE4D759C901C09F7C24CB3E939B54D2009AE9331446C1EDE5FA9D0A33B36F6A6C9B55E956A94169FBE9C1A24EC9A3E497371F4131F2B1E4FB25A1BB27B23A6661155F37C6EC913E5CB207AD894C2319852C556CA040C6B72DE6E913BCF419E5914507119F771206FAB25B1D6BAD57AFEAF74D807CC576549CD979B0AAC13F5D2B637CCF4A54D2D903A4B29C16B9E8BEE8AD6200D24E4E3E97EB25B2DD13C31AE2A4F27D6EFBFA113F9334F92204FCFFCAA5EBDCCBA986C5B6E665FE71D6654ACA3C8051424133597FD65A18BB2AA24FFDD8B09A8758D984E09BE1F55B16A37B36B058295B1E9942A89D386D4B4DB58C516429248052D97DE42BFC32AB14F13D7F963E86867B8B7245062061C9F315EA94C38FCC0E118373BEFC41D1004CF0FA6D951E20BAC5D2C15F5796163469B88A75FE5F5D2C69C949DA47DAC75D22869F37FAB2490791FA5A5854360EAA13701CEE40EC371797272A12746ABA9CB303224B82F8CCE3F62C0D3EA0D62BF3B2C387E015B1A96A4C4A2A73ADA521B0536B81A536A5119EC559D524BA7F2B25A094A164A4EEBB8ADA886DCBA9647FC4D2D4A91BA0DB32805EDA75B61E09F44BC49862D70B8F28C8E630CD6F0DF245535D79DCD75ECBDE51B29AA6DD3F59736E5028E3AB1E75CFCDA1FF9E6F8D52027A4BC218FC9A9E660BF7EB14D300F4199C04B24725405AFA6535DF0837FEF33C0F8B57B9BDFFB1D956E7B40E822FF40603FB5417523B115FE5864094001CEF2526395C19532F153C4630B95E9835FAC985E1C9DF62188DBA12D5B8BEEB414FFD90AFEDF8F986DF33EF5BC7F7C16ACDC4D40A00822CE17A9724066EED89127195BB9D037CB7FB74AA7178A1A4CBECC5D9F67747AA74156C70E54BABA8641A55B93637385A0D1D56E5220867B5A11ED44CFC405AC238DC39690A966A2DE238FFA1E3B3C859D988DE14916C32AB2A2CB35C57F3609C34F1E8E4B5FAC2F446E0EB78CFD64DD7A3570677D373E8FEC6FF47D5471577D92F22B115D03F302C8CD1A43FCDCEBBA823EE942D7733FF7F78672BEAACCEA279744CC14D60E3912E81A14421989CF5B2C10FD1CDB6CA95E2CA8C574AA6C4F3856602A0D32A9978697752878C0DCB50EF5463EE61C83F776AB9D8098755AF00D2972D3E5E502C39A9CE52C8588472C1D3242CA658290F472D48CB0876752643C2F63CFEB66DF6E93C8BE2404DFA10AB3D8EEF214C371DC0EC29755C086574B1AA92A892B517F6E01056DD5EFEB2437E23100E4A242A2F
18820061005152228 2 6 100 8191 2 D2D64D8CC6FDFA9897C8AE805EA7CB972D7A10F5A268EB5B33B0CCE2C75E480365A49070185D8B316872BAF0F3AAF94498A8E0007A13D574C905441F19D4B0D55A83E2A70C09F7B3E353DEA76F5FEB4191E31F4A52D0BC643B9FD1959BDF8B99C13F245B5D9E8589D6C18A844814486F25A8E189B964A9E72675DDE4D759C901C09F7C24CB3E939B54D2009AE9331446C1EDE5FA9D0A33B36F6A6C9B55E956A94169FBE9C1A24EC9A3E497371F4131F2B1E4FB25A1BB27B23A6661155F37C6EC913E5CB207AD894C2319852C556CA040C6B72DE6E913BCF419E5914507119F771206FAB25B1D6BAD57AFEAF74D807CC576549CD979B0AAC13F5D2B637CCF4A54D2D903A4B29C16B9E8BEE8AD6200D24E4E3E97EB25B2DD13C31AE2A4F27D6EFBFA113F9334F92204FCFFCAA5EBDCCBA986C5B6E665FE71D6654ACA3C8051424133597FD65A18BB2AA24FFDD8B09A8758D984E09BE1F55B16A37B36B058295B1E9942A89D386D4B4DB58C516429248052D97DE42BFC32AB14F13D7F963E86867B8B7245062061C9F315EA94C38FCC0E118373BEFC41D1004CF0FA6D951E20BAC5D2C15F5796163469B88A75FE5F5D2C69C949DA47DAC75D22869F37FAB2490791FA5A5854360EAA13701CEE40EC371797272A12746ABA9CB303224B82F8CCE3F62C0D3EA0D62BF3B2C387E015B1A96A4C4A2A73ADA521B0536B81A536A5119EC559D524BA7F2B25A094A164A4EEBB8ADA886DCBA9647FC4D2D4A91BA0DB32805EDA75B61E09F44BC49862D70B8F28C8E630CD6F0DF245535D79DCD75ECBDE51B29AA6DD3F59736E5028E3AB1E75CFCDA1FF9E6F8D52027A4BC218FC9A9E660BF7EB14D300F4199C04B24725405AFA6535DF0837FEF33C0F8B57B9BDFFB1D956E7B40E822FF40603FB5417523B115FE5864094001CEF2526395C19532F153C4630B95E9835FAC985E1C9DF62188DBA12D5B8BEEB414FFD90AFEDF8F986DF33EF5BC7F7C16ACDC4D40A00822CE17A9724066EED89127195BB9D037CB7FB74AA7178A1A4CBECC5D9F67747AA74156C70E54BABA8641A55B93637385A0D1D56E5220867B5A11ED44CFC405AC238DC39690A966A2DE238FFA1E3B3C859D988DE14916C32AB2A2CB35C57F3609C34F1E8E4B5FAC2F446E0EB78CFD64DD7A3570677D373E8FEC6FF47D5471577D92F22B115D03F302C8CD1A43FCDCEBBA823EE942D7733FF7F78672BEAACCEA279744CC14D60E3912E81A14421989CF5B2C10FD1CDB6CA95E2CA8C574AA6C4F3856602A0D32A9978697752878C0DCB50EF5463EE61C83F776AB9D8098755AF00D2972D3E5E502C39A9CE52C8588472C1D3242CA658290F472D48CB0876752643C2F63CFEB66DF6E93C8BE2404DFA10AB3D8EEF214C371DC0EC29755C086574B1AA92A892B517F6E01056DD5EFEB2437E23100E4A4C3B0B
diff --git a/moduli.0 b/moduli.0
new file mode 100644
index 000000000..55a315fab
--- /dev/null
+++ b/moduli.0
@@ -0,0 +1,72 @@
1MODULI(5) OpenBSD Programmer's Manual MODULI(5)
2
3NAME
4 moduli - Diffie Hellman moduli
5
6DESCRIPTION
7 The /etc/moduli file contains prime numbers and generators for use by
8 sshd(8) in the Diffie-Hellman Group Exchange key exchange method.
9
10 New moduli may be generated with ssh-keygen(1) using a two-step process.
11 An initial candidate generation pass, using ssh-keygen -G, calculates
12 numbers that are likely to be useful. A second primality testing pass,
13 using ssh-keygen -T provides a high degree of assurance that the numbers
14 are prime and are safe for use in Diffie Hellman operations by sshd(8).
15 This moduli format is used as the output from each pass.
16
17 The file consists of newline-separated records, one per modulus, contain-
18 ing seven space separated fields. These fields are as follows:
19
20 timestamp The time that the modulus was last processed as YYYYM-
21 MDDHHMMSS.
22
23 type Decimal number specifying the internal structure of
24 the prime modulus. Supported types are:
25
26 0 Unknown, not tested
27 2 "Safe" prime; (p-1)/2 is also prime.
28 4 Sophie Germain; (p+1)*2 is also prime.
29
30 Moduli candidates initially produced by ssh-keygen(1)
31 are Sophie Germain primes (type 4). Futher primality
32 testing with ssh-keygen(1) produces safe prime moduli
33 (type 2) that are ready for use in sshd(8). Other
34 types are not used by OpenSSH.
35
36 tests Decimal number indicating the type of primality tests
37 that the number has been subjected to represented as a
38 bitmask of the following values:
39
40 0x00 Not tested
41 0x01 Composite number - not prime.
42 0x02 Sieve of Eratosthenes
43 0x04 Probabalistic Miller-Rabin primality tests.
44
45 The ssh-keygen(1) moduli candidate generation uses the
46 Sieve of Eratosthenes (flag 0x02). Subsequent
47 ssh-keygen(1) primality tests are Miller-Rabin tests
48 (flag 0x04).
49
50 trials Decimal number indicating of primaility trials that
51 have been performed on the modulus.
52
53 size Decimal number indicating the size of the prime in
54 bits.
55
56 generator The recommended generator for use with this modulus
57 (hexadecimal).
58
59 modulus The modulus itself in hexadecimal.
60
61 When performing Diffie Hellman Group Exchange, sshd(8) first estimates
62 the size of the modulus required to produce enough Diffie Hellman output
63 to sufficiently key the selected symmetric cipher. sshd(8) then randomly
64 selects a modulus from /etc/moduli that best meets the size requirement.
65
66SEE ALSO
67 ssh-keygen(1), sshd(8),
68
69 Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
70 Protocol, RFC 4419, 2006.
71
72OpenBSD 4.4 June 26, 2008 2
diff --git a/moduli.5 b/moduli.5
new file mode 100644
index 000000000..4a99439cc
--- /dev/null
+++ b/moduli.5
@@ -0,0 +1,124 @@
1.\" $OpenBSD: moduli.5,v 1.12 2008/06/26 05:57:54 djm Exp $
2.\"
3.\" Copyright (c) 2008 Damien Miller <djm@mindrot.org>
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.Dd $Mdocdate: June 26 2008 $
17.Dt MODULI 5
18.Os
19.Sh NAME
20.Nm moduli
21.Nd Diffie Hellman moduli
22.Sh DESCRIPTION
23The
24.Pa /etc/moduli
25file contains prime numbers and generators for use by
26.Xr sshd 8
27in the Diffie-Hellman Group Exchange key exchange method.
28.Pp
29New moduli may be generated with
30.Xr ssh-keygen 1
31using a two-step process.
32An initial
33.Em candidate generation
34pass, using
35.Ic ssh-keygen -G ,
36calculates numbers that are likely to be useful.
37A second
38.Em primality testing
39pass, using
40.Ic ssh-keygen -T
41provides a high degree of assurance that the numbers are prime and are
42safe for use in Diffie Hellman operations by
43.Xr sshd 8 .
44This
45.Nm
46format is used as the output from each pass.
47.Pp
48The file consists of newline-separated records, one per modulus,
49containing seven space separated fields.
50These fields are as follows:
51.Pp
52.Bl -tag -width Description -offset indent
53.It timestamp
54The time that the modulus was last processed as YYYYMMDDHHMMSS.
55.It type
56Decimal number specifying the internal structure of the prime modulus.
57Supported types are:
58.Pp
59.Bl -tag -width 0x00 -compact
60.It 0
61Unknown, not tested
62.It 2
63"Safe" prime; (p-1)/2 is also prime.
64.It 4
65Sophie Germain; (p+1)*2 is also prime.
66.El
67.Pp
68Moduli candidates initially produced by
69.Xr ssh-keygen 1
70are Sophie Germain primes (type 4).
71Futher primality testing with
72.Xr ssh-keygen 1
73produces safe prime moduli (type 2) that are ready for use in
74.Xr sshd 8 .
75Other types are not used by OpenSSH.
76.It tests
77Decimal number indicating the type of primality tests that the number
78has been subjected to represented as a bitmask of the following values:
79.Pp
80.Bl -tag -width 0x00 -compact
81.It 0x00
82Not tested
83.It 0x01
84Composite number - not prime.
85.It 0x02
86Sieve of Eratosthenes
87.It 0x04
88Probabalistic Miller-Rabin primality tests.
89.El
90.Pp
91The
92.Xr ssh-keygen 1
93moduli candidate generation uses the Sieve of Eratosthenes (flag 0x02).
94Subsequent
95.Xr ssh-keygen 1
96primality tests are Miller-Rabin tests (flag 0x04).
97.It trials
98Decimal number indicating of primaility trials that have been performed
99on the modulus.
100.It size
101Decimal number indicating the size of the prime in bits.
102.It generator
103The recommended generator for use with this modulus (hexadecimal).
104.It modulus
105The modulus itself in hexadecimal.
106.El
107.Pp
108When performing Diffie Hellman Group Exchange,
109.Xr sshd 8
110first estimates the size of the modulus required to produce enough
111Diffie Hellman output to sufficiently key the selected symmetric cipher.
112.Xr sshd 8
113then randomly selects a modulus from
114.Fa /etc/moduli
115that best meets the size requirement.
116.Pp
117.Sh SEE ALSO
118.Xr ssh-keygen 1 ,
119.Xr sshd 8 ,
120.Rs
121.%R RFC 4419
122.%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol"
123.%D 2006
124.Re
diff --git a/moduli.c b/moduli.c
index 8fa545daf..f737cb3f5 100644
--- a/moduli.c
+++ b/moduli.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: moduli.c,v 1.20 2007/02/24 03:30:11 ray Exp $ */ 1/* $OpenBSD: moduli.c,v 1.21 2008/06/26 09:19:40 djm Exp $ */
2/* 2/*
3 * Copyright 1994 Phil Karn <karn@qualcomm.com> 3 * Copyright 1994 Phil Karn <karn@qualcomm.com>
4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> 4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
@@ -42,6 +42,7 @@
42#include <sys/types.h> 42#include <sys/types.h>
43 43
44#include <openssl/bn.h> 44#include <openssl/bn.h>
45#include <openssl/dh.h>
45 46
46#include <stdio.h> 47#include <stdio.h>
47#include <stdlib.h> 48#include <stdlib.h>
@@ -50,6 +51,7 @@
50#include <time.h> 51#include <time.h>
51 52
52#include "xmalloc.h" 53#include "xmalloc.h"
54#include "dh.h"
53#include "log.h" 55#include "log.h"
54 56
55/* 57/*
@@ -59,27 +61,6 @@
59/* need line long enough for largest moduli plus headers */ 61/* need line long enough for largest moduli plus headers */
60#define QLINESIZE (100+8192) 62#define QLINESIZE (100+8192)
61 63
62/* Type: decimal.
63 * Specifies the internal structure of the prime modulus.
64 */
65#define QTYPE_UNKNOWN (0)
66#define QTYPE_UNSTRUCTURED (1)
67#define QTYPE_SAFE (2)
68#define QTYPE_SCHNORR (3)
69#define QTYPE_SOPHIE_GERMAIN (4)
70#define QTYPE_STRONG (5)
71
72/* Tests: decimal (bit field).
73 * Specifies the methods used in checking for primality.
74 * Usually, more than one test is used.
75 */
76#define QTEST_UNTESTED (0x00)
77#define QTEST_COMPOSITE (0x01)
78#define QTEST_SIEVE (0x02)
79#define QTEST_MILLER_RABIN (0x04)
80#define QTEST_JACOBI (0x08)
81#define QTEST_ELLIPTIC (0x10)
82
83/* 64/*
84 * Size: decimal. 65 * Size: decimal.
85 * Specifies the number of the most significant bit (0 to M). 66 * Specifies the number of the most significant bit (0 to M).
@@ -434,8 +415,9 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
434 fatal("BN_set_word failed"); 415 fatal("BN_set_word failed");
435 if (BN_add(q, q, largebase) == 0) 416 if (BN_add(q, q, largebase) == 0)
436 fatal("BN_add failed"); 417 fatal("BN_add failed");
437 if (qfileout(out, QTYPE_SOPHIE_GERMAIN, QTEST_SIEVE, 418 if (qfileout(out, MODULI_TYPE_SOPHIE_GERMAIN,
438 largetries, (power - 1) /* MSB */, (0), q) == -1) { 419 MODULI_TESTS_SIEVE, largetries,
420 (power - 1) /* MSB */, (0), q) == -1) {
439 ret = -1; 421 ret = -1;
440 break; 422 break;
441 } 423 }
@@ -507,7 +489,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
507 /* tests */ 489 /* tests */
508 in_tests = strtoul(cp, &cp, 10); 490 in_tests = strtoul(cp, &cp, 10);
509 491
510 if (in_tests & QTEST_COMPOSITE) { 492 if (in_tests & MODULI_TESTS_COMPOSITE) {
511 debug2("%10u: known composite", count_in); 493 debug2("%10u: known composite", count_in);
512 continue; 494 continue;
513 } 495 }
@@ -526,7 +508,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
526 508
527 /* modulus (hex) */ 509 /* modulus (hex) */
528 switch (in_type) { 510 switch (in_type) {
529 case QTYPE_SOPHIE_GERMAIN: 511 case MODULI_TYPE_SOPHIE_GERMAIN:
530 debug2("%10u: (%u) Sophie-Germain", count_in, in_type); 512 debug2("%10u: (%u) Sophie-Germain", count_in, in_type);
531 a = q; 513 a = q;
532 if (BN_hex2bn(&a, cp) == 0) 514 if (BN_hex2bn(&a, cp) == 0)
@@ -539,11 +521,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
539 in_size += 1; 521 in_size += 1;
540 generator_known = 0; 522 generator_known = 0;
541 break; 523 break;
542 case QTYPE_UNSTRUCTURED: 524 case MODULI_TYPE_UNSTRUCTURED:
543 case QTYPE_SAFE: 525 case MODULI_TYPE_SAFE:
544 case QTYPE_SCHNORR: 526 case MODULI_TYPE_SCHNORR:
545 case QTYPE_STRONG: 527 case MODULI_TYPE_STRONG:
546 case QTYPE_UNKNOWN: 528 case MODULI_TYPE_UNKNOWN:
547 debug2("%10u: (%u)", count_in, in_type); 529 debug2("%10u: (%u)", count_in, in_type);
548 a = p; 530 a = p;
549 if (BN_hex2bn(&a, cp) == 0) 531 if (BN_hex2bn(&a, cp) == 0)
@@ -570,7 +552,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
570 continue; 552 continue;
571 } 553 }
572 554
573 if (in_tests & QTEST_MILLER_RABIN) 555 if (in_tests & MODULI_TESTS_MILLER_RABIN)
574 in_tries += trials; 556 in_tries += trials;
575 else 557 else
576 in_tries = trials; 558 in_tries = trials;
@@ -644,7 +626,8 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
644 } 626 }
645 debug("%10u: q is almost certainly prime", count_in); 627 debug("%10u: q is almost certainly prime", count_in);
646 628
647 if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN), 629 if (qfileout(out, MODULI_TYPE_SAFE,
630 in_tests | MODULI_TESTS_MILLER_RABIN,
648 in_tries, in_size, generator_known, p)) { 631 in_tries, in_size, generator_known, p)) {
649 res = -1; 632 res = -1;
650 break; 633 break;
diff --git a/monitor.c b/monitor.c
index 08c7ea3cb..73cf6bc9b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.91 2007/05/17 20:52:13 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.99 2008/07/10 18:08:11 markus 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>
@@ -51,6 +51,7 @@
51 51
52#include <openssl/dh.h> 52#include <openssl/dh.h>
53 53
54#include "openbsd-compat/sys-queue.h"
54#include "xmalloc.h" 55#include "xmalloc.h"
55#include "ssh.h" 56#include "ssh.h"
56#include "key.h" 57#include "key.h"
@@ -643,11 +644,11 @@ mm_answer_pwnamallow(int sock, Buffer *m)
643#endif 644#endif
644 buffer_put_cstring(m, pwent->pw_dir); 645 buffer_put_cstring(m, pwent->pw_dir);
645 buffer_put_cstring(m, pwent->pw_shell); 646 buffer_put_cstring(m, pwent->pw_shell);
647
648 out:
646 buffer_put_string(m, &options, sizeof(options)); 649 buffer_put_string(m, &options, sizeof(options));
647 if (options.banner != NULL) 650 if (options.banner != NULL)
648 buffer_put_cstring(m, options.banner); 651 buffer_put_cstring(m, options.banner);
649
650 out:
651 debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); 652 debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
652 mm_request_send(sock, MONITOR_ANS_PWNAM, m); 653 mm_request_send(sock, MONITOR_ANS_PWNAM, m);
653 654
@@ -1014,6 +1015,8 @@ mm_answer_keyallowed(int sock, Buffer *m)
1014 allowed = options.pubkey_authentication && 1015 allowed = options.pubkey_authentication &&
1015 user_key_allowed(authctxt->pw, key); 1016 user_key_allowed(authctxt->pw, key);
1016 auth_method = "publickey"; 1017 auth_method = "publickey";
1018 if (options.pubkey_authentication && allowed != 1)
1019 auth_clear_options();
1017 break; 1020 break;
1018 case MM_HOSTKEY: 1021 case MM_HOSTKEY:
1019 allowed = options.hostbased_authentication && 1022 allowed = options.hostbased_authentication &&
@@ -1026,6 +1029,8 @@ mm_answer_keyallowed(int sock, Buffer *m)
1026 allowed = options.rhosts_rsa_authentication && 1029 allowed = options.rhosts_rsa_authentication &&
1027 auth_rhosts_rsa_key_allowed(authctxt->pw, 1030 auth_rhosts_rsa_key_allowed(authctxt->pw,
1028 cuser, chost, key); 1031 cuser, chost, key);
1032 if (options.rhosts_rsa_authentication && allowed != 1)
1033 auth_clear_options();
1029 auth_method = "rsa"; 1034 auth_method = "rsa";
1030 break; 1035 break;
1031 default: 1036 default:
@@ -1055,7 +1060,7 @@ mm_answer_keyallowed(int sock, Buffer *m)
1055 } 1060 }
1056 1061
1057 debug3("%s: key %p is %s", 1062 debug3("%s: key %p is %s",
1058 __func__, key, allowed ? "allowed" : "disallowed"); 1063 __func__, key, allowed ? "allowed" : "not allowed");
1059 1064
1060 buffer_clear(m); 1065 buffer_clear(m);
1061 buffer_put_int(m, allowed); 1066 buffer_put_int(m, allowed);
@@ -1272,7 +1277,7 @@ mm_session_close(Session *s)
1272 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); 1277 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
1273 session_pty_cleanup2(s); 1278 session_pty_cleanup2(s);
1274 } 1279 }
1275 s->used = 0; 1280 session_unused(s->self);
1276} 1281}
1277 1282
1278int 1283int
@@ -1314,8 +1319,9 @@ mm_answer_pty(int sock, Buffer *m)
1314 1319
1315 mm_request_send(sock, MONITOR_ANS_PTY, m); 1320 mm_request_send(sock, MONITOR_ANS_PTY, m);
1316 1321
1317 mm_send_fd(sock, s->ptyfd); 1322 if (mm_send_fd(sock, s->ptyfd) == -1 ||
1318 mm_send_fd(sock, s->ttyfd); 1323 mm_send_fd(sock, s->ttyfd) == -1)
1324 fatal("%s: send fds failed", __func__);
1319 1325
1320 /* make sure nothing uses fd 0 */ 1326 /* make sure nothing uses fd 0 */
1321 if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) 1327 if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
@@ -1546,6 +1552,11 @@ mm_answer_term(int sock, Buffer *req)
1546 /* The child is terminating */ 1552 /* The child is terminating */
1547 session_destroy_all(&mm_session_close); 1553 session_destroy_all(&mm_session_close);
1548 1554
1555#ifdef USE_PAM
1556 if (options.use_pam)
1557 sshpam_cleanup();
1558#endif
1559
1549 while (waitpid(pmonitor->m_pid, &status, 0) == -1) 1560 while (waitpid(pmonitor->m_pid, &status, 0) == -1)
1550 if (errno != EINTR) 1561 if (errno != EINTR)
1551 exit(1); 1562 exit(1);
@@ -1694,7 +1705,7 @@ mm_get_keystate(struct monitor *pmonitor)
1694 u_char *blob, *p; 1705 u_char *blob, *p;
1695 u_int bloblen, plen; 1706 u_int bloblen, plen;
1696 u_int32_t seqnr, packets; 1707 u_int32_t seqnr, packets;
1697 u_int64_t blocks; 1708 u_int64_t blocks, bytes;
1698 1709
1699 debug3("%s: Waiting for new keys", __func__); 1710 debug3("%s: Waiting for new keys", __func__);
1700 1711
@@ -1727,11 +1738,13 @@ mm_get_keystate(struct monitor *pmonitor)
1727 seqnr = buffer_get_int(&m); 1738 seqnr = buffer_get_int(&m);
1728 blocks = buffer_get_int64(&m); 1739 blocks = buffer_get_int64(&m);
1729 packets = buffer_get_int(&m); 1740 packets = buffer_get_int(&m);
1730 packet_set_state(MODE_OUT, seqnr, blocks, packets); 1741 bytes = buffer_get_int64(&m);
1742 packet_set_state(MODE_OUT, seqnr, blocks, packets, bytes);
1731 seqnr = buffer_get_int(&m); 1743 seqnr = buffer_get_int(&m);
1732 blocks = buffer_get_int64(&m); 1744 blocks = buffer_get_int64(&m);
1733 packets = buffer_get_int(&m); 1745 packets = buffer_get_int(&m);
1734 packet_set_state(MODE_IN, seqnr, blocks, packets); 1746 bytes = buffer_get_int64(&m);
1747 packet_set_state(MODE_IN, seqnr, blocks, packets, bytes);
1735 1748
1736 skip: 1749 skip:
1737 /* Get the key context */ 1750 /* Get the key context */
diff --git a/monitor_fdpass.c b/monitor_fdpass.c
index 9f8e9cd55..cab538bc9 100644
--- a/monitor_fdpass.c
+++ b/monitor_fdpass.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_fdpass.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: monitor_fdpass.c,v 1.17 2008/03/24 16:11:07 deraadt Exp $ */
2/* 2/*
3 * Copyright 2001 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2001 Niels Provos <provos@citi.umich.edu>
4 * All rights reserved. 4 * All rights reserved.
@@ -40,7 +40,7 @@
40#include "log.h" 40#include "log.h"
41#include "monitor_fdpass.h" 41#include "monitor_fdpass.h"
42 42
43void 43int
44mm_send_fd(int sock, int fd) 44mm_send_fd(int sock, int fd)
45{ 45{
46#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) 46#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
@@ -49,7 +49,11 @@ mm_send_fd(int sock, int fd)
49 char ch = '\0'; 49 char ch = '\0';
50 ssize_t n; 50 ssize_t n;
51#ifndef HAVE_ACCRIGHTS_IN_MSGHDR 51#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
52 char tmp[CMSG_SPACE(sizeof(int))]; 52 union {
53 struct cmsghdr hdr;
54 char tmp[CMSG_SPACE(sizeof(int))];
55 char buf[CMSG_SPACE(sizeof(int))];
56 } cmsgbuf;
53 struct cmsghdr *cmsg; 57 struct cmsghdr *cmsg;
54#endif 58#endif
55 59
@@ -58,8 +62,8 @@ mm_send_fd(int sock, int fd)
58 msg.msg_accrights = (caddr_t)&fd; 62 msg.msg_accrights = (caddr_t)&fd;
59 msg.msg_accrightslen = sizeof(fd); 63 msg.msg_accrightslen = sizeof(fd);
60#else 64#else
61 msg.msg_control = (caddr_t)tmp; 65 msg.msg_control = (caddr_t)&cmsgbuf.buf;
62 msg.msg_controllen = CMSG_LEN(sizeof(int)); 66 msg.msg_controllen = sizeof(cmsgbuf.buf);
63 cmsg = CMSG_FIRSTHDR(&msg); 67 cmsg = CMSG_FIRSTHDR(&msg);
64 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 68 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
65 cmsg->cmsg_level = SOL_SOCKET; 69 cmsg->cmsg_level = SOL_SOCKET;
@@ -72,15 +76,21 @@ mm_send_fd(int sock, int fd)
72 msg.msg_iov = &vec; 76 msg.msg_iov = &vec;
73 msg.msg_iovlen = 1; 77 msg.msg_iovlen = 1;
74 78
75 if ((n = sendmsg(sock, &msg, 0)) == -1) 79 if ((n = sendmsg(sock, &msg, 0)) == -1) {
76 fatal("%s: sendmsg(%d): %s", __func__, fd, 80 error("%s: sendmsg(%d): %s", __func__, fd,
77 strerror(errno)); 81 strerror(errno));
78 if (n != 1) 82 return -1;
79 fatal("%s: sendmsg: expected sent 1 got %ld", 83 }
84
85 if (n != 1) {
86 error("%s: sendmsg: expected sent 1 got %ld",
80 __func__, (long)n); 87 __func__, (long)n);
88 return -1;
89 }
90 return 0;
81#else 91#else
82 fatal("%s: UsePrivilegeSeparation=yes not supported", 92 error("%s: file descriptor passing not supported", __func__);
83 __func__); 93 return -1;
84#endif 94#endif
85} 95}
86 96
@@ -94,7 +104,10 @@ mm_receive_fd(int sock)
94 char ch; 104 char ch;
95 int fd; 105 int fd;
96#ifndef HAVE_ACCRIGHTS_IN_MSGHDR 106#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
97 char tmp[CMSG_SPACE(sizeof(int))]; 107 union {
108 struct cmsghdr hdr;
109 char buf[CMSG_SPACE(sizeof(int))];
110 } cmsgbuf;
98 struct cmsghdr *cmsg; 111 struct cmsghdr *cmsg;
99#endif 112#endif
100 113
@@ -107,33 +120,43 @@ mm_receive_fd(int sock)
107 msg.msg_accrights = (caddr_t)&fd; 120 msg.msg_accrights = (caddr_t)&fd;
108 msg.msg_accrightslen = sizeof(fd); 121 msg.msg_accrightslen = sizeof(fd);
109#else 122#else
110 msg.msg_control = tmp; 123 msg.msg_control = &cmsgbuf.buf;
111 msg.msg_controllen = sizeof(tmp); 124 msg.msg_controllen = sizeof(cmsgbuf.buf);
112#endif 125#endif
113 126
114 if ((n = recvmsg(sock, &msg, 0)) == -1) 127 if ((n = recvmsg(sock, &msg, 0)) == -1) {
115 fatal("%s: recvmsg: %s", __func__, strerror(errno)); 128 error("%s: recvmsg: %s", __func__, strerror(errno));
116 if (n != 1) 129 return -1;
117 fatal("%s: recvmsg: expected received 1 got %ld", 130 }
131 if (n != 1) {
132 error("%s: recvmsg: expected received 1 got %ld",
118 __func__, (long)n); 133 __func__, (long)n);
134 return -1;
135 }
119 136
120#ifdef HAVE_ACCRIGHTS_IN_MSGHDR 137#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
121 if (msg.msg_accrightslen != sizeof(fd)) 138 if (msg.msg_accrightslen != sizeof(fd)) {
122 fatal("%s: no fd", __func__); 139 error("%s: no fd", __func__);
140 return -1;
141 }
123#else 142#else
124 cmsg = CMSG_FIRSTHDR(&msg); 143 cmsg = CMSG_FIRSTHDR(&msg);
125 if (cmsg == NULL) 144 if (cmsg == NULL) {
126 fatal("%s: no message header", __func__); 145 error("%s: no message header", __func__);
146 return -1;
147 }
127#ifndef BROKEN_CMSG_TYPE 148#ifndef BROKEN_CMSG_TYPE
128 if (cmsg->cmsg_type != SCM_RIGHTS) 149 if (cmsg->cmsg_type != SCM_RIGHTS) {
129 fatal("%s: expected type %d got %d", __func__, 150 error("%s: expected type %d got %d", __func__,
130 SCM_RIGHTS, cmsg->cmsg_type); 151 SCM_RIGHTS, cmsg->cmsg_type);
152 return -1;
153 }
131#endif 154#endif
132 fd = (*(int *)CMSG_DATA(cmsg)); 155 fd = (*(int *)CMSG_DATA(cmsg));
133#endif 156#endif
134 return fd; 157 return fd;
135#else 158#else
136 fatal("%s: UsePrivilegeSeparation=yes not supported", 159 error("%s: file descriptor passing not supported", __func__);
137 __func__); 160 return -1;
138#endif 161#endif
139} 162}
diff --git a/monitor_fdpass.h b/monitor_fdpass.h
index 12c67ec2d..a4b1f6358 100644
--- a/monitor_fdpass.h
+++ b/monitor_fdpass.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_fdpass.h,v 1.3 2006/03/25 22:22:43 djm Exp $ */ 1/* $OpenBSD: monitor_fdpass.h,v 1.4 2007/09/04 03:21:03 djm Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -28,7 +28,7 @@
28#ifndef _MM_FDPASS_H_ 28#ifndef _MM_FDPASS_H_
29#define _MM_FDPASS_H_ 29#define _MM_FDPASS_H_
30 30
31void mm_send_fd(int, int); 31int mm_send_fd(int, int);
32int mm_receive_fd(int); 32int mm_receive_fd(int);
33 33
34#endif /* _MM_FDPASS_H_ */ 34#endif /* _MM_FDPASS_H_ */
diff --git a/monitor_mm.h b/monitor_mm.h
index 36a07a06d..c890f7709 100644
--- a/monitor_mm.h
+++ b/monitor_mm.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_mm.h,v 1.4 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: monitor_mm.h,v 1.5 2008/04/29 11:20:31 otto Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -41,9 +41,6 @@ struct mm_master {
41 size_t size; 41 size_t size;
42 42
43 struct mm_master *mmalloc; /* Used to completely share */ 43 struct mm_master *mmalloc; /* Used to completely share */
44
45 int write; /* used to writing to other party */
46 int read; /* used for reading from other party */
47}; 44};
48 45
49RB_PROTOTYPE(mmtree, mm_share, next, mm_compare) 46RB_PROTOTYPE(mmtree, mm_share, next, mm_compare)
diff --git a/monitor_wrap.c b/monitor_wrap.c
index edf2814e5..40463d078 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.57 2007/06/07 19:37:34 pvalchev Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.63 2008/07/10 18:08:11 markus 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>
@@ -41,6 +41,7 @@
41#include <openssl/bn.h> 41#include <openssl/bn.h>
42#include <openssl/dh.h> 42#include <openssl/dh.h>
43 43
44#include "openbsd-compat/sys-queue.h"
44#include "xmalloc.h" 45#include "xmalloc.h"
45#include "ssh.h" 46#include "ssh.h"
46#include "dh.h" 47#include "dh.h"
@@ -222,8 +223,8 @@ mm_getpwnamallow(const char *username)
222 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 223 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
223 224
224 if (buffer_get_char(&m) == 0) { 225 if (buffer_get_char(&m) == 0) {
225 buffer_free(&m); 226 pw = NULL;
226 return (NULL); 227 goto out;
227 } 228 }
228 pw = buffer_get_string(&m, &len); 229 pw = buffer_get_string(&m, &len);
229 if (len != sizeof(struct passwd)) 230 if (len != sizeof(struct passwd))
@@ -237,6 +238,7 @@ mm_getpwnamallow(const char *username)
237 pw->pw_dir = buffer_get_string(&m, NULL); 238 pw->pw_dir = buffer_get_string(&m, NULL);
238 pw->pw_shell = buffer_get_string(&m, NULL); 239 pw->pw_shell = buffer_get_string(&m, NULL);
239 240
241out:
240 /* copy options block as a Match directive may have changed some */ 242 /* copy options block as a Match directive may have changed some */
241 newopts = buffer_get_string(&m, &len); 243 newopts = buffer_get_string(&m, &len);
242 if (len != sizeof(*newopts)) 244 if (len != sizeof(*newopts))
@@ -571,7 +573,7 @@ mm_send_keystate(struct monitor *monitor)
571 u_char *blob, *p; 573 u_char *blob, *p;
572 u_int bloblen, plen; 574 u_int bloblen, plen;
573 u_int32_t seqnr, packets; 575 u_int32_t seqnr, packets;
574 u_int64_t blocks; 576 u_int64_t blocks, bytes;
575 577
576 buffer_init(&m); 578 buffer_init(&m);
577 579
@@ -620,14 +622,16 @@ mm_send_keystate(struct monitor *monitor)
620 buffer_put_string(&m, blob, bloblen); 622 buffer_put_string(&m, blob, bloblen);
621 xfree(blob); 623 xfree(blob);
622 624
623 packet_get_state(MODE_OUT, &seqnr, &blocks, &packets); 625 packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes);
624 buffer_put_int(&m, seqnr); 626 buffer_put_int(&m, seqnr);
625 buffer_put_int64(&m, blocks); 627 buffer_put_int64(&m, blocks);
626 buffer_put_int(&m, packets); 628 buffer_put_int(&m, packets);
627 packet_get_state(MODE_IN, &seqnr, &blocks, &packets); 629 buffer_put_int64(&m, bytes);
630 packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes);
628 buffer_put_int(&m, seqnr); 631 buffer_put_int(&m, seqnr);
629 buffer_put_int64(&m, blocks); 632 buffer_put_int64(&m, blocks);
630 buffer_put_int(&m, packets); 633 buffer_put_int(&m, packets);
634 buffer_put_int64(&m, bytes);
631 635
632 debug3("%s: New keys have been sent", __func__); 636 debug3("%s: New keys have been sent", __func__);
633 skip: 637 skip:
@@ -664,7 +668,20 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
664{ 668{
665 Buffer m; 669 Buffer m;
666 char *p, *msg; 670 char *p, *msg;
667 int success = 0; 671 int success = 0, tmp1 = -1, tmp2 = -1;
672
673 /* Kludge: ensure there are fds free to receive the pty/tty */
674 if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
675 (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
676 error("%s: cannot allocate fds for pty", __func__);
677 if (tmp1 > 0)
678 close(tmp1);
679 if (tmp2 > 0)
680 close(tmp2);
681 return 0;
682 }
683 close(tmp1);
684 close(tmp2);
668 685
669 buffer_init(&m); 686 buffer_init(&m);
670 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 687 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
@@ -688,8 +705,9 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
688 buffer_append(&loginmsg, msg, strlen(msg)); 705 buffer_append(&loginmsg, msg, strlen(msg));
689 xfree(msg); 706 xfree(msg);
690 707
691 *ptyfd = mm_receive_fd(pmonitor->m_recvfd); 708 if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
692 *ttyfd = mm_receive_fd(pmonitor->m_recvfd); 709 (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
710 fatal("%s: receive fds failed", __func__);
693 711
694 /* Success */ 712 /* Success */
695 return (1); 713 return (1);
@@ -708,8 +726,9 @@ mm_session_pty_cleanup2(Session *s)
708 buffer_free(&m); 726 buffer_free(&m);
709 727
710 /* closed dup'ed master */ 728 /* closed dup'ed master */
711 if (close(s->ptymaster) < 0) 729 if (s->ptymaster != -1 && close(s->ptymaster) < 0)
712 error("close(s->ptymaster): %s", strerror(errno)); 730 error("close(s->ptymaster/%d): %s",
731 s->ptymaster, strerror(errno));
713 732
714 /* unlink pty from session */ 733 /* unlink pty from session */
715 s->ttyfd = -1; 734 s->ttyfd = -1;
diff --git a/mux.c b/mux.c
new file mode 100644
index 000000000..79f83768b
--- /dev/null
+++ b/mux.c
@@ -0,0 +1,728 @@
1/* $OpenBSD: mux.c,v 1.7 2008/06/13 17:21:20 dtucker Exp $ */
2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
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/* ssh session multiplexing support */
19
20#include "includes.h"
21
22/*
23 * TODO:
24 * 1. partial reads in muxserver_accept_control (maybe make channels
25 * from accepted connections)
26 * 2. Better signalling from master to slave, especially passing of
27 * error messages
28 * 3. Better fall-back from mux slave error to new connection.
29 * 3. Add/delete forwardings via slave
30 * 4. ExitOnForwardingFailure (after #3 obviously)
31 * 5. Maybe extension mechanisms for multi-X11/multi-agent forwarding
32 * 6. Document the mux mini-protocol somewhere.
33 * 7. Support ~^Z in mux slaves.
34 * 8. Inspect or control sessions in master.
35 * 9. If we ever support the "signal" channel request, send signals on
36 * sessions in master.
37 */
38
39#include <sys/types.h>
40#include <sys/param.h>
41#include <sys/stat.h>
42#include <sys/socket.h>
43#include <sys/un.h>
44
45#include <errno.h>
46#include <fcntl.h>
47#include <signal.h>
48#include <stdarg.h>
49#include <stddef.h>
50#include <stdlib.h>
51#include <stdio.h>
52#include <string.h>
53#include <unistd.h>
54#ifdef HAVE_PATHS_H
55#include <paths.h>
56#endif
57
58#ifdef HAVE_UTIL_H
59# include <util.h>
60#endif
61
62#ifdef HAVE_LIBUTIL_H
63# include <libutil.h>
64#endif
65
66#include "openbsd-compat/sys-queue.h"
67#include "xmalloc.h"
68#include "log.h"
69#include "ssh.h"
70#include "pathnames.h"
71#include "misc.h"
72#include "match.h"
73#include "buffer.h"
74#include "channels.h"
75#include "msg.h"
76#include "packet.h"
77#include "monitor_fdpass.h"
78#include "sshpty.h"
79#include "key.h"
80#include "readconf.h"
81#include "clientloop.h"
82
83/* from ssh.c */
84extern int tty_flag;
85extern Options options;
86extern int stdin_null_flag;
87extern char *host;
88int subsystem_flag;
89extern Buffer command;
90
91/* Context for session open confirmation callback */
92struct mux_session_confirm_ctx {
93 int want_tty;
94 int want_subsys;
95 int want_x_fwd;
96 int want_agent_fwd;
97 Buffer cmd;
98 char *term;
99 struct termios tio;
100 char **env;
101};
102
103/* fd to control socket */
104int muxserver_sock = -1;
105
106/* Multiplexing control command */
107u_int muxclient_command = 0;
108
109/* Set when signalled. */
110static volatile sig_atomic_t muxclient_terminate = 0;
111
112/* PID of multiplex server */
113static u_int muxserver_pid = 0;
114
115
116/* ** Multiplexing master support */
117
118/* Prepare a mux master to listen on a Unix domain socket. */
119void
120muxserver_listen(void)
121{
122 struct sockaddr_un addr;
123 mode_t old_umask;
124 int addr_len;
125
126 if (options.control_path == NULL ||
127 options.control_master == SSHCTL_MASTER_NO)
128 return;
129
130 debug("setting up multiplex master socket");
131
132 memset(&addr, '\0', sizeof(addr));
133 addr.sun_family = AF_UNIX;
134 addr_len = offsetof(struct sockaddr_un, sun_path) +
135 strlen(options.control_path) + 1;
136
137 if (strlcpy(addr.sun_path, options.control_path,
138 sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
139 fatal("ControlPath too long");
140
141 if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
142 fatal("%s socket(): %s", __func__, strerror(errno));
143
144 old_umask = umask(0177);
145 if (bind(muxserver_sock, (struct sockaddr *)&addr, addr_len) == -1) {
146 muxserver_sock = -1;
147 if (errno == EINVAL || errno == EADDRINUSE) {
148 error("ControlSocket %s already exists, "
149 "disabling multiplexing", options.control_path);
150 close(muxserver_sock);
151 muxserver_sock = -1;
152 xfree(options.control_path);
153 options.control_path = NULL;
154 options.control_master = SSHCTL_MASTER_NO;
155 return;
156 } else
157 fatal("%s bind(): %s", __func__, strerror(errno));
158 }
159 umask(old_umask);
160
161 if (listen(muxserver_sock, 64) == -1)
162 fatal("%s listen(): %s", __func__, strerror(errno));
163
164 set_nonblock(muxserver_sock);
165}
166
167/* Callback on open confirmation in mux master for a mux client session. */
168static void
169mux_session_confirm(int id, void *arg)
170{
171 struct mux_session_confirm_ctx *cctx = arg;
172 const char *display;
173 Channel *c;
174 int i;
175
176 if (cctx == NULL)
177 fatal("%s: cctx == NULL", __func__);
178 if ((c = channel_lookup(id)) == NULL)
179 fatal("%s: no channel for id %d", __func__, id);
180
181 display = getenv("DISPLAY");
182 if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
183 char *proto, *data;
184 /* Get reasonable local authentication information. */
185 client_x11_get_proto(display, options.xauth_location,
186 options.forward_x11_trusted, &proto, &data);
187 /* Request forwarding with authentication spoofing. */
188 debug("Requesting X11 forwarding with authentication spoofing.");
189 x11_request_forwarding_with_spoofing(id, display, proto, data);
190 /* XXX wait for reply */
191 }
192
193 if (cctx->want_agent_fwd && options.forward_agent) {
194 debug("Requesting authentication agent forwarding.");
195 channel_request_start(id, "auth-agent-req@openssh.com", 0);
196 packet_send();
197 }
198
199 client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
200 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
201
202 c->open_confirm_ctx = NULL;
203 buffer_free(&cctx->cmd);
204 xfree(cctx->term);
205 if (cctx->env != NULL) {
206 for (i = 0; cctx->env[i] != NULL; i++)
207 xfree(cctx->env[i]);
208 xfree(cctx->env);
209 }
210 xfree(cctx);
211}
212
213/*
214 * Accept a connection on the mux master socket and process the
215 * client's request. Returns flag indicating whether mux master should
216 * begin graceful close.
217 */
218int
219muxserver_accept_control(void)
220{
221 Buffer m;
222 Channel *c;
223 int client_fd, new_fd[3], ver, allowed, window, packetmax;
224 socklen_t addrlen;
225 struct sockaddr_storage addr;
226 struct mux_session_confirm_ctx *cctx;
227 char *cmd;
228 u_int i, j, len, env_len, mux_command, flags, escape_char;
229 uid_t euid;
230 gid_t egid;
231 int start_close = 0;
232
233 /*
234 * Accept connection on control socket
235 */
236 memset(&addr, 0, sizeof(addr));
237 addrlen = sizeof(addr);
238 if ((client_fd = accept(muxserver_sock,
239 (struct sockaddr*)&addr, &addrlen)) == -1) {
240 error("%s accept: %s", __func__, strerror(errno));
241 return 0;
242 }
243
244 if (getpeereid(client_fd, &euid, &egid) < 0) {
245 error("%s getpeereid failed: %s", __func__, strerror(errno));
246 close(client_fd);
247 return 0;
248 }
249 if ((euid != 0) && (getuid() != euid)) {
250 error("control mode uid mismatch: peer euid %u != uid %u",
251 (u_int) euid, (u_int) getuid());
252 close(client_fd);
253 return 0;
254 }
255
256 /* XXX handle asynchronously */
257 unset_nonblock(client_fd);
258
259 /* Read command */
260 buffer_init(&m);
261 if (ssh_msg_recv(client_fd, &m) == -1) {
262 error("%s: client msg_recv failed", __func__);
263 close(client_fd);
264 buffer_free(&m);
265 return 0;
266 }
267 if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
268 error("%s: wrong client version %d", __func__, ver);
269 buffer_free(&m);
270 close(client_fd);
271 return 0;
272 }
273
274 allowed = 1;
275 mux_command = buffer_get_int(&m);
276 flags = buffer_get_int(&m);
277
278 buffer_clear(&m);
279
280 switch (mux_command) {
281 case SSHMUX_COMMAND_OPEN:
282 if (options.control_master == SSHCTL_MASTER_ASK ||
283 options.control_master == SSHCTL_MASTER_AUTO_ASK)
284 allowed = ask_permission("Allow shared connection "
285 "to %s? ", host);
286 /* continue below */
287 break;
288 case SSHMUX_COMMAND_TERMINATE:
289 if (options.control_master == SSHCTL_MASTER_ASK ||
290 options.control_master == SSHCTL_MASTER_AUTO_ASK)
291 allowed = ask_permission("Terminate shared connection "
292 "to %s? ", host);
293 if (allowed)
294 start_close = 1;
295 /* FALLTHROUGH */
296 case SSHMUX_COMMAND_ALIVE_CHECK:
297 /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
298 buffer_clear(&m);
299 buffer_put_int(&m, allowed);
300 buffer_put_int(&m, getpid());
301 if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
302 error("%s: client msg_send failed", __func__);
303 close(client_fd);
304 buffer_free(&m);
305 return start_close;
306 }
307 buffer_free(&m);
308 close(client_fd);
309 return start_close;
310 default:
311 error("Unsupported command %d", mux_command);
312 buffer_free(&m);
313 close(client_fd);
314 return 0;
315 }
316
317 /* Reply for SSHMUX_COMMAND_OPEN */
318 buffer_clear(&m);
319 buffer_put_int(&m, allowed);
320 buffer_put_int(&m, getpid());
321 if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
322 error("%s: client msg_send failed", __func__);
323 close(client_fd);
324 buffer_free(&m);
325 return 0;
326 }
327
328 if (!allowed) {
329 error("Refused control connection");
330 close(client_fd);
331 buffer_free(&m);
332 return 0;
333 }
334
335 buffer_clear(&m);
336 if (ssh_msg_recv(client_fd, &m) == -1) {
337 error("%s: client msg_recv failed", __func__);
338 close(client_fd);
339 buffer_free(&m);
340 return 0;
341 }
342 if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
343 error("%s: wrong client version %d", __func__, ver);
344 buffer_free(&m);
345 close(client_fd);
346 return 0;
347 }
348
349 cctx = xcalloc(1, sizeof(*cctx));
350 cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
351 cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
352 cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
353 cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
354 cctx->term = buffer_get_string(&m, &len);
355 escape_char = buffer_get_int(&m);
356
357 cmd = buffer_get_string(&m, &len);
358 buffer_init(&cctx->cmd);
359 buffer_append(&cctx->cmd, cmd, strlen(cmd));
360
361 env_len = buffer_get_int(&m);
362 env_len = MIN(env_len, 4096);
363 debug3("%s: receiving %d env vars", __func__, env_len);
364 if (env_len != 0) {
365 cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env));
366 for (i = 0; i < env_len; i++)
367 cctx->env[i] = buffer_get_string(&m, &len);
368 cctx->env[i] = NULL;
369 }
370
371 debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__,
372 cctx->want_tty, cctx->want_subsys, cmd);
373 xfree(cmd);
374
375 /* Gather fds from client */
376 for(i = 0; i < 3; i++) {
377 if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) {
378 error("%s: failed to receive fd %d from slave",
379 __func__, i);
380 for (j = 0; j < i; j++)
381 close(new_fd[j]);
382 for (j = 0; j < env_len; j++)
383 xfree(cctx->env[j]);
384 if (env_len > 0)
385 xfree(cctx->env);
386 xfree(cctx->term);
387 buffer_free(&cctx->cmd);
388 close(client_fd);
389 xfree(cctx);
390 return 0;
391 }
392 }
393
394 debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
395 new_fd[0], new_fd[1], new_fd[2]);
396
397 /* Try to pick up ttymodes from client before it goes raw */
398 if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
399 error("%s: tcgetattr: %s", __func__, strerror(errno));
400
401 /* This roundtrip is just for synchronisation of ttymodes */
402 buffer_clear(&m);
403 if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
404 error("%s: client msg_send failed", __func__);
405 close(client_fd);
406 close(new_fd[0]);
407 close(new_fd[1]);
408 close(new_fd[2]);
409 buffer_free(&m);
410 xfree(cctx->term);
411 if (env_len != 0) {
412 for (i = 0; i < env_len; i++)
413 xfree(cctx->env[i]);
414 xfree(cctx->env);
415 }
416 return 0;
417 }
418 buffer_free(&m);
419
420 /* enable nonblocking unless tty */
421 if (!isatty(new_fd[0]))
422 set_nonblock(new_fd[0]);
423 if (!isatty(new_fd[1]))
424 set_nonblock(new_fd[1]);
425 if (!isatty(new_fd[2]))
426 set_nonblock(new_fd[2]);
427
428 set_nonblock(client_fd);
429
430 window = CHAN_SES_WINDOW_DEFAULT;
431 packetmax = CHAN_SES_PACKET_DEFAULT;
432 if (cctx->want_tty) {
433 window >>= 1;
434 packetmax >>= 1;
435 }
436
437 c = channel_new("session", SSH_CHANNEL_OPENING,
438 new_fd[0], new_fd[1], new_fd[2], window, packetmax,
439 CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
440
441 c->ctl_fd = client_fd;
442 if (cctx->want_tty && escape_char != 0xffffffff) {
443 channel_register_filter(c->self,
444 client_simple_escape_filter, NULL,
445 client_filter_cleanup,
446 client_new_escape_filter_ctx((int)escape_char));
447 }
448
449 debug3("%s: channel_new: %d", __func__, c->self);
450
451 channel_send_open(c->self);
452 channel_register_open_confirm(c->self, mux_session_confirm, cctx);
453 return 0;
454}
455
456/* ** Multiplexing client support */
457
458/* Exit signal handler */
459static void
460control_client_sighandler(int signo)
461{
462 muxclient_terminate = signo;
463}
464
465/*
466 * Relay signal handler - used to pass some signals from mux client to
467 * mux master.
468 */
469static void
470control_client_sigrelay(int signo)
471{
472 int save_errno = errno;
473
474 if (muxserver_pid > 1)
475 kill(muxserver_pid, signo);
476
477 errno = save_errno;
478}
479
480/* Check mux client environment variables before passing them to mux master. */
481static int
482env_permitted(char *env)
483{
484 int i, ret;
485 char name[1024], *cp;
486
487 if ((cp = strchr(env, '=')) == NULL || cp == env)
488 return (0);
489 ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
490 if (ret <= 0 || (size_t)ret >= sizeof(name))
491 fatal("env_permitted: name '%.100s...' too long", env);
492
493 for (i = 0; i < options.num_send_env; i++)
494 if (match_pattern(name, options.send_env[i]))
495 return (1);
496
497 return (0);
498}
499
500/* Multiplex client main loop. */
501void
502muxclient(const char *path)
503{
504 struct sockaddr_un addr;
505 int i, r, fd, sock, exitval[2], num_env, addr_len;
506 Buffer m;
507 char *term;
508 extern char **environ;
509 u_int allowed, flags;
510
511 if (muxclient_command == 0)
512 muxclient_command = SSHMUX_COMMAND_OPEN;
513
514 switch (options.control_master) {
515 case SSHCTL_MASTER_AUTO:
516 case SSHCTL_MASTER_AUTO_ASK:
517 debug("auto-mux: Trying existing master");
518 /* FALLTHROUGH */
519 case SSHCTL_MASTER_NO:
520 break;
521 default:
522 return;
523 }
524
525 memset(&addr, '\0', sizeof(addr));
526 addr.sun_family = AF_UNIX;
527 addr_len = offsetof(struct sockaddr_un, sun_path) +
528 strlen(path) + 1;
529
530 if (strlcpy(addr.sun_path, path,
531 sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
532 fatal("ControlPath too long");
533
534 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
535 fatal("%s socket(): %s", __func__, strerror(errno));
536
537 if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
538 if (muxclient_command != SSHMUX_COMMAND_OPEN) {
539 fatal("Control socket connect(%.100s): %s", path,
540 strerror(errno));
541 }
542 if (errno == ENOENT)
543 debug("Control socket \"%.100s\" does not exist", path);
544 else {
545 error("Control socket connect(%.100s): %s", path,
546 strerror(errno));
547 }
548 close(sock);
549 return;
550 }
551
552 if (stdin_null_flag) {
553 if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
554 fatal("open(/dev/null): %s", strerror(errno));
555 if (dup2(fd, STDIN_FILENO) == -1)
556 fatal("dup2: %s", strerror(errno));
557 if (fd > STDERR_FILENO)
558 close(fd);
559 }
560
561 term = getenv("TERM");
562
563 flags = 0;
564 if (tty_flag)
565 flags |= SSHMUX_FLAG_TTY;
566 if (subsystem_flag)
567 flags |= SSHMUX_FLAG_SUBSYS;
568 if (options.forward_x11)
569 flags |= SSHMUX_FLAG_X11_FWD;
570 if (options.forward_agent)
571 flags |= SSHMUX_FLAG_AGENT_FWD;
572
573 signal(SIGPIPE, SIG_IGN);
574
575 buffer_init(&m);
576
577 /* Send our command to server */
578 buffer_put_int(&m, muxclient_command);
579 buffer_put_int(&m, flags);
580 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
581 error("%s: msg_send", __func__);
582 muxerr:
583 close(sock);
584 buffer_free(&m);
585 if (muxclient_command != SSHMUX_COMMAND_OPEN)
586 cleanup_exit(255);
587 logit("Falling back to non-multiplexed connection");
588 xfree(options.control_path);
589 options.control_path = NULL;
590 options.control_master = SSHCTL_MASTER_NO;
591 return;
592 }
593 buffer_clear(&m);
594
595 /* Get authorisation status and PID of controlee */
596 if (ssh_msg_recv(sock, &m) == -1) {
597 error("%s: Did not receive reply from master", __func__);
598 goto muxerr;
599 }
600 if (buffer_get_char(&m) != SSHMUX_VER) {
601 error("%s: Master replied with wrong version", __func__);
602 goto muxerr;
603 }
604 if (buffer_get_int_ret(&allowed, &m) != 0) {
605 error("%s: bad server reply", __func__);
606 goto muxerr;
607 }
608 if (allowed != 1) {
609 error("Connection to master denied");
610 goto muxerr;
611 }
612 muxserver_pid = buffer_get_int(&m);
613
614 buffer_clear(&m);
615
616 switch (muxclient_command) {
617 case SSHMUX_COMMAND_ALIVE_CHECK:
618 fprintf(stderr, "Master running (pid=%d)\r\n",
619 muxserver_pid);
620 exit(0);
621 case SSHMUX_COMMAND_TERMINATE:
622 fprintf(stderr, "Exit request sent.\r\n");
623 exit(0);
624 case SSHMUX_COMMAND_OPEN:
625 buffer_put_cstring(&m, term ? term : "");
626 if (options.escape_char == SSH_ESCAPECHAR_NONE)
627 buffer_put_int(&m, 0xffffffff);
628 else
629 buffer_put_int(&m, options.escape_char);
630 buffer_append(&command, "\0", 1);
631 buffer_put_cstring(&m, buffer_ptr(&command));
632
633 if (options.num_send_env == 0 || environ == NULL) {
634 buffer_put_int(&m, 0);
635 } else {
636 /* Pass environment */
637 num_env = 0;
638 for (i = 0; environ[i] != NULL; i++) {
639 if (env_permitted(environ[i]))
640 num_env++; /* Count */
641 }
642 buffer_put_int(&m, num_env);
643 for (i = 0; environ[i] != NULL && num_env >= 0; i++) {
644 if (env_permitted(environ[i])) {
645 num_env--;
646 buffer_put_cstring(&m, environ[i]);
647 }
648 }
649 }
650 break;
651 default:
652 fatal("unrecognised muxclient_command %d", muxclient_command);
653 }
654
655 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) {
656 error("%s: msg_send", __func__);
657 goto muxerr;
658 }
659
660 if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
661 mm_send_fd(sock, STDOUT_FILENO) == -1 ||
662 mm_send_fd(sock, STDERR_FILENO) == -1) {
663 error("%s: send fds failed", __func__);
664 goto muxerr;
665 }
666
667 /*
668 * Mux errors are non-recoverable from this point as the master
669 * has ownership of the session now.
670 */
671
672 /* Wait for reply, so master has a chance to gather ttymodes */
673 buffer_clear(&m);
674 if (ssh_msg_recv(sock, &m) == -1)
675 fatal("%s: msg_recv", __func__);
676 if (buffer_get_char(&m) != SSHMUX_VER)
677 fatal("%s: wrong version", __func__);
678 buffer_free(&m);
679
680 signal(SIGHUP, control_client_sighandler);
681 signal(SIGINT, control_client_sighandler);
682 signal(SIGTERM, control_client_sighandler);
683 signal(SIGWINCH, control_client_sigrelay);
684
685 if (tty_flag)
686 enter_raw_mode();
687
688 /*
689 * Stick around until the controlee closes the client_fd.
690 * Before it does, it is expected to write this process' exit
691 * value (one int). This process must read the value and wait for
692 * the closure of the client_fd; if this one closes early, the
693 * multiplex master will terminate early too (possibly losing data).
694 */
695 exitval[0] = 0;
696 for (i = 0; !muxclient_terminate && i < (int)sizeof(exitval);) {
697 r = read(sock, (char *)exitval + i, sizeof(exitval) - i);
698 if (r == 0) {
699 debug2("Received EOF from master");
700 break;
701 }
702 if (r == -1) {
703 if (errno == EINTR)
704 continue;
705 fatal("%s: read %s", __func__, strerror(errno));
706 }
707 i += r;
708 }
709
710 close(sock);
711 leave_raw_mode();
712 if (i > (int)sizeof(int))
713 fatal("%s: master returned too much data (%d > %lu)",
714 __func__, i, (u_long)sizeof(int));
715 if (muxclient_terminate) {
716 debug2("Exiting on signal %d", muxclient_terminate);
717 exitval[0] = 255;
718 } else if (i < (int)sizeof(int)) {
719 debug2("Control master terminated unexpectedly");
720 exitval[0] = 255;
721 } else
722 debug2("Received exit status from master %d", exitval[0]);
723
724 if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
725 fprintf(stderr, "Shared connection to %s closed.\r\n", host);
726
727 exit(exitval[0]);
728}
diff --git a/nchan.c b/nchan.c
index ad461f4af..e0ebf43f1 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.57 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: nchan.c,v 1.60 2008/06/30 12:16:02 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -32,6 +32,7 @@
32#include <string.h> 32#include <string.h>
33#include <stdarg.h> 33#include <stdarg.h>
34 34
35#include "openbsd-compat/sys-queue.h"
35#include "ssh1.h" 36#include "ssh1.h"
36#include "ssh2.h" 37#include "ssh2.h"
37#include "buffer.h" 38#include "buffer.h"
@@ -77,6 +78,7 @@ static void chan_send_ieof1(Channel *);
77static void chan_send_oclose1(Channel *); 78static void chan_send_oclose1(Channel *);
78static void chan_send_close2(Channel *); 79static void chan_send_close2(Channel *);
79static void chan_send_eof2(Channel *); 80static void chan_send_eof2(Channel *);
81static void chan_send_eow2(Channel *);
80 82
81/* helper */ 83/* helper */
82static void chan_shutdown_write(Channel *); 84static void chan_shutdown_write(Channel *);
@@ -305,6 +307,17 @@ chan_rcvd_close2(Channel *c)
305 break; 307 break;
306 } 308 }
307} 309}
310void
311chan_rcvd_eow(Channel *c)
312{
313 debug2("channel %d: rcvd eow", c->self);
314 switch (c->istate) {
315 case CHAN_INPUT_OPEN:
316 chan_shutdown_read(c);
317 chan_set_istate(c, CHAN_INPUT_CLOSED);
318 break;
319 }
320}
308static void 321static void
309chan_rcvd_eof2(Channel *c) 322chan_rcvd_eof2(Channel *c)
310{ 323{
@@ -321,6 +334,8 @@ chan_write_failed2(Channel *c)
321 case CHAN_OUTPUT_OPEN: 334 case CHAN_OUTPUT_OPEN:
322 case CHAN_OUTPUT_WAIT_DRAIN: 335 case CHAN_OUTPUT_WAIT_DRAIN:
323 chan_shutdown_write(c); 336 chan_shutdown_write(c);
337 if (strcmp(c->ctype, "session") == 0)
338 chan_send_eow2(c);
324 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 339 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
325 break; 340 break;
326 default: 341 default:
@@ -363,6 +378,21 @@ chan_send_close2(Channel *c)
363 c->flags |= CHAN_CLOSE_SENT; 378 c->flags |= CHAN_CLOSE_SENT;
364 } 379 }
365} 380}
381static void
382chan_send_eow2(Channel *c)
383{
384 debug2("channel %d: send eow", c->self);
385 if (c->ostate == CHAN_OUTPUT_CLOSED) {
386 error("channel %d: must not sent eow on closed output",
387 c->self);
388 return;
389 }
390 packet_start(SSH2_MSG_CHANNEL_REQUEST);
391 packet_put_int(c->remote_id);
392 packet_put_cstring("eow@openssh.com");
393 packet_put_char(0);
394 packet_send();
395}
366 396
367/* shared */ 397/* shared */
368 398
diff --git a/nchan2.ms b/nchan2.ms
index a7a67b127..700150450 100644
--- a/nchan2.ms
+++ b/nchan2.ms
@@ -1,4 +1,4 @@
1.\" $OpenBSD: nchan2.ms,v 1.3 2003/11/21 11:57:03 djm Exp $ 1.\" $OpenBSD: nchan2.ms,v 1.4 2008/05/15 23:52:24 djm Exp $
2.\" 2.\"
3.\" Copyright (c) 2000 Markus Friedl. All rights reserved. 3.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
4.\" 4.\"
@@ -44,7 +44,7 @@ arrow from S1.e to S4.n
44box invis "rcvd CLOSE/" "shutdown_read" with .sw at last arrow.c 44box invis "rcvd CLOSE/" "shutdown_read" with .sw at last arrow.c
45arrow "ibuf_empty ||" "rcvd CLOSE/" "send EOF" "" from S2.e to S4.w 45arrow "ibuf_empty ||" "rcvd CLOSE/" "send EOF" "" from S2.e to S4.w
46arrow from S1.s to S2.n 46arrow from S1.s to S2.n
47box invis "read_failed/" "shutdown_read" with .e at last arrow.c 47box invis "read_failed ||" "rcvd EOW/" "shutdown_read" with .e at last arrow.c
48ellipse wid .9*ellipsewid ht .9*ellipseht at S4 48ellipse wid .9*ellipsewid ht .9*ellipseht at S4
49arrow "start" "" from S1.w+(-0.5,0) to S1.w 49arrow "start" "" from S1.w+(-0.5,0) to S1.w
50.PE 50.PE
@@ -59,7 +59,7 @@ S4: ellipse "OUTPUT" "CLOSED"
59move down l from 1st ellipse.s 59move down l from 1st ellipse.s
60S2: ellipse "OUTPUT" "WAIT" "DRAIN" 60S2: ellipse "OUTPUT" "WAIT" "DRAIN"
61arrow from S1.e to S4.n 61arrow from S1.e to S4.n
62box invis "write_failed/" "shutdown_write" with .sw at last arrow.c 62box invis "write_failed/" "shutdown_write" "send EOW" with .sw at last arrow.c
63arrow "obuf_empty ||" "write_failed/" "shutdown_write" "" from S2.e to S4.w 63arrow "obuf_empty ||" "write_failed/" "shutdown_write" "" from S2.e to S4.w
64arrow from S1.s to S2.n 64arrow from S1.s to S2.n
65box invis "rcvd EOF ||" "rcvd CLOSE/" "-" with .e at last arrow.c 65box invis "rcvd EOF ||" "rcvd CLOSE/" "-" with .e at last arrow.c
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index b44a7851e..a60e5a68d 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.41 2007/06/25 12:15:13 dtucker Exp $ 1# $Id: Makefile.in,v 1.43 2008/06/08 17:32:29 dtucker Exp $
2 2
3sysconfdir=@sysconfdir@ 3sysconfdir=@sysconfdir@
4piddir=@piddir@ 4piddir=@piddir@
@@ -16,9 +16,9 @@ RANLIB=@RANLIB@
16INSTALL=@INSTALL@ 16INSTALL=@INSTALL@
17LDFLAGS=-L. @LDFLAGS@ 17LDFLAGS=-L. @LDFLAGS@
18 18
19OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o 19OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
20 20
21COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o 21COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
22 22
23PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o 23PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
24 24
diff --git a/openbsd-compat/base64.c b/openbsd-compat/base64.c
index 9a60f583b..9e7466716 100644
--- a/openbsd-compat/base64.c
+++ b/openbsd-compat/base64.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */ 1/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 by Internet Software Consortium. 4 * Copyright (c) 1996 by Internet Software Consortium.
@@ -62,9 +62,6 @@
62 62
63#include "base64.h" 63#include "base64.h"
64 64
65/* XXX abort illegal in library */
66#define Assert(Cond) if (!(Cond)) abort()
67
68static const char Base64[] = 65static const char Base64[] =
69 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 66 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
70static const char Pad64 = '='; 67static const char Pad64 = '=';
@@ -151,10 +148,6 @@ b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
151 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 148 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
152 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 149 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
153 output[3] = input[2] & 0x3f; 150 output[3] = input[2] & 0x3f;
154 Assert(output[0] < 64);
155 Assert(output[1] < 64);
156 Assert(output[2] < 64);
157 Assert(output[3] < 64);
158 151
159 if (datalength + 4 > targsize) 152 if (datalength + 4 > targsize)
160 return (-1); 153 return (-1);
@@ -174,9 +167,6 @@ b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
174 output[0] = input[0] >> 2; 167 output[0] = input[0] >> 2;
175 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 168 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
176 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 169 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
177 Assert(output[0] < 64);
178 Assert(output[1] < 64);
179 Assert(output[2] < 64);
180 170
181 if (datalength + 4 > targsize) 171 if (datalength + 4 > targsize)
182 return (-1); 172 return (-1);
diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c
index 65afed1e3..c0d5bdb5c 100644
--- a/openbsd-compat/bindresvport.c
+++ b/openbsd-compat/bindresvport.c
@@ -1,6 +1,6 @@
1/* This file has be substantially modified from the original OpenBSD source */ 1/* This file has be substantially modified from the original OpenBSD source */
2 2
3/* $OpenBSD: bindresvport.c,v 1.16 2005/04/01 07:44:03 otto Exp $ */ 3/* $OpenBSD: bindresvport.c,v 1.17 2005/12/21 01:40:22 millert Exp $ */
4 4
5/* 5/*
6 * Copyright 1996, Jason Downs. All rights reserved. 6 * Copyright 1996, Jason Downs. All rights reserved.
@@ -54,8 +54,8 @@ bindresvport_sa(int sd, struct sockaddr *sa)
54{ 54{
55 int error, af; 55 int error, af;
56 struct sockaddr_storage myaddr; 56 struct sockaddr_storage myaddr;
57 struct sockaddr_in *sin; 57 struct sockaddr_in *in;
58 struct sockaddr_in6 *sin6; 58 struct sockaddr_in6 *in6;
59 u_int16_t *portp; 59 u_int16_t *portp;
60 u_int16_t port; 60 u_int16_t port;
61 socklen_t salen; 61 socklen_t salen;
@@ -74,13 +74,13 @@ bindresvport_sa(int sd, struct sockaddr *sa)
74 af = sa->sa_family; 74 af = sa->sa_family;
75 75
76 if (af == AF_INET) { 76 if (af == AF_INET) {
77 sin = (struct sockaddr_in *)sa; 77 in = (struct sockaddr_in *)sa;
78 salen = sizeof(struct sockaddr_in); 78 salen = sizeof(struct sockaddr_in);
79 portp = &sin->sin_port; 79 portp = &in->sin_port;
80 } else if (af == AF_INET6) { 80 } else if (af == AF_INET6) {
81 sin6 = (struct sockaddr_in6 *)sa; 81 in6 = (struct sockaddr_in6 *)sa;
82 salen = sizeof(struct sockaddr_in6); 82 salen = sizeof(struct sockaddr_in6);
83 portp = &sin6->sin6_port; 83 portp = &in6->sin6_port;
84 } else { 84 } else {
85 errno = EPFNOSUPPORT; 85 errno = EPFNOSUPPORT;
86 return (-1); 86 return (-1);
diff --git a/openbsd-compat/bsd-arc4random.c b/openbsd-compat/bsd-arc4random.c
index d45fb182a..9d4c8690e 100644
--- a/openbsd-compat/bsd-arc4random.c
+++ b/openbsd-compat/bsd-arc4random.c
@@ -19,6 +19,7 @@
19#include <sys/types.h> 19#include <sys/types.h>
20 20
21#include <string.h> 21#include <string.h>
22#include <stdlib.h>
22#include <stdarg.h> 23#include <stdarg.h>
23 24
24#include "log.h" 25#include "log.h"
@@ -82,3 +83,68 @@ arc4random_stir(void)
82 rc4_ready = REKEY_BYTES; 83 rc4_ready = REKEY_BYTES;
83} 84}
84#endif /* !HAVE_ARC4RANDOM */ 85#endif /* !HAVE_ARC4RANDOM */
86
87#ifndef ARC4RANDOM_BUF
88void
89arc4random_buf(void *_buf, size_t n)
90{
91 size_t i;
92 u_int32_t r = 0;
93 char *buf = (char *)_buf;
94
95 for (i = 0; i < n; i++) {
96 if (i % 4 == 0)
97 r = arc4random();
98 buf[i] = r & 0xff;
99 r >>= 8;
100 }
101 i = r = 0;
102}
103#endif /* !HAVE_ARC4RANDOM_BUF */
104
105#ifndef ARC4RANDOM_UNIFORM
106/*
107 * Calculate a uniformly distributed random number less than upper_bound
108 * avoiding "modulo bias".
109 *
110 * Uniformity is achieved by generating new random numbers until the one
111 * returned is outside the range [0, 2**32 % upper_bound). This
112 * guarantees the selected random number will be inside
113 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
114 * after reduction modulo upper_bound.
115 */
116u_int32_t
117arc4random_uniform(u_int32_t upper_bound)
118{
119 u_int32_t r, min;
120
121 if (upper_bound < 2)
122 return 0;
123
124#if (ULONG_MAX > 0xffffffffUL)
125 min = 0x100000000UL % upper_bound;
126#else
127 /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
128 if (upper_bound > 0x80000000)
129 min = 1 + ~upper_bound; /* 2**32 - upper_bound */
130 else {
131 /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
132 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
133 }
134#endif
135
136 /*
137 * This could theoretically loop forever but each retry has
138 * p > 0.5 (worst case, usually far better) of selecting a
139 * number inside the range we need, so it should rarely need
140 * to re-roll.
141 */
142 for (;;) {
143 r = arc4random();
144 if (r >= min)
145 break;
146 }
147
148 return r % upper_bound;
149}
150#endif /* !HAVE_ARC4RANDOM_UNIFORM */
diff --git a/openbsd-compat/bsd-asprintf.c b/openbsd-compat/bsd-asprintf.c
index 00fa0dfd8..3368195d4 100644
--- a/openbsd-compat/bsd-asprintf.c
+++ b/openbsd-compat/bsd-asprintf.c
@@ -55,6 +55,7 @@ vasprintf(char **str, const char *fmt, va_list ap)
55 if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ 55 if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
56 *str = string; 56 *str = string;
57 } else if (ret == INT_MAX || ret < 0) { /* Bad length */ 57 } else if (ret == INT_MAX || ret < 0) { /* Bad length */
58 free(string);
58 goto fail; 59 goto fail;
59 } else { /* bigger than initial, realloc allowing for nul */ 60 } else { /* bigger than initial, realloc allowing for nul */
60 len = (size_t)ret + 1; 61 len = (size_t)ret + 1;
diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c
index dbf8176b6..38be7e350 100644
--- a/openbsd-compat/bsd-cygwin_util.c
+++ b/openbsd-compat/bsd-cygwin_util.c
@@ -175,45 +175,7 @@ check_nt_auth(int pwd_authenticated, struct passwd *pw)
175int 175int
176check_ntsec(const char *filename) 176check_ntsec(const char *filename)
177{ 177{
178 char *cygwin; 178 return (pathconf(filename, _PC_POSIX_PERMISSIONS));
179 int allow_ntea = 0, allow_ntsec = 0;
180 struct statfs fsstat;
181
182 /* Windows 95/98/ME don't support file system security at all. */
183 if (!is_winnt)
184 return (0);
185
186 /* Evaluate current CYGWIN settings. */
187 cygwin = getenv("CYGWIN");
188 allow_ntea = ntea_on(cygwin);
189 allow_ntsec = ntsec_on(cygwin) ||
190 (has_capability(HAS_NTSEC_BY_DEFAULT) && !ntsec_off(cygwin));
191
192 /*
193 * `ntea' is an emulation of POSIX attributes. It doesn't support
194 * real file level security as ntsec on NTFS file systems does
195 * but it supports FAT filesystems. `ntea' is minimum requirement
196 * for security checks.
197 */
198 if (allow_ntea)
199 return (1);
200
201 /*
202 * Retrieve file system flags. In Cygwin, file system flags are
203 * copied to f_type which has no meaning in Win32 itself.
204 */
205 if (statfs(filename, &fsstat))
206 return (1);
207
208 /*
209 * Only file systems supporting ACLs are able to set permissions.
210 * `ntsec' is the setting in Cygwin which switches using of NTFS
211 * ACLs to support POSIX permissions on files.
212 */
213 if (fsstat.f_type & FS_PERSISTENT_ACLS)
214 return (allow_ntsec);
215
216 return (0);
217} 179}
218 180
219void 181void
diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c
index 836882eea..284db3a1f 100644
--- a/openbsd-compat/bsd-poll.c
+++ b/openbsd-compat/bsd-poll.c
@@ -1,4 +1,4 @@
1/* $Id: bsd-poll.c,v 1.1 2007/06/25 12:15:13 dtucker Exp $ */ 1/* $Id: bsd-poll.c,v 1.3 2008/04/04 05:16:36 djm 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).
@@ -17,12 +17,13 @@
17 */ 17 */
18 18
19#include "includes.h" 19#include "includes.h"
20#if !defined(HAVE_POLL) && defined(HAVE_SELECT) 20#if !defined(HAVE_POLL)
21 21
22#ifdef HAVE_SYS_SELECT_H 22#ifdef HAVE_SYS_SELECT_H
23# include <sys/select.h> 23# include <sys/select.h>
24#endif 24#endif
25 25
26#include <stdlib.h>
26#include <errno.h> 27#include <errno.h>
27#include "bsd-poll.h" 28#include "bsd-poll.h"
28 29
diff --git a/openbsd-compat/bsd-statvfs.c b/openbsd-compat/bsd-statvfs.c
new file mode 100644
index 000000000..844d5b464
--- /dev/null
+++ b/openbsd-compat/bsd-statvfs.c
@@ -0,0 +1,37 @@
1/* $Id: bsd-statvfs.c,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */
2
3/*
4 * Copyright (c) 2008 Darren Tucker <dtucker@zip.com.au>
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 MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include "includes.h"
20
21#include <errno.h>
22
23#ifndef HAVE_STATVFS
24int statvfs(const char *path, struct statvfs *buf)
25{
26 errno = ENOSYS;
27 return -1;
28}
29#endif
30
31#ifndef HAVE_FSTATVFS
32int fstatvfs(int fd, struct statvfs *buf)
33{
34 errno = ENOSYS;
35 return -1;
36}
37#endif
diff --git a/openbsd-compat/bsd-statvfs.h b/openbsd-compat/bsd-statvfs.h
new file mode 100644
index 000000000..da215ffc6
--- /dev/null
+++ b/openbsd-compat/bsd-statvfs.h
@@ -0,0 +1,68 @@
1/* $Id: bsd-statvfs.h,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */
2
3/*
4 * Copyright (c) 2008 Darren Tucker <dtucker@zip.com.au>
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 MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include "includes.h"
20
21#include <sys/types.h>
22
23#ifdef HAVE_SYS_STATFS_H
24#include <sys/statfs.h>
25#endif
26
27#ifndef HAVE_STATVFS
28
29#ifndef HAVE_FSBLKCNT_T
30typedef unsigned long fsblkcnt_t;
31#endif
32#ifndef HAVE_FSFILCNT_T
33typedef unsigned long fsfilcnt_t;
34#endif
35
36#ifndef ST_RDONLY
37#define ST_RDONLY 1
38#endif
39#ifndef ST_NOSUID
40#define ST_NOSUID 2
41#endif
42
43 /* as defined in IEEE Std 1003.1, 2004 Edition */
44struct statvfs {
45 unsigned long f_bsize; /* File system block size. */
46 unsigned long f_frsize; /* Fundamental file system block size. */
47 fsblkcnt_t f_blocks; /* Total number of blocks on file system in */
48 /* units of f_frsize. */
49 fsblkcnt_t f_bfree; /* Total number of free blocks. */
50 fsblkcnt_t f_bavail; /* Number of free blocks available to */
51 /* non-privileged process. */
52 fsfilcnt_t f_files; /* Total number of file serial numbers. */
53 fsfilcnt_t f_ffree; /* Total number of free file serial numbers. */
54 fsfilcnt_t f_favail; /* Number of file serial numbers available to */
55 /* non-privileged process. */
56 unsigned long f_fsid; /* File system ID. */
57 unsigned long f_flag; /* BBit mask of f_flag values. */
58 unsigned long f_namemax;/* Maximum filename length. */
59};
60#endif
61
62#ifndef HAVE_STATVFS
63int statvfs(const char *, struct statvfs *);
64#endif
65
66#ifndef HAVE_FSTATVFS
67int fstatvfs(int, struct statvfs *);
68#endif
diff --git a/openbsd-compat/fake-rfc2553.c b/openbsd-compat/fake-rfc2553.c
index b6ea3d21e..096d9e092 100644
--- a/openbsd-compat/fake-rfc2553.c
+++ b/openbsd-compat/fake-rfc2553.c
@@ -51,6 +51,8 @@ int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
51 struct hostent *hp; 51 struct hostent *hp;
52 char tmpserv[16]; 52 char tmpserv[16];
53 53
54 if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET)
55 return (EAI_FAMILY);
54 if (serv != NULL) { 56 if (serv != NULL) {
55 snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); 57 snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
56 if (strlcpy(serv, tmpserv, servlen) >= servlen) 58 if (strlcpy(serv, tmpserv, servlen) >= servlen)
@@ -95,6 +97,8 @@ gai_strerror(int err)
95 return ("memory allocation failure."); 97 return ("memory allocation failure.");
96 case EAI_NONAME: 98 case EAI_NONAME:
97 return ("nodename nor servname provided, or not known"); 99 return ("nodename nor servname provided, or not known");
100 case EAI_FAMILY:
101 return ("ai_family not supported");
98 default: 102 default:
99 return ("unknown/invalid error."); 103 return ("unknown/invalid error.");
100 } 104 }
@@ -159,6 +163,9 @@ getaddrinfo(const char *hostname, const char *servname,
159 u_long addr; 163 u_long addr;
160 164
161 port = 0; 165 port = 0;
166 if (hints && hints->ai_family != AF_UNSPEC &&
167 hints->ai_family != AF_INET)
168 return (EAI_FAMILY);
162 if (servname != NULL) { 169 if (servname != NULL) {
163 char *cp; 170 char *cp;
164 171
diff --git a/openbsd-compat/fake-rfc2553.h b/openbsd-compat/fake-rfc2553.h
index 5c2ce5b1b..3e9090fc8 100644
--- a/openbsd-compat/fake-rfc2553.h
+++ b/openbsd-compat/fake-rfc2553.h
@@ -1,4 +1,4 @@
1/* $Id: fake-rfc2553.h,v 1.13 2006/07/24 03:51:52 djm Exp $ */ 1/* $Id: fake-rfc2553.h,v 1.16 2008/07/14 11:37:37 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 2000-2003 Damien Miller. All rights reserved. 4 * Copyright (C) 2000-2003 Damien Miller. All rights reserved.
@@ -77,6 +77,7 @@ struct sockaddr_in6 {
77 u_int16_t sin6_port; 77 u_int16_t sin6_port;
78 u_int32_t sin6_flowinfo; 78 u_int32_t sin6_flowinfo;
79 struct in6_addr sin6_addr; 79 struct in6_addr sin6_addr;
80 u_int32_t sin6_scope_id;
80}; 81};
81#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ 82#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
82 83
@@ -128,6 +129,9 @@ struct sockaddr_in6 {
128#ifndef EAI_SYSTEM 129#ifndef EAI_SYSTEM
129# define EAI_SYSTEM (INT_MAX - 4) 130# define EAI_SYSTEM (INT_MAX - 4)
130#endif 131#endif
132#ifndef EAI_FAMILY
133# define EAI_FAMILY (INT_MAX - 5)
134#endif
131 135
132#ifndef HAVE_STRUCT_ADDRINFO 136#ifndef HAVE_STRUCT_ADDRINFO
133struct addrinfo { 137struct addrinfo {
@@ -152,7 +156,7 @@ int getaddrinfo(const char *, const char *,
152#endif /* !HAVE_GETADDRINFO */ 156#endif /* !HAVE_GETADDRINFO */
153 157
154#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO) 158#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
155#define gai_strerror(a) (ssh_gai_strerror(a)) 159#define gai_strerror(a) (_ssh_compat_gai_strerror(a))
156char *gai_strerror(int); 160char *gai_strerror(int);
157#endif /* !HAVE_GAI_STRERROR */ 161#endif /* !HAVE_GAI_STRERROR */
158 162
diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c
new file mode 100644
index 000000000..edd682a49
--- /dev/null
+++ b/openbsd-compat/fmt_scaled.c
@@ -0,0 +1,274 @@
1/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */
2
3/*
4 * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/* OPENBSD ORIGINAL: lib/libutil/fmt_scaled.c */
30
31/*
32 * fmt_scaled: Format numbers scaled for human comprehension
33 * scan_scaled: Scan numbers in this format.
34 *
35 * "Human-readable" output uses 4 digits max, and puts a unit suffix at
36 * the end. Makes output compact and easy-to-read esp. on huge disks.
37 * Formatting code was originally in OpenBSD "df", converted to library routine.
38 * Scanning code written for OpenBSD libutil.
39 */
40
41#include "includes.h"
42
43#ifndef HAVE_FMT_SCALED
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <errno.h>
48#include <string.h>
49#include <ctype.h>
50#include <limits.h>
51
52typedef enum {
53 NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6
54} unit_type;
55
56/* These three arrays MUST be in sync! XXX make a struct */
57static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA };
58static char scale_chars[] = "BKMGTPE";
59static long long scale_factors[] = {
60 1LL,
61 1024LL,
62 1024LL*1024,
63 1024LL*1024*1024,
64 1024LL*1024*1024*1024,
65 1024LL*1024*1024*1024*1024,
66 1024LL*1024*1024*1024*1024*1024,
67};
68#define SCALE_LENGTH (sizeof(units)/sizeof(units[0]))
69
70#define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */
71
72/** Convert the given input string "scaled" into numeric in "result".
73 * Return 0 on success, -1 and errno set on error.
74 */
75int
76scan_scaled(char *scaled, long long *result)
77{
78 char *p = scaled;
79 int sign = 0;
80 unsigned int i, ndigits = 0, fract_digits = 0;
81 long long scale_fact = 1, whole = 0, fpart = 0;
82
83 /* Skip leading whitespace */
84 while (isascii(*p) && isspace(*p))
85 ++p;
86
87 /* Then at most one leading + or - */
88 while (*p == '-' || *p == '+') {
89 if (*p == '-') {
90 if (sign) {
91 errno = EINVAL;
92 return -1;
93 }
94 sign = -1;
95 ++p;
96 } else if (*p == '+') {
97 if (sign) {
98 errno = EINVAL;
99 return -1;
100 }
101 sign = +1;
102 ++p;
103 }
104 }
105
106 /* Main loop: Scan digits, find decimal point, if present.
107 * We don't allow exponentials, so no scientific notation
108 * (but note that E for Exa might look like e to some!).
109 * Advance 'p' to end, to get scale factor.
110 */
111 for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
112 if (*p == '.') {
113 if (fract_digits > 0) { /* oops, more than one '.' */
114 errno = EINVAL;
115 return -1;
116 }
117 fract_digits = 1;
118 continue;
119 }
120
121 i = (*p) - '0'; /* whew! finally a digit we can use */
122 if (fract_digits > 0) {
123 if (fract_digits >= MAX_DIGITS-1)
124 /* ignore extra fractional digits */
125 continue;
126 fract_digits++; /* for later scaling */
127 fpart *= 10;
128 fpart += i;
129 } else { /* normal digit */
130 if (++ndigits >= MAX_DIGITS) {
131 errno = ERANGE;
132 return -1;
133 }
134 whole *= 10;
135 whole += i;
136 }
137 }
138
139 if (sign) {
140 whole *= sign;
141 fpart *= sign;
142 }
143
144 /* If no scale factor given, we're done. fraction is discarded. */
145 if (!*p) {
146 *result = whole;
147 return 0;
148 }
149
150 /* Validate scale factor, and scale whole and fraction by it. */
151 for (i = 0; i < SCALE_LENGTH; i++) {
152
153 /** Are we there yet? */
154 if (*p == scale_chars[i] ||
155 *p == tolower(scale_chars[i])) {
156
157 /* If it ends with alphanumerics after the scale char, bad. */
158 if (isalnum(*(p+1))) {
159 errno = EINVAL;
160 return -1;
161 }
162 scale_fact = scale_factors[i];
163
164 /* scale whole part */
165 whole *= scale_fact;
166
167 /* truncate fpart so it does't overflow.
168 * then scale fractional part.
169 */
170 while (fpart >= LLONG_MAX / scale_fact) {
171 fpart /= 10;
172 fract_digits--;
173 }
174 fpart *= scale_fact;
175 if (fract_digits > 0) {
176 for (i = 0; i < fract_digits -1; i++)
177 fpart /= 10;
178 }
179 whole += fpart;
180 *result = whole;
181 return 0;
182 }
183 }
184 errno = ERANGE;
185 return -1;
186}
187
188/* Format the given "number" into human-readable form in "result".
189 * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE.
190 * Return 0 on success, -1 and errno set if error.
191 */
192int
193fmt_scaled(long long number, char *result)
194{
195 long long abval, fract = 0;
196 unsigned int i;
197 unit_type unit = NONE;
198
199 abval = (number < 0LL) ? -number : number; /* no long long_abs yet */
200
201 /* Not every negative long long has a positive representation.
202 * Also check for numbers that are just too darned big to format
203 */
204 if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) {
205 errno = ERANGE;
206 return -1;
207 }
208
209 /* scale whole part; get unscaled fraction */
210 for (i = 0; i < SCALE_LENGTH; i++) {
211 if (abval/1024 < scale_factors[i]) {
212 unit = units[i];
213 fract = (i == 0) ? 0 : abval % scale_factors[i];
214 number /= scale_factors[i];
215 if (i > 0)
216 fract /= scale_factors[i - 1];
217 break;
218 }
219 }
220
221 fract = (10 * fract + 512) / 1024;
222 /* if the result would be >= 10, round main number */
223 if (fract == 10) {
224 if (number >= 0)
225 number++;
226 else
227 number--;
228 fract = 0;
229 }
230
231 if (number == 0)
232 strlcpy(result, "0B", FMT_SCALED_STRSIZE);
233 else if (unit == NONE || number >= 100 || number <= -100) {
234 if (fract >= 5) {
235 if (number >= 0)
236 number++;
237 else
238 number--;
239 }
240 (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c",
241 number, scale_chars[unit]);
242 } else
243 (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c",
244 number, fract, scale_chars[unit]);
245
246 return 0;
247}
248
249#ifdef MAIN
250/*
251 * This is the original version of the program in the man page.
252 * Copy-and-paste whatever you need from it.
253 */
254int
255main(int argc, char **argv)
256{
257 char *cinput = "1.5K", buf[FMT_SCALED_STRSIZE];
258 long long ninput = 10483892, result;
259
260 if (scan_scaled(cinput, &result) == 0)
261 printf("\"%s\" -> %lld\n", cinput, result);
262 else
263 perror(cinput);
264
265 if (fmt_scaled(ninput, buf) == 0)
266 printf("%lld -> \"%s\"\n", ninput, buf);
267 else
268 fprintf(stderr, "%lld invalid (%s)\n", ninput, strerror(errno));
269
270 return 0;
271}
272#endif
273
274#endif /* HAVE_FMT_SCALED */
diff --git a/openbsd-compat/getrrsetbyname.c b/openbsd-compat/getrrsetbyname.c
index 80af3f542..785b22569 100644
--- a/openbsd-compat/getrrsetbyname.c
+++ b/openbsd-compat/getrrsetbyname.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */ 1/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 Jakob Schlyter. All rights reserved. 4 * Copyright (c) 2001 Jakob Schlyter. All rights reserved.
@@ -288,7 +288,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
288 rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, 288 rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
289 rrset->rri_rdtype); 289 rrset->rri_rdtype);
290 rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, 290 rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
291 T_SIG); 291 T_RRSIG);
292 292
293 /* allocate memory for answers */ 293 /* allocate memory for answers */
294 rrset->rri_rdatas = calloc(rrset->rri_nrdatas, 294 rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
@@ -318,7 +318,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
318 rdata = &rrset->rri_rdatas[index_ans++]; 318 rdata = &rrset->rri_rdatas[index_ans++];
319 319
320 if (rr->class == rrset->rri_rdclass && 320 if (rr->class == rrset->rri_rdclass &&
321 rr->type == T_SIG) 321 rr->type == T_RRSIG)
322 rdata = &rrset->rri_sigs[index_sig++]; 322 rdata = &rrset->rri_sigs[index_sig++];
323 323
324 if (rdata) { 324 if (rdata) {
diff --git a/openbsd-compat/getrrsetbyname.h b/openbsd-compat/getrrsetbyname.h
index 39995b63f..1283f5506 100644
--- a/openbsd-compat/getrrsetbyname.h
+++ b/openbsd-compat/getrrsetbyname.h
@@ -62,8 +62,8 @@
62#define HFIXEDSZ 12 62#define HFIXEDSZ 12
63#endif 63#endif
64 64
65#ifndef T_SIG 65#ifndef T_RRSIG
66#define T_SIG 24 66#define T_RRSIG 46
67#endif 67#endif
68 68
69/* 69/*
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c
index b3dd2b171..74b506403 100644
--- a/openbsd-compat/glob.c
+++ b/openbsd-compat/glob.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: glob.c,v 1.25 2005/08/08 08:05:34 espie Exp $ */ 1/* $OpenBSD: glob.c,v 1.26 2005/11/28 17:50:12 deraadt Exp $ */
2/* 2/*
3 * Copyright (c) 1989, 1993 3 * Copyright (c) 1989, 1993
4 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
@@ -48,7 +48,8 @@
48 48
49#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ 49#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \
50 !defined(GLOB_HAS_GL_MATCHC) || \ 50 !defined(GLOB_HAS_GL_MATCHC) || \
51 !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 51 !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
52 defined(BROKEN_GLOB)
52 53
53static long 54static long
54get_arg_max(void) 55get_arg_max(void)
@@ -149,7 +150,7 @@ static int glob0(const Char *, glob_t *);
149static int glob1(Char *, Char *, glob_t *, size_t *); 150static int glob1(Char *, Char *, glob_t *, size_t *);
150static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, 151static int glob2(Char *, Char *, Char *, Char *, Char *, Char *,
151 glob_t *, size_t *); 152 glob_t *, size_t *);
152static int glob3(Char *, Char *, Char *, Char *, Char *, Char *, 153static int glob3(Char *, Char *, Char *, Char *, Char *,
153 Char *, Char *, glob_t *, size_t *); 154 Char *, Char *, glob_t *, size_t *);
154static int globextend(const Char *, glob_t *, size_t *); 155static int globextend(const Char *, glob_t *, size_t *);
155static const Char * 156static const Char *
@@ -571,16 +572,16 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
571 } else 572 } else
572 /* Need expansion, recurse. */ 573 /* Need expansion, recurse. */
573 return(glob3(pathbuf, pathbuf_last, pathend, 574 return(glob3(pathbuf, pathbuf_last, pathend,
574 pathend_last, pattern, pattern_last, 575 pathend_last, pattern, p, pattern_last,
575 p, pattern_last, pglob, limitp)); 576 pglob, limitp));
576 } 577 }
577 /* NOTREACHED */ 578 /* NOTREACHED */
578} 579}
579 580
580static int 581static int
581glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, 582glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
582 Char *pattern, Char *pattern_last, Char *restpattern, 583 Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob,
583 Char *restpattern_last, glob_t *pglob, size_t *limitp) 584 size_t *limitp)
584{ 585{
585 struct dirent *dp; 586 struct dirent *dp;
586 DIR *dirp; 587 DIR *dirp;
diff --git a/openbsd-compat/glob.h b/openbsd-compat/glob.h
index 9ba07f76e..a2b36f974 100644
--- a/openbsd-compat/glob.h
+++ b/openbsd-compat/glob.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: glob.h,v 1.9 2004/10/07 16:56:11 millert Exp $ */ 1/* $OpenBSD: glob.h,v 1.10 2005/12/13 00:35:22 millert Exp $ */
2/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ 2/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */
3 3
4/* 4/*
@@ -39,7 +39,8 @@
39 39
40#if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \ 40#if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \
41 !defined(GLOB_HAS_GL_MATCHC) || \ 41 !defined(GLOB_HAS_GL_MATCHC) || \
42 !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 42 !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
43 defined(BROKEN_GLOB)
43 44
44#ifndef _GLOB_H_ 45#ifndef _GLOB_H_
45#define _GLOB_H_ 46#define _GLOB_H_
@@ -66,7 +67,6 @@ typedef struct {
66 int (*gl_stat)(const char *, struct stat *); 67 int (*gl_stat)(const char *, struct stat *);
67} glob_t; 68} glob_t;
68 69
69/* Flags */
70#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ 70#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
71#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ 71#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
72#define GLOB_ERR 0x0004 /* Return on error. */ 72#define GLOB_ERR 0x0004 /* Return on error. */
@@ -75,6 +75,13 @@ typedef struct {
75#define GLOB_NOSORT 0x0020 /* Don't sort. */ 75#define GLOB_NOSORT 0x0020 /* Don't sort. */
76#define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ 76#define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */
77 77
78/* Error values returned by glob(3) */
79#define GLOB_NOSPACE (-1) /* Malloc call failed. */
80#define GLOB_ABORTED (-2) /* Unignored error. */
81#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */
82#define GLOB_NOSYS (-4) /* Function not supported. */
83#define GLOB_ABEND GLOB_ABORTED
84
78#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ 85#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
79#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ 86#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
80#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ 87#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
@@ -83,13 +90,6 @@ typedef struct {
83#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ 90#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
84#define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */ 91#define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */
85 92
86/* Error values returned by glob(3) */
87#define GLOB_NOSPACE (-1) /* Malloc call failed. */
88#define GLOB_ABORTED (-2) /* Unignored error. */
89#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */
90#define GLOB_NOSYS (-4) /* Function not supported. */
91#define GLOB_ABEND GLOB_ABORTED
92
93int glob(const char *, int, int (*)(const char *, int), glob_t *); 93int glob(const char *, int, int (*)(const char *, int), glob_t *);
94void globfree(glob_t *); 94void globfree(glob_t *);
95 95
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index 6406af19d..50c6d990b 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -1,4 +1,4 @@
1/* $Id: openbsd-compat.h,v 1.43 2007/06/25 12:15:13 dtucker Exp $ */ 1/* $Id: openbsd-compat.h,v 1.46 2008/06/08 17:32:29 dtucker 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.
@@ -101,6 +101,11 @@ int daemon(int nochdir, int noclose);
101char *dirname(const char *path); 101char *dirname(const char *path);
102#endif 102#endif
103 103
104#ifndef HAVE_FMT_SCALED
105#define FMT_SCALED_STRSIZE 7
106int fmt_scaled(long long number, char *result);
107#endif
108
104#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) 109#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
105char *inet_ntoa(struct in_addr in); 110char *inet_ntoa(struct in_addr in);
106#endif 111#endif
@@ -139,6 +144,7 @@ int writev(int, struct iovec *, int);
139 144
140/* Home grown routines */ 145/* Home grown routines */
141#include "bsd-misc.h" 146#include "bsd-misc.h"
147#include "bsd-statvfs.h"
142#include "bsd-waitpid.h" 148#include "bsd-waitpid.h"
143#include "bsd-poll.h" 149#include "bsd-poll.h"
144 150
@@ -151,6 +157,14 @@ unsigned int arc4random(void);
151void arc4random_stir(void); 157void arc4random_stir(void);
152#endif /* !HAVE_ARC4RANDOM */ 158#endif /* !HAVE_ARC4RANDOM */
153 159
160#ifndef HAVE_ARC4RANDOM_BUF
161void arc4random_buf(void *, size_t);
162#endif
163
164#ifndef HAVE_ARC4RANDOM_UNIFORM
165u_int32_t arc4random_uniform(u_int32_t);
166#endif
167
154#ifndef HAVE_ASPRINTF 168#ifndef HAVE_ASPRINTF
155int asprintf(char **, const char *, ...); 169int asprintf(char **, const char *, ...);
156#endif 170#endif
diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c
index 45ebd3f66..49238ba80 100644
--- a/openbsd-compat/openssl-compat.c
+++ b/openbsd-compat/openssl-compat.c
@@ -1,4 +1,4 @@
1/* $Id: openssl-compat.c,v 1.4 2006/02/22 11:24:47 dtucker Exp $ */ 1/* $Id: openssl-compat.c,v 1.6 2008/02/28 08:13:52 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>
diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h
index f1d2f19fc..6a1bed5b2 100644
--- a/openbsd-compat/openssl-compat.h
+++ b/openbsd-compat/openssl-compat.h
@@ -1,4 +1,4 @@
1/* $Id: openssl-compat.h,v 1.10 2007/06/14 13:47:31 dtucker Exp $ */ 1/* $Id: openssl-compat.h,v 1.12 2008/02/28 08:22:04 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>
@@ -19,6 +19,11 @@
19#include "includes.h" 19#include "includes.h"
20#include <openssl/evp.h> 20#include <openssl/evp.h>
21 21
22/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */
23#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f)
24# define OPENSSL_free(x) Free(x)
25#endif
26
22#if OPENSSL_VERSION_NUMBER < 0x00906000L 27#if OPENSSL_VERSION_NUMBER < 0x00906000L
23# define SSH_OLD_EVP 28# define SSH_OLD_EVP
24# define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) 29# define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
@@ -79,8 +84,8 @@ extern const EVP_CIPHER *evp_acss(void);
79# ifdef SSLeay_add_all_algorithms 84# ifdef SSLeay_add_all_algorithms
80# undef SSLeay_add_all_algorithms 85# undef SSLeay_add_all_algorithms
81# endif 86# endif
82# define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms() 87# define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms()
83#endif 88# endif
84 89
85int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *, 90int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *,
86 unsigned char *, int); 91 unsigned char *, int);
diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c
index 94faec670..5b1cb7387 100644
--- a/openbsd-compat/port-aix.c
+++ b/openbsd-compat/port-aix.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * 2 *
3 * Copyright (c) 2001 Gert Doering. All rights reserved. 3 * Copyright (c) 2001 Gert Doering. All rights reserved.
4 * Copyright (c) 2003,2004,2005 Darren Tucker. All rights reserved. 4 * Copyright (c) 2003,2004,2005,2006 Darren Tucker. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -394,4 +394,47 @@ sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
394} 394}
395# endif /* AIX_GETNAMEINFO_HACK */ 395# endif /* AIX_GETNAMEINFO_HACK */
396 396
397# if defined(USE_GETGRSET)
398# include <stdlib.h>
399int
400getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt)
401{
402 char *cp, *grplist, *grp;
403 gid_t gid;
404 int ret = 0, ngroups = 0, maxgroups;
405 long l;
406
407 maxgroups = *grpcnt;
408
409 if ((cp = grplist = getgrset(user)) == NULL)
410 return -1;
411
412 /* handle zero-length case */
413 if (maxgroups <= 0) {
414 *grpcnt = 0;
415 return -1;
416 }
417
418 /* copy primary group */
419 groups[ngroups++] = pgid;
420
421 /* copy each entry from getgrset into group list */
422 while ((grp = strsep(&grplist, ",")) != NULL) {
423 l = strtol(grp, NULL, 10);
424 if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) {
425 ret = -1;
426 goto out;
427 }
428 gid = (gid_t)l;
429 if (gid == pgid)
430 continue; /* we have already added primary gid */
431 groups[ngroups++] = gid;
432 }
433out:
434 free(cp);
435 *grpcnt = ngroups;
436 return ret;
437}
438# endif /* USE_GETGRSET */
439
397#endif /* _AIX */ 440#endif /* _AIX */
diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h
index 5a04bedad..ecb9feae8 100644
--- a/openbsd-compat/port-aix.h
+++ b/openbsd-compat/port-aix.h
@@ -1,9 +1,9 @@
1/* $Id: port-aix.h,v 1.27 2006/09/18 13:54:33 dtucker Exp $ */ 1/* $Id: port-aix.h,v 1.29 2008/03/09 05:36:55 dtucker Exp $ */
2 2
3/* 3/*
4 * 4 *
5 * Copyright (c) 2001 Gert Doering. All rights reserved. 5 * Copyright (c) 2001 Gert Doering. All rights reserved.
6 * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. 6 * Copyright (c) 2004,2005,2006 Darren Tucker. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -103,4 +103,14 @@ int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t,
103# define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g)) 103# define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g))
104#endif 104#endif
105 105
106/*
107 * We use getgrset in preference to multiple getgrent calls for efficiency
108 * plus it supports NIS and LDAP groups.
109 */
110#if !defined(HAVE_GETGROUPLIST) && defined(HAVE_GETGRSET)
111# define HAVE_GETGROUPLIST
112# define USE_GETGRSET
113int getgrouplist(const char *, gid_t, gid_t *, int *);
114#endif
115
106#endif /* _AIX */ 116#endif /* _AIX */
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
index 2f697e7d9..ad262758e 100644
--- a/openbsd-compat/port-linux.c
+++ b/openbsd-compat/port-linux.c
@@ -1,4 +1,4 @@
1/* $Id: port-linux.c,v 1.4 2007/06/27 22:48:03 djm Exp $ */ 1/* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> 4 * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
@@ -36,7 +36,7 @@
36#include <selinux/get_context_list.h> 36#include <selinux/get_context_list.h>
37 37
38/* Wrapper around is_selinux_enabled() to log its return value once only */ 38/* Wrapper around is_selinux_enabled() to log its return value once only */
39static int 39int
40ssh_selinux_enabled(void) 40ssh_selinux_enabled(void)
41{ 41{
42 static int enabled = -1; 42 static int enabled = -1;
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
index 05e520e1c..5cd39bf83 100644
--- a/openbsd-compat/port-linux.h
+++ b/openbsd-compat/port-linux.h
@@ -1,4 +1,4 @@
1/* $Id: port-linux.h,v 1.1 2006/04/22 11:26:08 djm Exp $ */ 1/* $Id: port-linux.h,v 1.2 2008/03/26 20:27:21 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Damien Miller <djm@openbsd.org> 4 * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
@@ -20,6 +20,7 @@
20#define _PORT_LINUX_H 20#define _PORT_LINUX_H
21 21
22#ifdef WITH_SELINUX 22#ifdef WITH_SELINUX
23int ssh_selinux_enabled(void);
23void ssh_selinux_setup_pty(char *, const char *); 24void ssh_selinux_setup_pty(char *, const char *);
24void ssh_selinux_setup_exec_context(char *); 25void ssh_selinux_setup_exec_context(char *);
25#endif 26#endif
diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c
index 276474db8..ddc92d0f3 100644
--- a/openbsd-compat/port-tun.c
+++ b/openbsd-compat/port-tun.c
@@ -29,6 +29,7 @@
29#include <string.h> 29#include <string.h>
30#include <unistd.h> 30#include <unistd.h>
31 31
32#include "openbsd-compat/sys-queue.h"
32#include "log.h" 33#include "log.h"
33#include "misc.h" 34#include "misc.h"
34#include "buffer.h" 35#include "buffer.h"
diff --git a/openbsd-compat/regress/closefromtest.c b/openbsd-compat/regress/closefromtest.c
index bb129fa16..145b09d7b 100644
--- a/openbsd-compat/regress/closefromtest.c
+++ b/openbsd-compat/regress/closefromtest.c
@@ -57,4 +57,5 @@ main(void)
57 for (i = 0; i < NUM_OPENS; i++) 57 for (i = 0; i < NUM_OPENS; i++)
58 if (close(fds[i]) != -1) 58 if (close(fds[i]) != -1)
59 fail("failed to close from lowest fd"); 59 fail("failed to close from lowest fd");
60 return 0;
60} 61}
diff --git a/openbsd-compat/regress/strtonumtest.c b/openbsd-compat/regress/strtonumtest.c
index cb8585129..50ca5bd22 100644
--- a/openbsd-compat/regress/strtonumtest.c
+++ b/openbsd-compat/regress/strtonumtest.c
@@ -21,6 +21,20 @@
21#include <stdio.h> 21#include <stdio.h>
22#include <stdlib.h> 22#include <stdlib.h>
23 23
24/* LLONG_MAX is known as LONGLONG_MAX on AIX */
25#if defined(LONGLONG_MAX) && !defined(LLONG_MAX)
26# define LLONG_MAX LONGLONG_MAX
27# define LLONG_MIN LONGLONG_MIN
28#endif
29
30/* LLONG_MAX is known as LONG_LONG_MAX on HP-UX */
31#if defined(LONG_LONG_MAX) && !defined(LLONG_MAX)
32# define LLONG_MAX LONG_LONG_MAX
33# define LLONG_MIN LONG_LONG_MIN
34#endif
35
36long long strtonum(const char *, long long, long long, const char **);
37
24int fail; 38int fail;
25 39
26void 40void
diff --git a/openbsd-compat/rresvport.c b/openbsd-compat/rresvport.c
index 5b0275ce0..1cd61e58d 100644
--- a/openbsd-compat/rresvport.c
+++ b/openbsd-compat/rresvport.c
@@ -44,6 +44,7 @@
44#include <errno.h> 44#include <errno.h>
45#include <stdlib.h> 45#include <stdlib.h>
46#include <string.h> 46#include <string.h>
47#include <unistd.h>
47 48
48#if 0 49#if 0
49int 50int
diff --git a/openbsd-compat/setenv.c b/openbsd-compat/setenv.c
index b52a99c2c..e2a8b6dd3 100644
--- a/openbsd-compat/setenv.c
+++ b/openbsd-compat/setenv.c
@@ -47,7 +47,7 @@ extern char **environ;
47 * Explicitly removes '=' in argument name. 47 * Explicitly removes '=' in argument name.
48 */ 48 */
49static char * 49static char *
50__findenv(const char *name, int *offset) 50__findenv(const char *name, size_t *offset)
51{ 51{
52 extern char **environ; 52 extern char **environ;
53 int len, i; 53 int len, i;
@@ -82,7 +82,7 @@ setenv(const char *name, const char *value, int rewrite)
82{ 82{
83 static char **lastenv; /* last value of environ */ 83 static char **lastenv; /* last value of environ */
84 char *C; 84 char *C;
85 int l_value, offset; 85 size_t l_value, offset;
86 86
87 if (*value == '=') /* no `=' in value */ 87 if (*value == '=') /* no `=' in value */
88 ++value; 88 ++value;
@@ -133,7 +133,7 @@ void
133unsetenv(const char *name) 133unsetenv(const char *name)
134{ 134{
135 char **P; 135 char **P;
136 int offset; 136 size_t offset;
137 137
138 while (__findenv(name, &offset)) /* if set multiple times */ 138 while (__findenv(name, &offset)) /* if set multiple times */
139 for (P = &environ[offset];; ++P) 139 for (P = &environ[offset];; ++P)
diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c
index b511f6649..2965f689e 100644
--- a/openbsd-compat/setproctitle.c
+++ b/openbsd-compat/setproctitle.c
@@ -43,6 +43,8 @@
43#endif 43#endif
44#include <string.h> 44#include <string.h>
45 45
46#include <vis.h>
47
46#define SPT_NONE 0 /* don't use it at all */ 48#define SPT_NONE 0 /* don't use it at all */
47#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ 49#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */
48#define SPT_REUSEARGV 2 /* cover argv with title information */ 50#define SPT_REUSEARGV 2 /* cover argv with title information */
@@ -121,7 +123,7 @@ setproctitle(const char *fmt, ...)
121{ 123{
122#if SPT_TYPE != SPT_NONE 124#if SPT_TYPE != SPT_NONE
123 va_list ap; 125 va_list ap;
124 char buf[1024]; 126 char buf[1024], ptitle[1024];
125 size_t len; 127 size_t len;
126 extern char *__progname; 128 extern char *__progname;
127#if SPT_TYPE == SPT_PSTAT 129#if SPT_TYPE == SPT_PSTAT
@@ -142,14 +144,16 @@ setproctitle(const char *fmt, ...)
142 vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); 144 vsnprintf(buf + len, sizeof(buf) - len , fmt, ap);
143 } 145 }
144 va_end(ap); 146 va_end(ap);
147 strnvis(ptitle, buf, sizeof(ptitle),
148 VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL);
145 149
146#if SPT_TYPE == SPT_PSTAT 150#if SPT_TYPE == SPT_PSTAT
147 pst.pst_command = buf; 151 pst.pst_command = ptitle;
148 pstat(PSTAT_SETCMD, pst, strlen(buf), 0, 0); 152 pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0);
149#elif SPT_TYPE == SPT_REUSEARGV 153#elif SPT_TYPE == SPT_REUSEARGV
150/* debug("setproctitle: copy \"%s\" into len %d", 154/* debug("setproctitle: copy \"%s\" into len %d",
151 buf, argv_env_len); */ 155 buf, argv_env_len); */
152 len = strlcpy(argv_start, buf, argv_env_len); 156 len = strlcpy(argv_start, ptitle, argv_env_len);
153 for(; len < argv_env_len; len++) 157 for(; len < argv_env_len; len++)
154 argv_start[len] = SPT_PADCHAR; 158 argv_start[len] = SPT_PADCHAR;
155#endif 159#endif
diff --git a/openbsd-compat/sigact.c b/openbsd-compat/sigact.c
index 8b8e4dd2c..d67845cf1 100644
--- a/openbsd-compat/sigact.c
+++ b/openbsd-compat/sigact.c
@@ -36,6 +36,7 @@
36/* OPENBSD ORIGINAL: lib/libcurses/base/sigaction.c */ 36/* OPENBSD ORIGINAL: lib/libcurses/base/sigaction.c */
37 37
38#include "includes.h" 38#include "includes.h"
39#include <errno.h>
39#include <signal.h> 40#include <signal.h>
40#include "sigact.h" 41#include "sigact.h"
41 42
@@ -47,28 +48,39 @@
47int 48int
48sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) 49sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact)
49{ 50{
50 return sigvec(sig, &(sigact->sv), &(osigact->sv)); 51 return sigvec(sig, sigact ? &sigact->sv : NULL,
52 osigact ? &osigact->sv : NULL);
51} 53}
52 54
53int 55int
54sigemptyset (sigset_t * mask) 56sigemptyset (sigset_t *mask)
55{ 57{
58 if (!mask) {
59 errno = EINVAL;
60 return -1;
61 }
56 *mask = 0; 62 *mask = 0;
57 return 0; 63 return 0;
58} 64}
59 65
60int 66int
61sigprocmask (int mode, sigset_t * mask, sigset_t * omask) 67sigprocmask (int mode, sigset_t *mask, sigset_t *omask)
62{ 68{
63 sigset_t current = sigsetmask(0); 69 sigset_t current = sigsetmask(0);
64 70
65 if (omask) *omask = current; 71 if (!mask) {
72 errno = EINVAL;
73 return -1;
74 }
66 75
67 if (mode==SIG_BLOCK) 76 if (omask)
77 *omask = current;
78
79 if (mode == SIG_BLOCK)
68 current |= *mask; 80 current |= *mask;
69 else if (mode==SIG_UNBLOCK) 81 else if (mode == SIG_UNBLOCK)
70 current &= ~*mask; 82 current &= ~*mask;
71 else if (mode==SIG_SETMASK) 83 else if (mode == SIG_SETMASK)
72 current = *mask; 84 current = *mask;
73 85
74 sigsetmask(current); 86 sigsetmask(current);
@@ -76,28 +88,44 @@ sigprocmask (int mode, sigset_t * mask, sigset_t * omask)
76} 88}
77 89
78int 90int
79sigsuspend (sigset_t * mask) 91sigsuspend (sigset_t *mask)
80{ 92{
93 if (!mask) {
94 errno = EINVAL;
95 return -1;
96 }
81 return sigpause(*mask); 97 return sigpause(*mask);
82} 98}
83 99
84int 100int
85sigdelset (sigset_t * mask, int sig) 101sigdelset (sigset_t *mask, int sig)
86{ 102{
103 if (!mask) {
104 errno = EINVAL;
105 return -1;
106 }
87 *mask &= ~sigmask(sig); 107 *mask &= ~sigmask(sig);
88 return 0; 108 return 0;
89} 109}
90 110
91int 111int
92sigaddset (sigset_t * mask, int sig) 112sigaddset (sigset_t *mask, int sig)
93{ 113{
114 if (!mask) {
115 errno = EINVAL;
116 return -1;
117 }
94 *mask |= sigmask(sig); 118 *mask |= sigmask(sig);
95 return 0; 119 return 0;
96} 120}
97 121
98int 122int
99sigismember (sigset_t * mask, int sig) 123sigismember (sigset_t *mask, int sig)
100{ 124{
125 if (!mask) {
126 errno = EINVAL;
127 return -1;
128 }
101 return (*mask & sigmask(sig)) != 0; 129 return (*mask & sigmask(sig)) != 0;
102} 130}
103 131
diff --git a/openbsd-compat/sys-queue.h b/openbsd-compat/sys-queue.h
index 402343324..5cf0587bd 100644
--- a/openbsd-compat/sys-queue.h
+++ b/openbsd-compat/sys-queue.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: queue.h,v 1.25 2004/04/08 16:08:21 henning Exp $ */ 1/* $OpenBSD: queue.h,v 1.32 2007/04/30 18:42:34 pedro Exp $ */
2/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ 2/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3 3
4/* 4/*
@@ -167,6 +167,12 @@
167 * For details on the use of these macros, see the queue(3) manual page. 167 * For details on the use of these macros, see the queue(3) manual page.
168 */ 168 */
169 169
170#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
171#define _Q_INVALIDATE(a) (a) = ((void *)-1)
172#else
173#define _Q_INVALIDATE(a)
174#endif
175
170/* 176/*
171 * Singly-linked List definitions. 177 * Singly-linked List definitions.
172 */ 178 */
@@ -229,13 +235,14 @@ struct { \
229#define SLIST_REMOVE(head, elm, type, field) do { \ 235#define SLIST_REMOVE(head, elm, type, field) do { \
230 if ((head)->slh_first == (elm)) { \ 236 if ((head)->slh_first == (elm)) { \
231 SLIST_REMOVE_HEAD((head), field); \ 237 SLIST_REMOVE_HEAD((head), field); \
232 } \ 238 } else { \
233 else { \
234 struct type *curelm = (head)->slh_first; \ 239 struct type *curelm = (head)->slh_first; \
235 while( curelm->field.sle_next != (elm) ) \ 240 \
241 while (curelm->field.sle_next != (elm)) \
236 curelm = curelm->field.sle_next; \ 242 curelm = curelm->field.sle_next; \
237 curelm->field.sle_next = \ 243 curelm->field.sle_next = \
238 curelm->field.sle_next->field.sle_next; \ 244 curelm->field.sle_next->field.sle_next; \
245 _Q_INVALIDATE((elm)->field.sle_next); \
239 } \ 246 } \
240} while (0) 247} while (0)
241 248
@@ -303,6 +310,8 @@ struct { \
303 (elm)->field.le_next->field.le_prev = \ 310 (elm)->field.le_next->field.le_prev = \
304 (elm)->field.le_prev; \ 311 (elm)->field.le_prev; \
305 *(elm)->field.le_prev = (elm)->field.le_next; \ 312 *(elm)->field.le_prev = (elm)->field.le_next; \
313 _Q_INVALIDATE((elm)->field.le_prev); \
314 _Q_INVALIDATE((elm)->field.le_next); \
306} while (0) 315} while (0)
307 316
308#define LIST_REPLACE(elm, elm2, field) do { \ 317#define LIST_REPLACE(elm, elm2, field) do { \
@@ -311,6 +320,8 @@ struct { \
311 &(elm2)->field.le_next; \ 320 &(elm2)->field.le_next; \
312 (elm2)->field.le_prev = (elm)->field.le_prev; \ 321 (elm2)->field.le_prev = (elm)->field.le_prev; \
313 *(elm2)->field.le_prev = (elm2); \ 322 *(elm2)->field.le_prev = (elm2); \
323 _Q_INVALIDATE((elm)->field.le_prev); \
324 _Q_INVALIDATE((elm)->field.le_next); \
314} while (0) 325} while (0)
315 326
316/* 327/*
@@ -369,8 +380,8 @@ struct { \
369 (listelm)->field.sqe_next = (elm); \ 380 (listelm)->field.sqe_next = (elm); \
370} while (0) 381} while (0)
371 382
372#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ 383#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
373 if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ 384 if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
374 (head)->sqh_last = &(head)->sqh_first; \ 385 (head)->sqh_last = &(head)->sqh_first; \
375} while (0) 386} while (0)
376 387
@@ -465,6 +476,8 @@ struct { \
465 else \ 476 else \
466 (head)->tqh_last = (elm)->field.tqe_prev; \ 477 (head)->tqh_last = (elm)->field.tqe_prev; \
467 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ 478 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
479 _Q_INVALIDATE((elm)->field.tqe_prev); \
480 _Q_INVALIDATE((elm)->field.tqe_next); \
468} while (0) 481} while (0)
469 482
470#define TAILQ_REPLACE(head, elm, elm2, field) do { \ 483#define TAILQ_REPLACE(head, elm, elm2, field) do { \
@@ -475,6 +488,8 @@ struct { \
475 (head)->tqh_last = &(elm2)->field.tqe_next; \ 488 (head)->tqh_last = &(elm2)->field.tqe_next; \
476 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ 489 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
477 *(elm2)->field.tqe_prev = (elm2); \ 490 *(elm2)->field.tqe_prev = (elm2); \
491 _Q_INVALIDATE((elm)->field.tqe_prev); \
492 _Q_INVALIDATE((elm)->field.tqe_next); \
478} while (0) 493} while (0)
479 494
480/* 495/*
@@ -575,6 +590,8 @@ struct { \
575 else \ 590 else \
576 (elm)->field.cqe_prev->field.cqe_next = \ 591 (elm)->field.cqe_prev->field.cqe_next = \
577 (elm)->field.cqe_next; \ 592 (elm)->field.cqe_next; \
593 _Q_INVALIDATE((elm)->field.cqe_prev); \
594 _Q_INVALIDATE((elm)->field.cqe_next); \
578} while (0) 595} while (0)
579 596
580#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ 597#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
@@ -588,6 +605,8 @@ struct { \
588 (head).cqh_first = (elm2); \ 605 (head).cqh_first = (elm2); \
589 else \ 606 else \
590 (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ 607 (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
608 _Q_INVALIDATE((elm)->field.cqe_prev); \
609 _Q_INVALIDATE((elm)->field.cqe_next); \
591} while (0) 610} while (0)
592 611
593#endif /* !_FAKE_QUEUE_H_ */ 612#endif /* !_FAKE_QUEUE_H_ */
diff --git a/openbsd-compat/sys-tree.h b/openbsd-compat/sys-tree.h
index c80b90b21..d4949b5e7 100644
--- a/openbsd-compat/sys-tree.h
+++ b/openbsd-compat/sys-tree.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ 1/* $OpenBSD: tree.h,v 1.10 2007/10/29 23:49:41 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * All rights reserved. 4 * All rights reserved.
@@ -289,7 +289,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
289 (x) != NULL; \ 289 (x) != NULL; \
290 (x) = SPLAY_NEXT(name, head, x)) 290 (x) = SPLAY_NEXT(name, head, x))
291 291
292/* Macros that define a red-back tree */ 292/* Macros that define a red-black tree */
293#define RB_HEAD(name, type) \ 293#define RB_HEAD(name, type) \
294struct name { \ 294struct name { \
295 struct type *rbh_root; /* root of the tree */ \ 295 struct type *rbh_root; /* root of the tree */ \
@@ -381,9 +381,9 @@ void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
381struct type *name##_RB_REMOVE(struct name *, struct type *); \ 381struct type *name##_RB_REMOVE(struct name *, struct type *); \
382struct type *name##_RB_INSERT(struct name *, struct type *); \ 382struct type *name##_RB_INSERT(struct name *, struct type *); \
383struct type *name##_RB_FIND(struct name *, struct type *); \ 383struct type *name##_RB_FIND(struct name *, struct type *); \
384struct type *name##_RB_NEXT(struct name *, struct type *); \ 384struct type *name##_RB_NEXT(struct type *); \
385struct type *name##_RB_MINMAX(struct name *, int); \ 385struct type *name##_RB_MINMAX(struct name *, int);
386 \ 386
387 387
388/* Main rb operation. 388/* Main rb operation.
389 * Moves node close to the key of elm to top 389 * Moves node close to the key of elm to top
@@ -626,7 +626,7 @@ name##_RB_FIND(struct name *head, struct type *elm) \
626} \ 626} \
627 \ 627 \
628struct type * \ 628struct type * \
629name##_RB_NEXT(struct name *head, struct type *elm) \ 629name##_RB_NEXT(struct type *elm) \
630{ \ 630{ \
631 if (RB_RIGHT(elm, field)) { \ 631 if (RB_RIGHT(elm, field)) { \
632 elm = RB_RIGHT(elm, field); \ 632 elm = RB_RIGHT(elm, field); \
@@ -667,13 +667,13 @@ name##_RB_MINMAX(struct name *head, int val) \
667#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) 667#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
668#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) 668#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
669#define RB_FIND(name, x, y) name##_RB_FIND(x, y) 669#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
670#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y) 670#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
671#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) 671#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
672#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) 672#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
673 673
674#define RB_FOREACH(x, name, head) \ 674#define RB_FOREACH(x, name, head) \
675 for ((x) = RB_MIN(name, head); \ 675 for ((x) = RB_MIN(name, head); \
676 (x) != NULL; \ 676 (x) != NULL; \
677 (x) = name##_RB_NEXT(head, x)) 677 (x) = name##_RB_NEXT(x))
678 678
679#endif /* _SYS_TREE_H_ */ 679#endif /* _SYS_TREE_H_ */
diff --git a/packet.c b/packet.c
index f82a63c47..8abd43eb4 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.148 2007/06/07 19:37:34 pvalchev Exp $ */ 1/* $OpenBSD: packet.c,v 1.157 2008/07/10 18:08:11 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
@@ -136,12 +136,18 @@ static int server_side = 0;
136/* Set to true if we are authenticated. */ 136/* Set to true if we are authenticated. */
137static int after_authentication = 0; 137static int after_authentication = 0;
138 138
139int keep_alive_timeouts = 0;
140
141/* Set to the maximum time that we will wait to send or receive a packet */
142static int packet_timeout_ms = -1;
143
139/* Session key information for Encryption and MAC */ 144/* Session key information for Encryption and MAC */
140Newkeys *newkeys[MODE_MAX]; 145Newkeys *newkeys[MODE_MAX];
141static struct packet_state { 146static struct packet_state {
142 u_int32_t seqnr; 147 u_int32_t seqnr;
143 u_int32_t packets; 148 u_int32_t packets;
144 u_int64_t blocks; 149 u_int64_t blocks;
150 u_int64_t bytes;
145} p_read, p_send; 151} p_read, p_send;
146 152
147static u_int64_t max_blocks_in, max_blocks_out; 153static u_int64_t max_blocks_in, max_blocks_out;
@@ -186,7 +192,21 @@ packet_set_connection(int fd_in, int fd_out)
186 buffer_init(&outgoing_packet); 192 buffer_init(&outgoing_packet);
187 buffer_init(&incoming_packet); 193 buffer_init(&incoming_packet);
188 TAILQ_INIT(&outgoing); 194 TAILQ_INIT(&outgoing);
195 p_send.packets = p_read.packets = 0;
196 }
197}
198
199void
200packet_set_timeout(int timeout, int count)
201{
202 if (timeout == 0 || count == 0) {
203 packet_timeout_ms = -1;
204 return;
189 } 205 }
206 if ((INT_MAX / 1000) / count < timeout)
207 packet_timeout_ms = INT_MAX;
208 else
209 packet_timeout_ms = timeout * count * 1000;
190} 210}
191 211
192/* Returns 1 if remote host is connected via socket, 0 if not. */ 212/* Returns 1 if remote host is connected via socket, 0 if not. */
@@ -293,18 +313,25 @@ packet_get_ssh1_cipher(void)
293} 313}
294 314
295void 315void
296packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets) 316packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets,
317 u_int64_t *bytes)
297{ 318{
298 struct packet_state *state; 319 struct packet_state *state;
299 320
300 state = (mode == MODE_IN) ? &p_read : &p_send; 321 state = (mode == MODE_IN) ? &p_read : &p_send;
301 *seqnr = state->seqnr; 322 if (seqnr)
302 *blocks = state->blocks; 323 *seqnr = state->seqnr;
303 *packets = state->packets; 324 if (blocks)
325 *blocks = state->blocks;
326 if (packets)
327 *packets = state->packets;
328 if (bytes)
329 *bytes = state->bytes;
304} 330}
305 331
306void 332void
307packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets) 333packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets,
334 u_int64_t bytes)
308{ 335{
309 struct packet_state *state; 336 struct packet_state *state;
310 337
@@ -312,6 +339,7 @@ packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets)
312 state->seqnr = seqnr; 339 state->seqnr = seqnr;
313 state->blocks = blocks; 340 state->blocks = blocks;
314 state->packets = packets; 341 state->packets = packets;
342 state->bytes = bytes;
315} 343}
316 344
317/* returns 1 if connection is via ipv4 */ 345/* returns 1 if connection is via ipv4 */
@@ -590,7 +618,8 @@ packet_send1(void)
590 fprintf(stderr, "encrypted: "); 618 fprintf(stderr, "encrypted: ");
591 buffer_dump(&output); 619 buffer_dump(&output);
592#endif 620#endif
593 621 p_send.packets++;
622 p_send.bytes += len + buffer_len(&outgoing_packet);
594 buffer_clear(&outgoing_packet); 623 buffer_clear(&outgoing_packet);
595 624
596 /* 625 /*
@@ -816,6 +845,7 @@ packet_send2_wrapped(void)
816 if (!(datafellows & SSH_BUG_NOREKEY)) 845 if (!(datafellows & SSH_BUG_NOREKEY))
817 fatal("XXX too many packets with same key"); 846 fatal("XXX too many packets with same key");
818 p_send.blocks += (packet_length + 4) / block_size; 847 p_send.blocks += (packet_length + 4) / block_size;
848 p_send.bytes += packet_length + 4;
819 buffer_clear(&outgoing_packet); 849 buffer_clear(&outgoing_packet);
820 850
821 if (type == SSH2_MSG_NEWKEYS) 851 if (type == SSH2_MSG_NEWKEYS)
@@ -889,9 +919,11 @@ packet_send(void)
889int 919int
890packet_read_seqnr(u_int32_t *seqnr_p) 920packet_read_seqnr(u_int32_t *seqnr_p)
891{ 921{
892 int type, len; 922 int type, len, ret, ms_remain;
893 fd_set *setp; 923 fd_set *setp;
894 char buf[8192]; 924 char buf[8192];
925 struct timeval timeout, start, *timeoutp = NULL;
926
895 DBG(debug("packet_read()")); 927 DBG(debug("packet_read()"));
896 928
897 setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS), 929 setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),
@@ -923,11 +955,35 @@ packet_read_seqnr(u_int32_t *seqnr_p)
923 sizeof(fd_mask)); 955 sizeof(fd_mask));
924 FD_SET(connection_in, setp); 956 FD_SET(connection_in, setp);
925 957
958 if (packet_timeout_ms > 0) {
959 ms_remain = packet_timeout_ms;
960 timeoutp = &timeout;
961 }
926 /* Wait for some data to arrive. */ 962 /* Wait for some data to arrive. */
927 while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && 963 for (;;) {
928 (errno == EAGAIN || errno == EINTR)) 964 if (packet_timeout_ms != -1) {
929 ; 965 ms_to_timeval(&timeout, ms_remain);
930 966 gettimeofday(&start, NULL);
967 }
968 if ((ret = select(connection_in + 1, setp, NULL,
969 NULL, timeoutp)) >= 0)
970 break;
971 if (errno != EAGAIN && errno != EINTR &&
972 errno != EWOULDBLOCK)
973 break;
974 if (packet_timeout_ms == -1)
975 continue;
976 ms_subtract_diff(&start, &ms_remain);
977 if (ms_remain <= 0) {
978 ret = 0;
979 break;
980 }
981 }
982 if (ret == 0) {
983 logit("Connection to %.200s timed out while "
984 "waiting to read", get_remote_ipaddr());
985 cleanup_exit(255);
986 }
931 /* Read data from the socket. */ 987 /* Read data from the socket. */
932 len = read(connection_in, buf, sizeof(buf)); 988 len = read(connection_in, buf, sizeof(buf));
933 if (len == 0) { 989 if (len == 0) {
@@ -1052,6 +1108,8 @@ packet_read_poll1(void)
1052 buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), 1108 buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
1053 buffer_len(&compression_buffer)); 1109 buffer_len(&compression_buffer));
1054 } 1110 }
1111 p_read.packets++;
1112 p_read.bytes += padded_len + 4;
1055 type = buffer_get_char(&incoming_packet); 1113 type = buffer_get_char(&incoming_packet);
1056 if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) 1114 if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
1057 packet_disconnect("Invalid ssh1 packet type: %d", type); 1115 packet_disconnect("Invalid ssh1 packet type: %d", type);
@@ -1140,6 +1198,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
1140 if (!(datafellows & SSH_BUG_NOREKEY)) 1198 if (!(datafellows & SSH_BUG_NOREKEY))
1141 fatal("XXX too many packets with same key"); 1199 fatal("XXX too many packets with same key");
1142 p_read.blocks += (packet_length + 4) / block_size; 1200 p_read.blocks += (packet_length + 4) / block_size;
1201 p_read.bytes += packet_length + 4;
1143 1202
1144 /* get padlen */ 1203 /* get padlen */
1145 cp = buffer_ptr(&incoming_packet); 1204 cp = buffer_ptr(&incoming_packet);
@@ -1192,10 +1251,13 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
1192 for (;;) { 1251 for (;;) {
1193 if (compat20) { 1252 if (compat20) {
1194 type = packet_read_poll2(seqnr_p); 1253 type = packet_read_poll2(seqnr_p);
1195 if (type) 1254 if (type) {
1255 keep_alive_timeouts = 0;
1196 DBG(debug("received packet type %d", type)); 1256 DBG(debug("received packet type %d", type));
1257 }
1197 switch (type) { 1258 switch (type) {
1198 case SSH2_MSG_IGNORE: 1259 case SSH2_MSG_IGNORE:
1260 debug3("Received SSH2_MSG_IGNORE");
1199 break; 1261 break;
1200 case SSH2_MSG_DEBUG: 1262 case SSH2_MSG_DEBUG:
1201 packet_get_char(); 1263 packet_get_char();
@@ -1328,6 +1390,12 @@ packet_get_string(u_int *length_ptr)
1328 return buffer_get_string(&incoming_packet, length_ptr); 1390 return buffer_get_string(&incoming_packet, length_ptr);
1329} 1391}
1330 1392
1393void *
1394packet_get_string_ptr(u_int *length_ptr)
1395{
1396 return buffer_get_string_ptr(&incoming_packet, length_ptr);
1397}
1398
1331/* 1399/*
1332 * Sends a diagnostic message from the server to the client. This message 1400 * Sends a diagnostic message from the server to the client. This message
1333 * can be sent at any time (but not while constructing another message). The 1401 * can be sent at any time (but not while constructing another message). The
@@ -1422,16 +1490,19 @@ packet_write_poll(void)
1422 1490
1423 if (len > 0) { 1491 if (len > 0) {
1424 len = write(connection_out, buffer_ptr(&output), len); 1492 len = write(connection_out, buffer_ptr(&output), len);
1425 if (len <= 0) { 1493 if (len == -1) {
1426 if (errno == EAGAIN) 1494 if (errno == EINTR || errno == EAGAIN ||
1495 errno == EWOULDBLOCK)
1427 return; 1496 return;
1428 else 1497 fatal("Write failed: %.100s", strerror(errno));
1429 fatal("Write failed: %.100s", strerror(errno));
1430 } 1498 }
1499 if (len == 0)
1500 fatal("Write connection closed");
1431 buffer_consume(&output, len); 1501 buffer_consume(&output, len);
1432 } 1502 }
1433} 1503}
1434 1504
1505
1435/* 1506/*
1436 * Calls packet_write_poll repeatedly until all pending output data has been 1507 * Calls packet_write_poll repeatedly until all pending output data has been
1437 * written. 1508 * written.
@@ -1441,6 +1512,8 @@ void
1441packet_write_wait(void) 1512packet_write_wait(void)
1442{ 1513{
1443 fd_set *setp; 1514 fd_set *setp;
1515 int ret, ms_remain;
1516 struct timeval start, timeout, *timeoutp = NULL;
1444 1517
1445 setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS), 1518 setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
1446 sizeof(fd_mask)); 1519 sizeof(fd_mask));
@@ -1449,9 +1522,35 @@ packet_write_wait(void)
1449 memset(setp, 0, howmany(connection_out + 1, NFDBITS) * 1522 memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
1450 sizeof(fd_mask)); 1523 sizeof(fd_mask));
1451 FD_SET(connection_out, setp); 1524 FD_SET(connection_out, setp);
1452 while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && 1525
1453 (errno == EAGAIN || errno == EINTR)) 1526 if (packet_timeout_ms > 0) {
1454 ; 1527 ms_remain = packet_timeout_ms;
1528 timeoutp = &timeout;
1529 }
1530 for (;;) {
1531 if (packet_timeout_ms != -1) {
1532 ms_to_timeval(&timeout, ms_remain);
1533 gettimeofday(&start, NULL);
1534 }
1535 if ((ret = select(connection_out + 1, NULL, setp,
1536 NULL, timeoutp)) >= 0)
1537 break;
1538 if (errno != EAGAIN && errno != EINTR &&
1539 errno != EWOULDBLOCK)
1540 break;
1541 if (packet_timeout_ms == -1)
1542 continue;
1543 ms_subtract_diff(&start, &ms_remain);
1544 if (ms_remain <= 0) {
1545 ret = 0;
1546 break;
1547 }
1548 }
1549 if (ret == 0) {
1550 logit("Connection to %.200s timed out while "
1551 "waiting to write", get_remote_ipaddr());
1552 cleanup_exit(255);
1553 }
1455 packet_write_poll(); 1554 packet_write_poll();
1456 } 1555 }
1457 xfree(setp); 1556 xfree(setp);
diff --git a/packet.h b/packet.h
index 21ff45067..03bb87c9b 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.h,v 1.45 2006/03/25 22:22:43 djm Exp $ */ 1/* $OpenBSD: packet.h,v 1.49 2008/07/10 18:08:11 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -21,6 +21,7 @@
21#include <openssl/bn.h> 21#include <openssl/bn.h>
22 22
23void packet_set_connection(int, int); 23void packet_set_connection(int, int);
24void packet_set_timeout(int, int);
24void packet_set_nonblocking(void); 25void packet_set_nonblocking(void);
25int packet_get_connection_in(void); 26int packet_get_connection_in(void);
26int packet_get_connection_out(void); 27int packet_get_connection_out(void);
@@ -58,6 +59,7 @@ void packet_get_bignum(BIGNUM * value);
58void packet_get_bignum2(BIGNUM * value); 59void packet_get_bignum2(BIGNUM * value);
59void *packet_get_raw(u_int *length_ptr); 60void *packet_get_raw(u_int *length_ptr);
60void *packet_get_string(u_int *length_ptr); 61void *packet_get_string(u_int *length_ptr);
62void *packet_get_string_ptr(u_int *length_ptr);
61void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); 63void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2)));
62void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); 64void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
63 65
@@ -66,8 +68,8 @@ int packet_get_keyiv_len(int);
66void packet_get_keyiv(int, u_char *, u_int); 68void packet_get_keyiv(int, u_char *, u_int);
67int packet_get_keycontext(int, u_char *); 69int packet_get_keycontext(int, u_char *);
68void packet_set_keycontext(int, u_char *); 70void packet_set_keycontext(int, u_char *);
69void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *); 71void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *, u_int64_t *);
70void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t); 72void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t, u_int64_t);
71int packet_get_ssh1_cipher(void); 73int packet_get_ssh1_cipher(void);
72void packet_set_iv(int, u_char *); 74void packet_set_iv(int, u_char *);
73 75
@@ -86,6 +88,7 @@ void tty_make_modes(int, struct termios *);
86void tty_parse_modes(int, int *); 88void tty_parse_modes(int, int *);
87 89
88extern u_int max_packet_size; 90extern u_int max_packet_size;
91extern int keep_alive_timeouts;
89int packet_set_maxsize(u_int); 92int packet_set_maxsize(u_int);
90#define packet_get_maxsize() max_packet_size 93#define packet_get_maxsize() max_packet_size
91 94
diff --git a/readconf.c b/readconf.c
index d57d4551d..73f6eb361 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.162 2007/03/20 03:56:12 tedu Exp $ */ 1/* $OpenBSD: readconf.c,v 1.167 2008/06/26 11:46:31 grunk 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
@@ -130,6 +130,7 @@ typedef enum {
130 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 130 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
131 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, 131 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
132 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 132 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
133 oVisualHostKey,
133 oDeprecated, oUnsupported 134 oDeprecated, oUnsupported
134} OpCodes; 135} OpCodes;
135 136
@@ -226,6 +227,7 @@ static struct {
226 { "tunneldevice", oTunnelDevice }, 227 { "tunneldevice", oTunnelDevice },
227 { "localcommand", oLocalCommand }, 228 { "localcommand", oLocalCommand },
228 { "permitlocalcommand", oPermitLocalCommand }, 229 { "permitlocalcommand", oPermitLocalCommand },
230 { "visualhostkey", oVisualHostKey },
229 { NULL, oBadOption } 231 { NULL, oBadOption }
230}; 232};
231 233
@@ -326,6 +328,7 @@ process_config_line(Options *options, const char *host,
326{ 328{
327 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; 329 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
328 int opcode, *intptr, value, value2, scale; 330 int opcode, *intptr, value, value2, scale;
331 LogLevel *log_level_ptr;
329 long long orig, val64; 332 long long orig, val64;
330 size_t len; 333 size_t len;
331 Forward fwd; 334 Forward fwd;
@@ -498,7 +501,6 @@ parse_yesnoask:
498 goto parse_int; 501 goto parse_int;
499 502
500 case oRekeyLimit: 503 case oRekeyLimit:
501 intptr = &options->rekey_limit;
502 arg = strdelim(&s); 504 arg = strdelim(&s);
503 if (!arg || *arg == '\0') 505 if (!arg || *arg == '\0')
504 fatal("%.200s line %d: Missing argument.", filename, linenum); 506 fatal("%.200s line %d: Missing argument.", filename, linenum);
@@ -526,14 +528,14 @@ parse_yesnoask:
526 } 528 }
527 val64 *= scale; 529 val64 *= scale;
528 /* detect integer wrap and too-large limits */ 530 /* detect integer wrap and too-large limits */
529 if ((val64 / scale) != orig || val64 > INT_MAX) 531 if ((val64 / scale) != orig || val64 > UINT_MAX)
530 fatal("%.200s line %d: RekeyLimit too large", 532 fatal("%.200s line %d: RekeyLimit too large",
531 filename, linenum); 533 filename, linenum);
532 if (val64 < 16) 534 if (val64 < 16)
533 fatal("%.200s line %d: RekeyLimit too small", 535 fatal("%.200s line %d: RekeyLimit too small",
534 filename, linenum); 536 filename, linenum);
535 if (*activep && *intptr == -1) 537 if (*activep && options->rekey_limit == -1)
536 *intptr = (int)val64; 538 options->rekey_limit = (u_int32_t)val64;
537 break; 539 break;
538 540
539 case oIdentityFile: 541 case oIdentityFile:
@@ -692,14 +694,14 @@ parse_int:
692 break; 694 break;
693 695
694 case oLogLevel: 696 case oLogLevel:
695 intptr = (int *) &options->log_level; 697 log_level_ptr = &options->log_level;
696 arg = strdelim(&s); 698 arg = strdelim(&s);
697 value = log_level_number(arg); 699 value = log_level_number(arg);
698 if (value == SYSLOG_LEVEL_NOT_SET) 700 if (value == SYSLOG_LEVEL_NOT_SET)
699 fatal("%.200s line %d: unsupported log level '%s'", 701 fatal("%.200s line %d: unsupported log level '%s'",
700 filename, linenum, arg ? arg : "<NONE>"); 702 filename, linenum, arg ? arg : "<NONE>");
701 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET) 703 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
702 *intptr = (LogLevel) value; 704 *log_level_ptr = (LogLevel) value;
703 break; 705 break;
704 706
705 case oLocalForward: 707 case oLocalForward:
@@ -915,6 +917,10 @@ parse_int:
915 intptr = &options->permit_local_command; 917 intptr = &options->permit_local_command;
916 goto parse_flag; 918 goto parse_flag;
917 919
920 case oVisualHostKey:
921 intptr = &options->visual_host_key;
922 goto parse_flag;
923
918 case oDeprecated: 924 case oDeprecated:
919 debug("%s line %d: Deprecated option \"%s\"", 925 debug("%s line %d: Deprecated option \"%s\"",
920 filename, linenum, keyword); 926 filename, linenum, keyword);
@@ -1065,6 +1071,7 @@ initialize_options(Options * options)
1065 options->tun_remote = -1; 1071 options->tun_remote = -1;
1066 options->local_command = NULL; 1072 options->local_command = NULL;
1067 options->permit_local_command = -1; 1073 options->permit_local_command = -1;
1074 options->visual_host_key = -1;
1068} 1075}
1069 1076
1070/* 1077/*
@@ -1199,6 +1206,8 @@ fill_default_options(Options * options)
1199 options->tun_remote = SSH_TUNID_ANY; 1206 options->tun_remote = SSH_TUNID_ANY;
1200 if (options->permit_local_command == -1) 1207 if (options->permit_local_command == -1)
1201 options->permit_local_command = 0; 1208 options->permit_local_command = 0;
1209 if (options->visual_host_key == -1)
1210 options->visual_host_key = 0;
1202 /* options->local_command should not be set by default */ 1211 /* options->local_command should not be set by default */
1203 /* options->proxy_command should not be set by default */ 1212 /* options->proxy_command should not be set by default */
1204 /* options->user will be set in the main program if appropriate */ 1213 /* options->user will be set in the main program if appropriate */
@@ -1255,7 +1264,7 @@ parse_forward(Forward *fwd, const char *fwdspec)
1255 1264
1256 xfree(p); 1265 xfree(p);
1257 1266
1258 if (fwd->listen_port == 0 && fwd->connect_port == 0) 1267 if (fwd->listen_port == 0 || fwd->connect_port == 0)
1259 goto fail_free; 1268 goto fail_free;
1260 1269
1261 if (fwd->connect_host != NULL && 1270 if (fwd->connect_host != NULL &&
diff --git a/readconf.h b/readconf.h
index d484f258e..47c7aef4e 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.71 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: readconf.h,v 1.74 2008/06/26 11:46:31 grunk Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -100,7 +100,7 @@ typedef struct {
100 int clear_forwardings; 100 int clear_forwardings;
101 101
102 int enable_ssh_keysign; 102 int enable_ssh_keysign;
103 int rekey_limit; 103 int64_t rekey_limit;
104 int no_host_authentication_for_localhost; 104 int no_host_authentication_for_localhost;
105 int identities_only; 105 int identities_only;
106 int server_alive_interval; 106 int server_alive_interval;
@@ -120,6 +120,7 @@ typedef struct {
120 120
121 char *local_command; 121 char *local_command;
122 int permit_local_command; 122 int permit_local_command;
123 int visual_host_key;
123 124
124} Options; 125} Options;
125 126
diff --git a/regress/Makefile b/regress/Makefile
index 539956398..3b8ea245b 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,10 +1,15 @@
1# $OpenBSD: Makefile,v 1.42 2006/07/19 13:34:52 dtucker Exp $ 1# $OpenBSD: Makefile,v 1.48 2008/06/28 13:57:25 djm Exp $
2 2
3REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec 3REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec
4tests: $(REGRESS_TARGETS) 4tests: $(REGRESS_TARGETS)
5 5
6# Interop tests are not run by default
7interop interop-tests: t-exec-interop
8
6clean: 9clean:
7 for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done 10 for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done
11 rm -rf $(OBJ).putty
12
8distclean: clean 13distclean: clean
9 14
10LTESTS= connect \ 15LTESTS= connect \
@@ -29,6 +34,7 @@ LTESTS= connect \
29 agent-ptrace \ 34 agent-ptrace \
30 keyscan \ 35 keyscan \
31 keygen-change \ 36 keygen-change \
37 key-options \
32 scp \ 38 scp \
33 sftp \ 39 sftp \
34 sftp-cmds \ 40 sftp-cmds \
@@ -42,8 +48,13 @@ LTESTS= connect \
42 reexec \ 48 reexec \
43 brokenkeys \ 49 brokenkeys \
44 cfgmatch \ 50 cfgmatch \
51 addrmatch \
52 localcommand \
45 forcecommand 53 forcecommand
46 54
55INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
56#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
57
47USER!= id -un 58USER!= id -un
48CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ 59CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \
49 authorized_keys_${USER} known_hosts pidfile \ 60 authorized_keys_${USER} known_hosts pidfile \
@@ -52,9 +63,8 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \
52 rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \ 63 rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \
53 ls.copy banner.in banner.out empty.in \ 64 ls.copy banner.in banner.out empty.in \
54 scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \ 65 scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \
55 sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv 66 sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \
56 67 putty.rsa2
57#LTESTS += ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
58 68
59t1: 69t1:
60 ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv 70 ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv
@@ -96,3 +106,11 @@ t-exec: ${LTESTS:=.sh}
96 echo "run test $${TEST}" ... 1>&2; \ 106 echo "run test $${TEST}" ... 1>&2; \
97 (env SUDO=${SUDO} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ 107 (env SUDO=${SUDO} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
98 done 108 done
109
110t-exec-interop: ${INTEROP_TESTS:=.sh}
111 @if [ "x$?" = "x" ]; then exit 0; fi; \
112 for TEST in ""$?; do \
113 echo "run test $${TEST}" ... 1>&2; \
114 (env SUDO=${SUDO} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
115 done
116
diff --git a/regress/addrmatch.sh b/regress/addrmatch.sh
new file mode 100644
index 000000000..a258f7bb4
--- /dev/null
+++ b/regress/addrmatch.sh
@@ -0,0 +1,42 @@
1# $OpenBSD: addrmatch.sh,v 1.1 2008/06/10 05:23:32 dtucker Exp $
2# Placed in the Public Domain.
3
4tid="address match"
5
6mv $OBJ/sshd_proxy $OBJ/sshd_proxy_orig
7
8run_trial()
9{
10 user="$1"; addr="$2"; host="$3"; expected="$4"; descr="$5"
11
12 verbose "test $descr for $user $addr $host"
13 result=`${SSHD} -f $OBJ/sshd_proxy -T \
14 -C user=${user},addr=${addr},host=${host} | \
15 awk '/passwordauthentication/ {print $2}'`
16 if [ "$result" != "$expected" ]; then
17 fail "failed for $user $addr $host: expected $expected, got $result"
18 fi
19}
20
21cp $OBJ/sshd_proxy_orig $OBJ/sshd_proxy
22cat >>$OBJ/sshd_proxy <<EOD
23PasswordAuthentication no
24Match Address 192.168.0.0/16,!192.168.30.0/24,10.0.0.0/8,host.example.com
25 PasswordAuthentication yes
26Match Address 1.1.1.1,::1,!::3,2000::/16
27 PasswordAuthentication yes
28EOD
29
30run_trial user 192.168.0.1 somehost yes "permit, first entry"
31run_trial user 192.168.30.1 somehost no "deny, negative match"
32run_trial user 19.0.0.1 somehost no "deny, no match"
33run_trial user 10.255.255.254 somehost yes "permit, list middle"
34run_trial user 192.168.30.1 192.168.0.1 no "deny, faked IP in hostname"
35run_trial user 1.1.1.1 somehost.example.com yes "permit, bare IP4 address"
36test "$TEST_SSH_IPV6" = "no" && exit
37run_trial user ::1 somehost.example.com yes "permit, bare IP6 address"
38run_trial user ::2 somehost.exaple.com no "deny IPv6"
39run_trial user ::3 somehost no "deny IP6 negated"
40run_trial user ::4 somehost no "deny, IP6 no match"
41run_trial user 2000::1 somehost yes "permit, IP6 network"
42run_trial user 2001::1 somehost no "deny, IP6 network"
diff --git a/regress/agent-getpeereid.sh b/regress/agent-getpeereid.sh
index d71324241..5d7f73291 100644
--- a/regress/agent-getpeereid.sh
+++ b/regress/agent-getpeereid.sh
@@ -1,11 +1,11 @@
1# $OpenBSD: agent-getpeereid.sh,v 1.3 2006/07/06 12:01:53 grunk Exp $ 1# $OpenBSD: agent-getpeereid.sh,v 1.4 2007/11/25 15:35:09 jmc Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="disallow agent attach from other uid" 4tid="disallow agent attach from other uid"
5 5
6UNPRIV=nobody 6UNPRIV=nobody
7ASOCK=${OBJ}/agent 7ASOCK=${OBJ}/agent
8SSH_AUTH_SOCK=/nonexistant 8SSH_AUTH_SOCK=/nonexistent
9 9
10if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 && \ 10if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 && \
11 grep "#undef.*HAVE_GETPEERUCRED" ${BUILDDIR}/config.h >/dev/null && \ 11 grep "#undef.*HAVE_GETPEERUCRED" ${BUILDDIR}/config.h >/dev/null && \
diff --git a/regress/agent.sh b/regress/agent.sh
index b34487767..094cf694b 100644
--- a/regress/agent.sh
+++ b/regress/agent.sh
@@ -1,9 +1,9 @@
1# $OpenBSD: agent.sh,v 1.6 2002/03/15 13:08:56 markus Exp $ 1# $OpenBSD: agent.sh,v 1.7 2007/11/25 15:35:09 jmc Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="simple agent test" 4tid="simple agent test"
5 5
6SSH_AUTH_SOCK=/nonexistant ${SSHADD} -l > /dev/null 2>&1 6SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1
7if [ $? -ne 2 ]; then 7if [ $? -ne 2 ]; then
8 fail "ssh-add -l did not fail with exit code 2" 8 fail "ssh-add -l did not fail with exit code 2"
9fi 9fi
diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh
index d987dcb97..35c5e52a1 100644
--- a/regress/cfgmatch.sh
+++ b/regress/cfgmatch.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cfgmatch.sh,v 1.2 2006/07/22 01:50:00 dtucker Exp $ 1# $OpenBSD: cfgmatch.sh,v 1.4 2006/12/13 08:36:36 dtucker Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="sshd_config match" 4tid="sshd_config match"
@@ -35,7 +35,7 @@ for p in 1 2; do
35 rm -f $pidfile 35 rm -f $pidfile
36 trace "match permitopen localhost proto $p" 36 trace "match permitopen localhost proto $p"
37 ${SSH} -$p $fwd -F $OBJ/ssh_config -f somehost \ 37 ${SSH} -$p $fwd -F $OBJ/ssh_config -f somehost \
38 "echo \$\$ > $pidfile; exec sleep 100" >>$TEST_SSH_LOGFILE 2>&1 ||\ 38 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' >>$TEST_SSH_LOGFILE 2>&1 ||\
39 fail "match permitopen proto $p sshd failed" 39 fail "match permitopen proto $p sshd failed"
40 sleep 1; 40 sleep 1;
41 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ 41 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
@@ -48,7 +48,7 @@ for p in 1 2; do
48 rm -f $pidfile 48 rm -f $pidfile
49 trace "match permitopen proxy proto $p" 49 trace "match permitopen proxy proto $p"
50 ${SSH} -q -$p $fwd -F $OBJ/ssh_proxy -f somehost \ 50 ${SSH} -q -$p $fwd -F $OBJ/ssh_proxy -f somehost \
51 "echo \$\$ > $pidfile; exec sleep 100" >>$TEST_SSH_LOGFILE 2>&1 ||\ 51 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' >>$TEST_SSH_LOGFILE 2>&1 ||\
52 fail "match permitopen proxy proto $p sshd failed" 52 fail "match permitopen proxy proto $p sshd failed"
53 sleep 1; 53 sleep 1;
54 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ 54 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
@@ -65,7 +65,7 @@ for p in 1 2; do
65 rm -f $pidfile 65 rm -f $pidfile
66 trace "match permitopen proxy w/key opts proto $p" 66 trace "match permitopen proxy w/key opts proto $p"
67 ${SSH} -q -$p $fwd -F $OBJ/ssh_proxy -f somehost \ 67 ${SSH} -q -$p $fwd -F $OBJ/ssh_proxy -f somehost \
68 "echo \$\$ > $pidfile; exec sleep 100" >>$TEST_SSH_LOGFILE 2>&1 ||\ 68 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' >>$TEST_SSH_LOGFILE 2>&1 ||\
69 fail "match permitopen w/key opt proto $p sshd failed" 69 fail "match permitopen w/key opt proto $p sshd failed"
70 sleep 1; 70 sleep 1;
71 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ 71 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
@@ -79,7 +79,7 @@ for p in 1 2; do
79 rm -f $pidfile 79 rm -f $pidfile
80 trace "match permitopen localhost proto $p" 80 trace "match permitopen localhost proto $p"
81 ${SSH} -$p $fwd -F $OBJ/ssh_config -f somehost \ 81 ${SSH} -$p $fwd -F $OBJ/ssh_config -f somehost \
82 "echo \$\$ > $pidfile; exec sleep 100" >>$TEST_SSH_LOGFILE 2>&1 ||\ 82 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' >>$TEST_SSH_LOGFILE 2>&1 ||\
83 fail "match permitopen proto $p sshd failed" 83 fail "match permitopen proto $p sshd failed"
84 sleep 1; 84 sleep 1;
85 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ 85 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
@@ -97,10 +97,29 @@ for p in 1 2; do
97 rm -f $pidfile 97 rm -f $pidfile
98 trace "match permitopen proxy w/key opts proto $p" 98 trace "match permitopen proxy w/key opts proto $p"
99 ${SSH} -q -$p $fwd -F $OBJ/ssh_proxy -f somehost \ 99 ${SSH} -q -$p $fwd -F $OBJ/ssh_proxy -f somehost \
100 "echo \$\$ > $pidfile; exec sleep 100" >>$TEST_SSH_LOGFILE 2>&1 ||\ 100 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' >>$TEST_SSH_LOGFILE 2>&1 ||\
101 fail "match override permitopen proto $p sshd failed" 101 fail "match override permitopen proto $p sshd failed"
102 sleep 1; 102 sleep 1;
103 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ 103 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
104 fail "match override permitopen proto $p" 104 fail "match override permitopen proto $p"
105 stop_client 105 stop_client
106done 106done
107
108cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
109echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy
110echo "Match User NoSuchUser" >>$OBJ/sshd_proxy
111echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy
112
113# Test that a rule that doesn't match doesn't override, plus test a
114# PermitOpen entry that's not at the start of the list
115for p in 1 2; do
116 rm -f $pidfile
117 trace "nomatch permitopen proxy w/key opts proto $p"
118 ${SSH} -q -$p $fwd -F $OBJ/ssh_proxy -f somehost \
119 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' >>$TEST_SSH_LOGFILE 2>&1 ||\
120 fail "nomatch override permitopen proto $p sshd failed"
121 sleep 1;
122 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
123 fail "nomatch override permitopen proto $p"
124 stop_client
125done
diff --git a/regress/cipher-speed.sh b/regress/cipher-speed.sh
index 592511143..d39a829d4 100644
--- a/regress/cipher-speed.sh
+++ b/regress/cipher-speed.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cipher-speed.sh,v 1.2 2005/05/24 04:09:54 djm Exp $ 1# $OpenBSD: cipher-speed.sh,v 1.3 2007/06/07 19:41:46 pvalchev Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="cipher speed" 4tid="cipher speed"
@@ -12,7 +12,7 @@ tries="1 2"
12DATA=/bin/ls 12DATA=/bin/ls
13DATA=/bsd 13DATA=/bsd
14 14
15macs="hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96" 15macs="hmac-sha1 hmac-md5 umac-64@openssh.com hmac-sha1-96 hmac-md5-96"
16ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc 16ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
17 arcfour128 arcfour256 arcfour aes192-cbc aes256-cbc aes128-ctr" 17 arcfour128 arcfour256 arcfour aes192-cbc aes256-cbc aes128-ctr"
18 18
diff --git a/regress/conch-ciphers.sh b/regress/conch-ciphers.sh
new file mode 100644
index 000000000..84b190618
--- /dev/null
+++ b/regress/conch-ciphers.sh
@@ -0,0 +1,30 @@
1# $OpenBSD: conch-ciphers.sh,v 1.2 2008/06/30 10:43:03 djm Exp $
2# Placed in the Public Domain.
3
4tid="conch ciphers"
5
6DATA=/bin/ls
7COPY=${OBJ}/copy
8
9if test "x$REGRESS_INTEROP_CONCH" != "xyes" ; then
10 fatal "conch interop tests not enabled"
11fi
12
13start_sshd
14
15for c in aes256-ctr aes256-cbc aes192-ctr aes192-cbc aes128-ctr aes128-cbc \
16 cast128-cbc blowfish 3des-cbc ; do
17 verbose "$tid: cipher $c"
18 rm -f ${COPY}
19 # XXX the 2nd "cat" seems to be needed because of buggy FD handling
20 # in conch
21 ${CONCH} --identity $OBJ/rsa --port $PORT --user $USER -e none \
22 --known-hosts $OBJ/known_hosts --notty --noagent --nox11 -n \
23 127.0.0.1 "cat ${DATA}" 2>/dev/null | cat > ${COPY}
24 if [ $? -ne 0 ]; then
25 fail "ssh cat $DATA failed"
26 fi
27 cmp ${DATA} ${COPY} || fail "corrupted copy"
28done
29rm -f ${COPY}
30
diff --git a/regress/key-options.sh b/regress/key-options.sh
new file mode 100644
index 000000000..f98d78b30
--- /dev/null
+++ b/regress/key-options.sh
@@ -0,0 +1,71 @@
1# $OpenBSD: key-options.sh,v 1.2 2008/06/30 08:07:34 djm Exp $
2# Placed in the Public Domain.
3
4tid="key options"
5
6origkeys="$OBJ/authkeys_orig"
7authkeys="$OBJ/authorized_keys_${USER}"
8cp $authkeys $origkeys
9
10# Test command= forced command
11for p in 1 2; do
12 for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do
13 sed "s/.*/$c &/" $origkeys >$authkeys
14 verbose "key option proto $p $c"
15 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost echo foo`
16 if [ "$r" = "foo" ]; then
17 fail "key option forced command not restricted"
18 fi
19 if [ "$r" != "bar" ]; then
20 fail "key option forced command not executed"
21 fi
22 done
23done
24
25# Test no-pty
26sed 's/.*/no-pty &/' $origkeys >$authkeys
27for p in 1 2; do
28 verbose "key option proto $p no-pty"
29 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty`
30 if [ -f "$r" ]; then
31 fail "key option failed proto $p no-pty (pty $r)"
32 fi
33done
34
35# Test environment=
36echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy
37sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys
38for p in 1 2; do
39 verbose "key option proto $p environment"
40 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'`
41 if [ "$r" != "bar" ]; then
42 fail "key option environment not set"
43 fi
44done
45
46# Test from= restriction
47start_sshd
48for p in 1 2; do
49 for f in 127.0.0.1 '127.0.0.0\/8'; do
50 cat $origkeys >$authkeys
51 ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true
52 if [ $? -ne 0 ]; then
53 fail "key option proto $p failed without restriction"
54 fi
55
56 sed 's/.*/from="'"$f"'" &/' $origkeys >$authkeys
57 from=`head -1 $authkeys | cut -f1 -d ' '`
58 verbose "key option proto $p $from"
59 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo true'`
60 if [ "$r" = "true" ]; then
61 fail "key option proto $p $from not restricted"
62 fi
63
64 r=`${SSH} -$p -q -F $OBJ/ssh_config somehost 'echo true'`
65 if [ "$r" != "true" ]; then
66 fail "key option proto $p $from not allowed but should be"
67 fi
68 done
69done
70
71rm -f "$origkeys"
diff --git a/regress/localcommand.sh b/regress/localcommand.sh
new file mode 100644
index 000000000..feade7a9d
--- /dev/null
+++ b/regress/localcommand.sh
@@ -0,0 +1,15 @@
1# $OpenBSD: localcommand.sh,v 1.1 2007/10/29 06:57:13 dtucker Exp $
2# Placed in the Public Domain.
3
4tid="localcommand"
5
6echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy
7echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy
8
9for p in 1 2; do
10 verbose "test $tid: proto $p localcommand"
11 a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true`
12 if [ "$a" != "foo" ] ; then
13 fail "$tid proto $p"
14 fi
15done
diff --git a/regress/putty-ciphers.sh b/regress/putty-ciphers.sh
new file mode 100644
index 000000000..40435ef41
--- /dev/null
+++ b/regress/putty-ciphers.sh
@@ -0,0 +1,28 @@
1# $OpenBSD: putty-ciphers.sh,v 1.2 2008/06/30 10:31:11 djm Exp $
2# Placed in the Public Domain.
3
4tid="putty ciphers"
5
6DATA=/bin/ls
7COPY=${OBJ}/copy
8
9if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
10 fatal "putty interop tests not enabled"
11fi
12
13for c in aes blowfish 3des arcfour ; do
14 verbose "$tid: cipher $c"
15 cp ${OBJ}/.putty/sessions/localhost_proxy \
16 ${OBJ}/.putty/sessions/cipher_$c
17 echo "Cipher=$c" >> ${OBJ}/.putty/sessions/cipher_$c
18
19 rm -f ${COPY}
20 env HOME=$PWD ${PLINK} -load cipher_$c -batch -i putty.rsa2 \
21 127.0.0.1 cat ${DATA} > ${COPY}
22 if [ $? -ne 0 ]; then
23 fail "ssh cat $DATA failed"
24 fi
25 cmp ${DATA} ${COPY} || fail "corrupted copy"
26done
27rm -f ${COPY}
28
diff --git a/regress/putty-kex.sh b/regress/putty-kex.sh
new file mode 100644
index 000000000..2534b8575
--- /dev/null
+++ b/regress/putty-kex.sh
@@ -0,0 +1,25 @@
1# $OpenBSD: putty-kex.sh,v 1.2 2008/06/30 10:31:11 djm Exp $
2# Placed in the Public Domain.
3
4tid="putty KEX"
5
6DATA=/bin/ls
7COPY=${OBJ}/copy
8
9if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
10 fatal "putty interop tests not enabled"
11fi
12
13for k in dh-gex-sha1 dh-group1-sha1 dh-group14-sha1 ; do
14 verbose "$tid: kex $k"
15 cp ${OBJ}/.putty/sessions/localhost_proxy \
16 ${OBJ}/.putty/sessions/kex_$k
17 echo "KEX=$k" >> ${OBJ}/.putty/sessions/kex_$k
18
19 env HOME=$PWD ${PLINK} -load kex_$k -batch -i putty.rsa2 \
20 127.0.0.1 true
21 if [ $? -ne 0 ]; then
22 fail "KEX $k failed"
23 fi
24done
25
diff --git a/regress/putty-transfer.sh b/regress/putty-transfer.sh
new file mode 100644
index 000000000..6b21f3be7
--- /dev/null
+++ b/regress/putty-transfer.sh
@@ -0,0 +1,43 @@
1# $OpenBSD: putty-transfer.sh,v 1.2 2008/06/30 10:31:11 djm Exp $
2# Placed in the Public Domain.
3
4tid="putty transfer data"
5
6DATA=/bin/ls
7COPY=${OBJ}/copy
8
9if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
10 fatal "putty interop tests not enabled"
11fi
12
13# XXX support protocol 1 too
14for p in 2; do
15 for c in 0 1 ; do
16 verbose "$tid: proto $p compression $c"
17 rm -f ${COPY}
18 cp ${OBJ}/.putty/sessions/localhost_proxy \
19 ${OBJ}/.putty/sessions/compression_$c
20 echo "Compression=$c" >> ${OBJ}/.putty/sessions/kex_$k
21 env HOME=$PWD ${PLINK} -load compression_$c -batch \
22 -i putty.rsa$p 127.0.0.1 cat ${DATA} > ${COPY}
23 if [ $? -ne 0 ]; then
24 fail "ssh cat $DATA failed"
25 fi
26 cmp ${DATA} ${COPY} || fail "corrupted copy"
27
28 for s in 10 100 1k 32k 64k 128k 256k; do
29 trace "proto $p compression $c dd-size ${s}"
30 rm -f ${COPY}
31 dd if=$DATA obs=${s} 2> /dev/null | \
32 env HOME=$PWD ${PLINK} -load compression_$c \
33 -batch -i putty.rsa$p 127.0.0.1 \
34 "cat > ${COPY}"
35 if [ $? -ne 0 ]; then
36 fail "ssh cat $DATA failed"
37 fi
38 cmp $DATA ${COPY} || fail "corrupted copy"
39 done
40 done
41done
42rm -f ${COPY}
43
diff --git a/regress/sftp-badcmds.sh b/regress/sftp-badcmds.sh
index eac189aaf..b48b1cb01 100644
--- a/regress/sftp-badcmds.sh
+++ b/regress/sftp-badcmds.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: sftp-badcmds.sh,v 1.2 2003/05/15 04:07:12 mouring Exp $ 1# $OpenBSD: sftp-badcmds.sh,v 1.3 2008/03/24 21:46:54 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="sftp invalid commands" 4tid="sftp invalid commands"
@@ -45,17 +45,6 @@ echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
45 || fail "rename nonexist failed" 45 || fail "rename nonexist failed"
46test -f ${COPY}.1 && fail "file exists after rename nonexistent" 46test -f ${COPY}.1 && fail "file exists after rename nonexistent"
47 47
48rm -f ${COPY} ${COPY}.1
49cp $DATA $COPY
50cp $DATA2 ${COPY}.1
51verbose "$tid: rename target exists"
52echo "rename $COPY ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
53 || fail "rename target exists failed"
54test -f ${COPY} || fail "oldname missing after rename target exists"
55test -f ${COPY}.1 || fail "newname missing after rename target exists"
56cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists"
57cmp $DATA2 ${COPY}.1 >/dev/null 2>&1 || fail "corrupted newname after rename target exists"
58
59rm -rf ${COPY} ${COPY}.dd 48rm -rf ${COPY} ${COPY}.dd
60cp $DATA $COPY 49cp $DATA $COPY
61mkdir ${COPY}.dd 50mkdir ${COPY}.dd
diff --git a/regress/sftp-cmds.sh b/regress/sftp-cmds.sh
index 31b21d1f2..3b453c5e8 100644
--- a/regress/sftp-cmds.sh
+++ b/regress/sftp-cmds.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: sftp-cmds.sh,v 1.6 2003/10/07 07:04:52 djm Exp $ 1# $OpenBSD: sftp-cmds.sh,v 1.9 2007/12/12 05:04:03 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4# XXX - TODO: 4# XXX - TODO:
@@ -34,14 +34,22 @@ fi
34# Path with embedded quote 34# Path with embedded quote
35QUOTECOPY=${COPY}".\"blah\"" 35QUOTECOPY=${COPY}".\"blah\""
36QUOTECOPY_ARG=${COPY}'.\"blah\"' 36QUOTECOPY_ARG=${COPY}'.\"blah\"'
37# File with spaces
38SPACECOPY="${COPY} this has spaces.txt"
39SPACECOPY_ARG="${COPY}\ this\ has\ spaces.txt"
40# File with glob metacharacters
41GLOBMETACOPY="${COPY} [metachar].txt"
37 42
38rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 43rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2
39mkdir ${COPY}.dd 44mkdir ${COPY}.dd
40 45
41verbose "$tid: lls" 46verbose "$tid: lls"
42echo "lls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 47(echo "lcd ${OBJ}" ; echo "lls") | ${SFTP} -P ${SFTPSERVER} 2>&1 | \
43 || fail "lls failed" 48 grep copy.dd >/dev/null 2>&1 || fail "lls failed"
44# XXX always successful 49
50verbose "$tid: lls w/path"
51echo "lls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} 2>&1 | \
52 grep copy.dd >/dev/null 2>&1 || fail "lls w/path failed"
45 53
46verbose "$tid: ls" 54verbose "$tid: ls"
47echo "ls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 55echo "ls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
@@ -89,12 +97,27 @@ if [ "$os" != "cygwin" ]; then
89rm -f ${QUOTECOPY} 97rm -f ${QUOTECOPY}
90cp $DATA ${QUOTECOPY} 98cp $DATA ${QUOTECOPY}
91verbose "$tid: get filename with quotes" 99verbose "$tid: get filename with quotes"
92echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 100echo "get \"$QUOTECOPY_ARG\" ${COPY}" | \
93 || fail "put failed" 101 ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed"
94cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes" 102cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes"
95rm -f ${QUOTECOPY} ${COPY} 103rm -f ${QUOTECOPY} ${COPY}
96fi 104fi
97 105
106rm -f "$SPACECOPY" ${COPY}
107cp $DATA "$SPACECOPY"
108verbose "$tid: get filename with spaces"
109echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
110 || fail "get failed"
111cmp ${COPY} "$SPACECOPY" || fail "corrupted copy after get with spaces"
112
113rm -f "$GLOBMETACOPY" ${COPY}
114cp $DATA "$GLOBMETACOPY"
115verbose "$tid: get filename with glob metacharacters"
116echo "get \"${GLOBMETACOPY}\" ${COPY}" | \
117 ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed"
118cmp ${COPY} "$GLOBMETACOPY" || \
119 fail "corrupted copy after get with glob metacharacters"
120
98rm -f ${COPY}.dd/* 121rm -f ${COPY}.dd/*
99verbose "$tid: get to directory" 122verbose "$tid: get to directory"
100echo "get $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 123echo "get $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
@@ -125,18 +148,24 @@ done
125 148
126rm -f ${COPY} 149rm -f ${COPY}
127verbose "$tid: put" 150verbose "$tid: put"
128echo "put $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 151echo "put $DATA $COPY" | \
129 || fail "put failed" 152 ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
130cmp $DATA ${COPY} || fail "corrupted copy after put" 153cmp $DATA ${COPY} || fail "corrupted copy after put"
131 154
132if [ "$os" != "cygwin" ]; then 155if [ "$os" != "cygwin" ]; then
133rm -f ${QUOTECOPY} 156rm -f ${QUOTECOPY}
134verbose "$tid: put filename with quotes" 157verbose "$tid: put filename with quotes"
135echo "put $DATA \"$QUOTECOPY_ARG\"" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 158echo "put $DATA \"$QUOTECOPY_ARG\"" | \
136 || fail "put failed" 159 ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
137cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes" 160cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes"
138fi 161fi
139 162
163rm -f "$SPACECOPY"
164verbose "$tid: put filename with spaces"
165echo "put $DATA ${SPACECOPY_ARG}" | \
166 ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
167cmp $DATA "$SPACECOPY" || fail "corrupted copy after put with spaces"
168
140rm -f ${COPY}.dd/* 169rm -f ${COPY}.dd/*
141verbose "$tid: put to directory" 170verbose "$tid: put to directory"
142echo "put $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 171echo "put $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
@@ -145,7 +174,7 @@ cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put"
145 174
146rm -f ${COPY}.dd/* 175rm -f ${COPY}.dd/*
147verbose "$tid: glob put to directory" 176verbose "$tid: glob put to directory"
148echo "put /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 177echo "put /bin/l? ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
149 || fail "put failed" 178 || fail "put failed"
150for x in $GLOBFILES; do 179for x in $GLOBFILES; do
151 cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" 180 cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put"
@@ -159,7 +188,7 @@ cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put"
159 188
160rm -f ${COPY}.dd/* 189rm -f ${COPY}.dd/*
161verbose "$tid: glob put to local dir" 190verbose "$tid: glob put to local dir"
162(echo "cd ${COPY}.dd"; echo "put /bin/l*") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 191(echo "cd ${COPY}.dd"; echo "put /bin/l?") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
163 || fail "put failed" 192 || fail "put failed"
164for x in $GLOBFILES; do 193for x in $GLOBFILES; do
165 cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" 194 cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put"
@@ -172,8 +201,9 @@ test -f ${COPY}.1 || fail "missing file after rename"
172cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename" 201cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename"
173 202
174verbose "$tid: rename directory" 203verbose "$tid: rename directory"
175echo "rename ${COPY}.dd ${COPY}.dd2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ 204echo "rename ${COPY}.dd ${COPY}.dd2" | \
176 || fail "rename directory failed" 205 ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || \
206 fail "rename directory failed"
177test -d ${COPY}.dd && fail "oldname exists after rename directory" 207test -d ${COPY}.dd && fail "oldname exists after rename directory"
178test -d ${COPY}.dd2 || fail "missing newname after rename directory" 208test -d ${COPY}.dd2 || fail "missing newname after rename directory"
179 209
@@ -207,5 +237,5 @@ echo "lchdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
207 || fail "lchdir failed" 237 || fail "lchdir failed"
208 238
209rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 239rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2
210 240rm -rf ${QUOTECOPY} "$SPACECOPY" "$GLOBMETACOPY"
211 241
diff --git a/regress/sftp-glob.sh b/regress/sftp-glob.sh
index e238356a2..60116a748 100644
--- a/regress/sftp-glob.sh
+++ b/regress/sftp-glob.sh
@@ -1,28 +1,68 @@
1# $OpenBSD: sftp-glob.sh,v 1.1 2004/12/10 01:31:30 fgsch Exp $ 1# $OpenBSD: sftp-glob.sh,v 1.3 2007/10/26 05:30:01 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="sftp glob" 4tid="sftp glob"
5 5
6sftp_ls() {
7 target=$1
8 errtag=$2
9 expected=$3
10 unexpected=$4
11 verbose "$tid: $errtag"
12 printf "ls -l %s" "${target}" | \
13 ${SFTP} -b - -P ${SFTPSERVER} 2>/dev/null | \
14 grep -v "^sftp>" > ${RESULTS}
15 if [ $? -ne 0 ]; then
16 fail "$errtag failed"
17 fi
18 if test "x$expected" != "x" ; then
19 if fgrep "$expected" ${RESULTS} >/dev/null 2>&1 ; then
20 :
21 else
22 fail "$expected missing from $errtag results"
23 fi
24 fi
25 if test "x$unexpected" != "x" && \
26 fgrep "$unexpected" ${RESULTS} >/dev/null 2>&1 ; then
27 fail "$unexpected present in $errtag results"
28 fi
29 rm -f ${RESULTS}
30}
31
6BASE=${OBJ}/glob 32BASE=${OBJ}/glob
33RESULTS=${OBJ}/results
7DIR=${BASE}/dir 34DIR=${BASE}/dir
8DATA=${DIR}/file 35DATA=${DIR}/file
9 36
37GLOB1="${DIR}/g-wild*"
38GLOB2="${DIR}/g-wildx"
39QUOTE="${DIR}/g-quote\""
40SLASH="${DIR}/g-sl\\ash"
41ESLASH="${DIR}/g-slash\\"
42QSLASH="${DIR}/g-qs\\\""
43SPACE="${DIR}/g-q space"
44
10rm -rf ${BASE} 45rm -rf ${BASE}
11mkdir -p ${DIR} 46mkdir -p ${DIR}
12touch ${DATA} 47touch "${DATA}" "${GLOB1}" "${GLOB2}" "${QUOTE}"
13 48touch "${QSLASH}" "${ESLASH}" "${SLASH}" "${SPACE}"
14verbose "$tid: ls file" 49
15echo "ls -l ${DIR}/fil*" | ${SFTP} -P ${SFTPSERVER} 2>/dev/null | \ 50# target message expected unexpected
16 grep ${DATA} >/dev/null 2>&1 51sftp_ls "${DIR}/fil*" "file glob" "${DATA}" ""
17if [ $? -ne 0 ]; then 52sftp_ls "${BASE}/d*" "dir glob" "`basename ${DATA}`" ""
18 fail "globbed ls file failed" 53sftp_ls "${DIR}/g-wild\"*\"" "quoted glob" "g-wild*" "g-wildx"
19fi 54sftp_ls "${DIR}/g-wild\*" "escaped glob" "g-wild*" "g-wildx"
20 55sftp_ls "${DIR}/g-quote\\\"" "escaped quote" "g-quote\"" ""
21verbose "$tid: ls dir" 56sftp_ls "\"${DIR}/g-quote\\\"\"" "quoted quote" "g-quote\"" ""
22echo "ls -l ${BASE}/d*" | ${SFTP} -P ${SFTPSERVER} 2>/dev/null | \ 57sftp_ls "'${DIR}/g-quote\"'" "single-quoted quote" "g-quote\"" ""
23 grep file >/dev/null 2>&1 58sftp_ls "${DIR}/g-sl\\\\ash" "escaped slash" "g-sl\\ash" ""
24if [ $? -ne 0 ]; then 59sftp_ls "'${DIR}/g-sl\\\\ash'" "quoted slash" "g-sl\\ash" ""
25 fail "globbed ls dir failed" 60sftp_ls "${DIR}/g-slash\\\\" "escaped slash at EOL" "g-slash\\" ""
26fi 61sftp_ls "'${DIR}/g-slash\\\\'" "quoted slash at EOL" "g-slash\\" ""
62sftp_ls "${DIR}/g-qs\\\\\\\"" "escaped slash+quote" "g-qs\\\"" ""
63sftp_ls "'${DIR}/g-qs\\\\\"'" "quoted slash+quote" "g-qs\\\"" ""
64sftp_ls "${DIR}/g-q\\ space" "escaped space" "g-q space" ""
65sftp_ls "'${DIR}/g-q space'" "quoted space" "g-q space" ""
27 66
28rm -rf ${BASE} 67rm -rf ${BASE}
68
diff --git a/regress/ssh2putty.sh b/regress/ssh2putty.sh
new file mode 100755
index 000000000..dfdeeff4a
--- /dev/null
+++ b/regress/ssh2putty.sh
@@ -0,0 +1,33 @@
1#!/bin/sh
2
3if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then
4 echo "Usage: ssh2putty hostname port ssh-private-key"
5 exit 1
6fi
7
8HOST=$1
9PORT=$2
10KEYFILE=$3
11
12# XXX - support DSA keys too
13if grep "BEGIN RSA PRIVATE KEY" $KEYFILE >/dev/null 2>&1 ; then
14 :
15else
16 echo "Unsupported private key format"
17 exit 1
18fi
19
20public_exponent=`
21 openssl rsa -noout -text -in $KEYFILE | grep ^publicExponent |
22 sed 's/.*(//;s/).*//'
23`
24test $? -ne 0 && exit 1
25
26modulus=`
27 openssl rsa -noout -modulus -in $KEYFILE | grep ^Modulus= |
28 sed 's/^Modulus=/0x/' | tr A-Z a-z
29`
30test $? -ne 0 && exit 1
31
32echo "rsa2@$PORT:$HOST $public_exponent,$modulus"
33
diff --git a/regress/test-exec.sh b/regress/test-exec.sh
index 59ae33c08..b54448912 100644
--- a/regress/test-exec.sh
+++ b/regress/test-exec.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: test-exec.sh,v 1.28 2005/05/20 23:14:15 djm Exp $ 1# $OpenBSD: test-exec.sh,v 1.35 2008/06/28 13:57:25 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4#SUDO=sudo 4#SUDO=sudo
@@ -69,6 +69,11 @@ SFTP=sftp
69SFTPSERVER=/usr/libexec/openssh/sftp-server 69SFTPSERVER=/usr/libexec/openssh/sftp-server
70SCP=scp 70SCP=scp
71 71
72# Interop testing
73PLINK=plink
74PUTTYGEN=puttygen
75CONCH=conch
76
72if [ "x$TEST_SSH_SSH" != "x" ]; then 77if [ "x$TEST_SSH_SSH" != "x" ]; then
73 SSH="${TEST_SSH_SSH}" 78 SSH="${TEST_SSH_SSH}"
74fi 79fi
@@ -96,6 +101,27 @@ fi
96if [ "x$TEST_SSH_SCP" != "x" ]; then 101if [ "x$TEST_SSH_SCP" != "x" ]; then
97 SCP="${TEST_SSH_SCP}" 102 SCP="${TEST_SSH_SCP}"
98fi 103fi
104if [ "x$TEST_SSH_PLINK" != "x" ]; then
105 # Find real binary, if it exists
106 case "${TEST_SSH_PLINK}" in
107 /*) PLINK="${TEST_SSH_PLINK}" ;;
108 *) PLINK=`which ${TEST_SSH_PLINK} 2>/dev/null` ;;
109 esac
110fi
111if [ "x$TEST_SSH_PUTTYGEN" != "x" ]; then
112 # Find real binary, if it exists
113 case "${TEST_SSH_PUTTYGEN}" in
114 /*) PUTTYGEN="${TEST_SSH_PUTTYGEN}" ;;
115 *) PUTTYGEN=`which ${TEST_SSH_PUTTYGEN} 2>/dev/null` ;;
116 esac
117fi
118if [ "x$TEST_SSH_CONCH" != "x" ]; then
119 # Find real binary, if it exists
120 case "${TEST_SSH_CONCH}" in
121 /*) CONCH="${TEST_SSH_CONCH}" ;;
122 *) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;;
123 esac
124fi
99 125
100# Path to sshd must be absolute for rexec 126# Path to sshd must be absolute for rexec
101case "$SSHD" in 127case "$SSHD" in
@@ -269,6 +295,49 @@ for t in rsa rsa1; do
269done 295done
270chmod 644 $OBJ/authorized_keys_$USER 296chmod 644 $OBJ/authorized_keys_$USER
271 297
298# Activate Twisted Conch tests if the binary is present
299REGRESS_INTEROP_CONCH=no
300if test -x "$CONCH" ; then
301 REGRESS_INTEROP_CONCH=yes
302fi
303
304# If PuTTY is present and we are running a PuTTY test, prepare keys and
305# configuration
306REGRESS_INTEROP_PUTTY=no
307if test -x "$PUTTYGEN" -a -x "$PLINK" ; then
308 REGRESS_INTEROP_PUTTY=yes
309fi
310case "$SCRIPT" in
311*putty*) ;;
312*) REGRESS_INTEROP_PUTTY=no ;;
313esac
314
315if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
316 mkdir -p ${OBJ}/.putty
317
318 # Add a PuTTY key to authorized_keys
319 rm -f ${OBJ}/putty.rsa2
320 puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null
321 puttygen -O public-openssh ${OBJ}/putty.rsa2 \
322 >> $OBJ/authorized_keys_$USER
323
324 # Convert rsa2 host key to PuTTY format
325 ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa > \
326 ${OBJ}/.putty/sshhostkeys
327 ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa >> \
328 ${OBJ}/.putty/sshhostkeys
329
330 # Setup proxied session
331 mkdir -p ${OBJ}/.putty/sessions
332 rm -f ${OBJ}/.putty/sessions/localhost_proxy
333 echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy
334 echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy
335 echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy
336 echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSH_LOGFILE} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy
337
338 REGRESS_INTEROP_PUTTY=yes
339fi
340
272# create a proxy version of the client config 341# create a proxy version of the client config
273( 342(
274 cat $OBJ/ssh_config 343 cat $OBJ/ssh_config
@@ -281,8 +350,8 @@ ${SSHD} -t -f $OBJ/sshd_proxy || fatal "sshd_proxy broken"
281start_sshd () 350start_sshd ()
282{ 351{
283 # start sshd 352 # start sshd
284 $SUDO ${SSHD} -f $OBJ/sshd_config -t || fatal "sshd_config broken" 353 $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken"
285 $SUDO ${SSHD} -f $OBJ/sshd_config -e >>$TEST_SSH_LOGFILE 2>&1 354 $SUDO ${SSHD} -f $OBJ/sshd_config -e "$@" >>$TEST_SSH_LOGFILE 2>&1
286 355
287 trace "wait for sshd" 356 trace "wait for sshd"
288 i=0; 357 i=0;
diff --git a/regress/try-ciphers.sh b/regress/try-ciphers.sh
index 379fe353a..ef776d2ee 100644
--- a/regress/try-ciphers.sh
+++ b/regress/try-ciphers.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: try-ciphers.sh,v 1.10 2005/05/24 04:10:54 djm Exp $ 1# $OpenBSD: try-ciphers.sh,v 1.11 2007/06/07 19:41:46 pvalchev Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="try ciphers" 4tid="try ciphers"
@@ -7,7 +7,7 @@ ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
7 arcfour128 arcfour256 arcfour 7 arcfour128 arcfour256 arcfour
8 aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se 8 aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se
9 aes128-ctr aes192-ctr aes256-ctr" 9 aes128-ctr aes192-ctr aes256-ctr"
10macs="hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96" 10macs="hmac-sha1 hmac-md5 umac-64@openssh.com hmac-sha1-96 hmac-md5-96"
11 11
12for c in $ciphers; do 12for c in $ciphers; do
13 for m in $macs; do 13 for m in $macs; do
diff --git a/scp.0 b/scp.0
index 012d4f0ad..b6b9d919c 100644
--- a/scp.0
+++ b/scp.0
@@ -14,9 +14,11 @@ DESCRIPTION
14 as ssh(1). Unlike rcp(1), scp will ask for passwords or passphrases if 14 as ssh(1). Unlike rcp(1), scp will ask for passwords or passphrases if
15 they are needed for authentication. 15 they are needed for authentication.
16 16
17 Any file name may contain a host and user specification to indicate that 17 File names may contain a user and host specification to indicate that the
18 the file is to be copied to/from that host. Copies between two remote 18 file is to be copied to/from that host. Local file names can be made ex-
19 hosts are permitted. 19 plicit using absolute or relative pathnames to avoid scp treating file
20 names containing `:' as host specifiers. Copies between two remote hosts
21 are also permitted.
20 22
21 The options are as follows: 23 The options are as follows:
22 24
@@ -43,8 +45,8 @@ DESCRIPTION
43 This option is directly passed to ssh(1). 45 This option is directly passed to ssh(1).
44 46
45 -i identity_file 47 -i identity_file
46 Selects the file from which the identity (private key) for RSA 48 Selects the file from which the identity (private key) for public
47 authentication is read. This option is directly passed to 49 key authentication is read. This option is directly passed to
48 ssh(1). 50 ssh(1).
49 51
50 -l limit 52 -l limit
@@ -115,9 +117,11 @@ DESCRIPTION
115 -p Preserves modification times, access times, and modes from the 117 -p Preserves modification times, access times, and modes from the
116 original file. 118 original file.
117 119
118 -q Disables the progress meter. 120 -q Quiet mode: disables the progress meter as well as warning and
121 diagnostic messages from ssh(1).
119 122
120 -r Recursively copy entire directories. 123 -r Recursively copy entire directories. Note that scp follows sym-
124 bolic links encountered in the tree traversal.
121 125
122 -S program 126 -S program
123 Name of program to use for the encrypted connection. The program 127 Name of program to use for the encrypted connection. The program
@@ -141,4 +145,4 @@ AUTHORS
141 Timo Rinne <tri@iki.fi> 145 Timo Rinne <tri@iki.fi>
142 Tatu Ylonen <ylo@cs.hut.fi> 146 Tatu Ylonen <ylo@cs.hut.fi>
143 147
144OpenBSD 4.2 August 8, 2007 3 148OpenBSD 4.4 July 12, 2008 3
diff --git a/scp.1 b/scp.1
index b37ac84be..5033d84f2 100644
--- a/scp.1
+++ b/scp.1
@@ -9,9 +9,9 @@
9.\" 9.\"
10.\" Created: Sun May 7 00:14:37 1995 ylo 10.\" Created: Sun May 7 00:14:37 1995 ylo
11.\" 11.\"
12.\" $OpenBSD: scp.1,v 1.42 2007/08/06 19:16:06 sobrado Exp $ 12.\" $OpenBSD: scp.1,v 1.46 2008/07/12 05:33:41 djm Exp $
13.\" 13.\"
14.Dd $Mdocdate: August 8 2007 $ 14.Dd $Mdocdate: July 12 2008 $
15.Dt SCP 1 15.Dt SCP 1
16.Os 16.Os
17.Sh NAME 17.Sh NAME
@@ -56,9 +56,15 @@ Unlike
56will ask for passwords or passphrases if they are needed for 56will ask for passwords or passphrases if they are needed for
57authentication. 57authentication.
58.Pp 58.Pp
59Any file name may contain a host and user specification to indicate 59File names may contain a user and host specification to indicate
60that the file is to be copied to/from that host. 60that the file is to be copied to/from that host.
61Copies between two remote hosts are permitted. 61Local file names can be made explicit using absolute or relative pathnames
62to avoid
63.Nm
64treating file names containing
65.Sq :\&
66as host specifiers.
67Copies between two remote hosts are also permitted.
62.Pp 68.Pp
63The options are as follows: 69The options are as follows:
64.Bl -tag -width Ds 70.Bl -tag -width Ds
@@ -98,7 +104,7 @@ per-user configuration file for
98This option is directly passed to 104This option is directly passed to
99.Xr ssh 1 . 105.Xr ssh 1 .
100.It Fl i Ar identity_file 106.It Fl i Ar identity_file
101Selects the file from which the identity (private key) for RSA 107Selects the file from which the identity (private key) for public key
102authentication is read. 108authentication is read.
103This option is directly passed to 109This option is directly passed to
104.Xr ssh 1 . 110.Xr ssh 1 .
@@ -178,9 +184,14 @@ is already reserved for preserving the times and modes of the file in
178Preserves modification times, access times, and modes from the 184Preserves modification times, access times, and modes from the
179original file. 185original file.
180.It Fl q 186.It Fl q
181Disables the progress meter. 187Quiet mode: disables the progress meter as well as warning and diagnostic
188messages from
189.Xr ssh 1 .
182.It Fl r 190.It Fl r
183Recursively copy entire directories. 191Recursively copy entire directories.
192Note that
193.Nm
194follows symbolic links encountered in the tree traversal.
184.It Fl S Ar program 195.It Fl S Ar program
185Name of 196Name of
186.Ar program 197.Ar program
diff --git a/scp.c b/scp.c
index 1765a44e6..9f8b7a192 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: scp.c,v 1.160 2007/08/06 19:16:06 sobrado Exp $ */ 1/* $OpenBSD: scp.c,v 1.163 2008/06/13 18:55:22 dtucker Exp $ */
2/* 2/*
3 * scp - secure remote copy. This is basically patched BSD rcp which 3 * scp - secure remote copy. This is basically patched BSD rcp which
4 * uses ssh to do the data transfer (instead of using rcmd). 4 * uses ssh to do the data transfer (instead of using rcmd).
@@ -78,6 +78,13 @@
78#ifdef HAVE_SYS_STAT_H 78#ifdef HAVE_SYS_STAT_H
79# include <sys/stat.h> 79# include <sys/stat.h>
80#endif 80#endif
81#ifdef HAVE_POLL_H
82#include <poll.h>
83#else
84# ifdef HAVE_SYS_POLL_H
85# include <sys/poll.h>
86# endif
87#endif
81#ifdef HAVE_SYS_TIME_H 88#ifdef HAVE_SYS_TIME_H
82# include <sys/time.h> 89# include <sys/time.h>
83#endif 90#endif
@@ -109,6 +116,8 @@
109 116
110extern char *__progname; 117extern char *__progname;
111 118
119#define COPY_BUFLEN 16384
120
112int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); 121int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
113 122
114void bwlimit(int); 123void bwlimit(int);
@@ -282,6 +291,7 @@ void sink(int, char *[]);
282void source(int, char *[]); 291void source(int, char *[]);
283void tolocal(int, char *[]); 292void tolocal(int, char *[]);
284void toremote(char *, int, char *[]); 293void toremote(char *, int, char *[]);
294size_t scpio(ssize_t (*)(int, void *, size_t), int, void *, size_t, off_t *);
285void usage(void); 295void usage(void);
286 296
287int 297int
@@ -441,6 +451,43 @@ main(int argc, char **argv)
441 exit(errs != 0); 451 exit(errs != 0);
442} 452}
443 453
454/*
455 * atomicio-like wrapper that also applies bandwidth limits and updates
456 * the progressmeter counter.
457 */
458size_t
459scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c)
460{
461 u_char *p = (u_char *)_p;
462 size_t offset;
463 ssize_t r;
464 struct pollfd pfd;
465
466 pfd.fd = fd;
467 pfd.events = f == read ? POLLIN : POLLOUT;
468 for (offset = 0; offset < l;) {
469 r = f(fd, p + offset, l - offset);
470 if (r == 0) {
471 errno = EPIPE;
472 return offset;
473 }
474 if (r < 0) {
475 if (errno == EINTR)
476 continue;
477 if (errno == EAGAIN || errno == EWOULDBLOCK) {
478 (void)poll(&pfd, 1, -1); /* Ignore errors */
479 continue;
480 }
481 return offset;
482 }
483 offset += (size_t)r;
484 *c += (off_t)r;
485 if (limit_rate)
486 bwlimit(r);
487 }
488 return offset;
489}
490
444void 491void
445toremote(char *targ, int argc, char **argv) 492toremote(char *targ, int argc, char **argv)
446{ 493{
@@ -582,8 +629,8 @@ source(int argc, char **argv)
582 struct stat stb; 629 struct stat stb;
583 static BUF buffer; 630 static BUF buffer;
584 BUF *bp; 631 BUF *bp;
585 off_t i, amt, statbytes; 632 off_t i, statbytes;
586 size_t result; 633 size_t amt;
587 int fd = -1, haderr, indx; 634 int fd = -1, haderr, indx;
588 char *last, *name, buf[2048], encname[MAXPATHLEN]; 635 char *last, *name, buf[2048], encname[MAXPATHLEN];
589 int len; 636 int len;
@@ -604,6 +651,10 @@ source(int argc, char **argv)
604syserr: run_err("%s: %s", name, strerror(errno)); 651syserr: run_err("%s: %s", name, strerror(errno));
605 goto next; 652 goto next;
606 } 653 }
654 if (stb.st_size < 0) {
655 run_err("%s: %s", name, "Negative file size");
656 goto next;
657 }
607 unset_nonblock(fd); 658 unset_nonblock(fd);
608 switch (stb.st_mode & S_IFMT) { 659 switch (stb.st_mode & S_IFMT) {
609 case S_IFREG: 660 case S_IFREG:
@@ -629,8 +680,14 @@ syserr: run_err("%s: %s", name, strerror(errno));
629 * versions expecting microseconds. 680 * versions expecting microseconds.
630 */ 681 */
631 (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", 682 (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
632 (u_long) stb.st_mtime, 683 (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
633 (u_long) stb.st_atime); 684 (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
685 if (verbose_mode) {
686 fprintf(stderr, "File mtime %ld atime %ld\n",
687 (long)stb.st_mtime, (long)stb.st_atime);
688 fprintf(stderr, "Sending file timestamps: %s",
689 buf);
690 }
634 (void) atomicio(vwrite, remout, buf, strlen(buf)); 691 (void) atomicio(vwrite, remout, buf, strlen(buf));
635 if (response() < 0) 692 if (response() < 0)
636 goto next; 693 goto next;
@@ -645,7 +702,7 @@ syserr: run_err("%s: %s", name, strerror(errno));
645 (void) atomicio(vwrite, remout, buf, strlen(buf)); 702 (void) atomicio(vwrite, remout, buf, strlen(buf));
646 if (response() < 0) 703 if (response() < 0)
647 goto next; 704 goto next;
648 if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { 705 if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) {
649next: if (fd != -1) { 706next: if (fd != -1) {
650 (void) close(fd); 707 (void) close(fd);
651 fd = -1; 708 fd = -1;
@@ -654,27 +711,25 @@ next: if (fd != -1) {
654 } 711 }
655 if (showprogress) 712 if (showprogress)
656 start_progress_meter(curfile, stb.st_size, &statbytes); 713 start_progress_meter(curfile, stb.st_size, &statbytes);
657 /* Keep writing after an error so that we stay sync'd up. */ 714 set_nonblock(remout);
658 for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { 715 for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
659 amt = bp->cnt; 716 amt = bp->cnt;
660 if (i + amt > stb.st_size) 717 if (i + (off_t)amt > stb.st_size)
661 amt = stb.st_size - i; 718 amt = stb.st_size - i;
662 if (!haderr) { 719 if (!haderr) {
663 result = atomicio(read, fd, bp->buf, amt); 720 if (atomicio(read, fd, bp->buf, amt) != amt)
664 if (result != amt)
665 haderr = errno; 721 haderr = errno;
666 } 722 }
667 if (haderr) 723 /* Keep writing after error to retain sync */
668 (void) atomicio(vwrite, remout, bp->buf, amt); 724 if (haderr) {
669 else { 725 (void)atomicio(vwrite, remout, bp->buf, amt);
670 result = atomicio(vwrite, remout, bp->buf, amt); 726 continue;
671 if (result != amt)
672 haderr = errno;
673 statbytes += result;
674 } 727 }
675 if (limit_rate) 728 if (scpio(vwrite, remout, bp->buf, amt,
676 bwlimit(amt); 729 &statbytes) != amt)
730 haderr = errno;
677 } 731 }
732 unset_nonblock(remout);
678 if (showprogress) 733 if (showprogress)
679 stop_progress_meter(); 734 stop_progress_meter();
680 735
@@ -780,10 +835,10 @@ bwlimit(int amount)
780 thresh /= 2; 835 thresh /= 2;
781 if (thresh < 2048) 836 if (thresh < 2048)
782 thresh = 2048; 837 thresh = 2048;
783 } else if (bwend.tv_usec < 100) { 838 } else if (bwend.tv_usec < 10000) {
784 thresh *= 2; 839 thresh *= 2;
785 if (thresh > 32768) 840 if (thresh > COPY_BUFLEN * 4)
786 thresh = 32768; 841 thresh = COPY_BUFLEN * 4;
787 } 842 }
788 843
789 TIMEVAL_TO_TIMESPEC(&bwend, &ts); 844 TIMEVAL_TO_TIMESPEC(&bwend, &ts);
@@ -974,7 +1029,7 @@ bad: run_err("%s: %s", np, strerror(errno));
974 continue; 1029 continue;
975 } 1030 }
976 (void) atomicio(vwrite, remout, "", 1); 1031 (void) atomicio(vwrite, remout, "", 1);
977 if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { 1032 if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) {
978 (void) close(ofd); 1033 (void) close(ofd);
979 continue; 1034 continue;
980 } 1035 }
@@ -984,26 +1039,24 @@ bad: run_err("%s: %s", np, strerror(errno));
984 statbytes = 0; 1039 statbytes = 0;
985 if (showprogress) 1040 if (showprogress)
986 start_progress_meter(curfile, size, &statbytes); 1041 start_progress_meter(curfile, size, &statbytes);
987 for (count = i = 0; i < size; i += 4096) { 1042 set_nonblock(remin);
988 amt = 4096; 1043 for (count = i = 0; i < size; i += bp->cnt) {
1044 amt = bp->cnt;
989 if (i + amt > size) 1045 if (i + amt > size)
990 amt = size - i; 1046 amt = size - i;
991 count += amt; 1047 count += amt;
992 do { 1048 do {
993 j = atomicio(read, remin, cp, amt); 1049 j = scpio(read, remin, cp, amt, &statbytes);
994 if (j == 0) { 1050 if (j == 0) {
995 run_err("%s", j ? strerror(errno) : 1051 run_err("%s", j != EPIPE ?
1052 strerror(errno) :
996 "dropped connection"); 1053 "dropped connection");
997 exit(1); 1054 exit(1);
998 } 1055 }
999 amt -= j; 1056 amt -= j;
1000 cp += j; 1057 cp += j;
1001 statbytes += j;
1002 } while (amt > 0); 1058 } while (amt > 0);
1003 1059
1004 if (limit_rate)
1005 bwlimit(4096);
1006
1007 if (count == bp->cnt) { 1060 if (count == bp->cnt) {
1008 /* Keep reading so we stay sync'd up. */ 1061 /* Keep reading so we stay sync'd up. */
1009 if (wrerr == NO) { 1062 if (wrerr == NO) {
@@ -1017,6 +1070,7 @@ bad: run_err("%s: %s", np, strerror(errno));
1017 cp = bp->buf; 1070 cp = bp->buf;
1018 } 1071 }
1019 } 1072 }
1073 unset_nonblock(remin);
1020 if (showprogress) 1074 if (showprogress)
1021 stop_progress_meter(); 1075 stop_progress_meter();
1022 if (count != 0 && wrerr == NO && 1076 if (count != 0 && wrerr == NO &&
diff --git a/servconf.c b/servconf.c
index 1a7545171..66e22979f 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.c,v 1.172 2007/04/23 10:15:39 dtucker Exp $ */ 1/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 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
@@ -23,7 +23,9 @@
23#include <signal.h> 23#include <signal.h>
24#include <unistd.h> 24#include <unistd.h>
25#include <stdarg.h> 25#include <stdarg.h>
26#include <errno.h>
26 27
28#include "openbsd-compat/sys-queue.h"
27#include "xmalloc.h" 29#include "xmalloc.h"
28#include "ssh.h" 30#include "ssh.h"
29#include "log.h" 31#include "log.h"
@@ -99,6 +101,7 @@ initialize_server_options(ServerOptions *options)
99 options->use_login = -1; 101 options->use_login = -1;
100 options->compression = -1; 102 options->compression = -1;
101 options->allow_tcp_forwarding = -1; 103 options->allow_tcp_forwarding = -1;
104 options->allow_agent_forwarding = -1;
102 options->num_allow_users = 0; 105 options->num_allow_users = 0;
103 options->num_deny_users = 0; 106 options->num_deny_users = 0;
104 options->num_allow_groups = 0; 107 options->num_allow_groups = 0;
@@ -112,6 +115,7 @@ initialize_server_options(ServerOptions *options)
112 options->max_startups_rate = -1; 115 options->max_startups_rate = -1;
113 options->max_startups = -1; 116 options->max_startups = -1;
114 options->max_authtries = -1; 117 options->max_authtries = -1;
118 options->max_sessions = -1;
115 options->banner = NULL; 119 options->banner = NULL;
116 options->use_dns = -1; 120 options->use_dns = -1;
117 options->client_alive_interval = -1; 121 options->client_alive_interval = -1;
@@ -122,6 +126,7 @@ initialize_server_options(ServerOptions *options)
122 options->permit_tun = -1; 126 options->permit_tun = -1;
123 options->num_permitted_opens = -1; 127 options->num_permitted_opens = -1;
124 options->adm_forced_command = NULL; 128 options->adm_forced_command = NULL;
129 options->chroot_directory = NULL;
125} 130}
126 131
127void 132void
@@ -153,7 +158,7 @@ fill_default_server_options(ServerOptions *options)
153 if (options->pid_file == NULL) 158 if (options->pid_file == NULL)
154 options->pid_file = _PATH_SSH_DAEMON_PID_FILE; 159 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
155 if (options->server_key_bits == -1) 160 if (options->server_key_bits == -1)
156 options->server_key_bits = 768; 161 options->server_key_bits = 1024;
157 if (options->login_grace_time == -1) 162 if (options->login_grace_time == -1)
158 options->login_grace_time = 120; 163 options->login_grace_time = 120;
159 if (options->key_regeneration_time == -1) 164 if (options->key_regeneration_time == -1)
@@ -222,6 +227,8 @@ fill_default_server_options(ServerOptions *options)
222 options->compression = COMP_DELAYED; 227 options->compression = COMP_DELAYED;
223 if (options->allow_tcp_forwarding == -1) 228 if (options->allow_tcp_forwarding == -1)
224 options->allow_tcp_forwarding = 1; 229 options->allow_tcp_forwarding = 1;
230 if (options->allow_agent_forwarding == -1)
231 options->allow_agent_forwarding = 1;
225 if (options->gateway_ports == -1) 232 if (options->gateway_ports == -1)
226 options->gateway_ports = 0; 233 options->gateway_ports = 0;
227 if (options->max_startups == -1) 234 if (options->max_startups == -1)
@@ -232,6 +239,8 @@ fill_default_server_options(ServerOptions *options)
232 options->max_startups_begin = options->max_startups; 239 options->max_startups_begin = options->max_startups;
233 if (options->max_authtries == -1) 240 if (options->max_authtries == -1)
234 options->max_authtries = DEFAULT_AUTH_FAIL_MAX; 241 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
242 if (options->max_sessions == -1)
243 options->max_sessions = DEFAULT_SESSIONS_MAX;
235 if (options->use_dns == -1) 244 if (options->use_dns == -1)
236 options->use_dns = 1; 245 options->use_dns = 1;
237 if (options->client_alive_interval == -1) 246 if (options->client_alive_interval == -1)
@@ -286,13 +295,13 @@ typedef enum {
286 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 295 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
287 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 296 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
288 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, 297 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
289 sMaxStartups, sMaxAuthTries, 298 sMaxStartups, sMaxAuthTries, sMaxSessions,
290 sBanner, sUseDNS, sHostbasedAuthentication, 299 sBanner, sUseDNS, sHostbasedAuthentication,
291 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 300 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
292 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 301 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
293 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, 302 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
294 sMatch, sPermitOpen, sForceCommand, 303 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
295 sUsePrivilegeSeparation, 304 sUsePrivilegeSeparation, sAllowAgentForwarding,
296 sDeprecated, sUnsupported 305 sDeprecated, sUnsupported
297} ServerOpCodes; 306} ServerOpCodes;
298 307
@@ -321,7 +330,7 @@ static struct {
321 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, 330 { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
322 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, 331 { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
323 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, 332 { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
324 { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL }, 333 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
325 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 334 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
326 { "loglevel", sLogLevel, SSHCFG_GLOBAL }, 335 { "loglevel", sLogLevel, SSHCFG_GLOBAL },
327 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 336 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
@@ -378,6 +387,7 @@ static struct {
378 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, 387 { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
379 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ 388 { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
380 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, 389 { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
390 { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
381 { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, 391 { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
382 { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, 392 { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
383 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, 393 { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
@@ -388,7 +398,8 @@ static struct {
388 { "gatewayports", sGatewayPorts, SSHCFG_ALL }, 398 { "gatewayports", sGatewayPorts, SSHCFG_ALL },
389 { "subsystem", sSubsystem, SSHCFG_GLOBAL }, 399 { "subsystem", sSubsystem, SSHCFG_GLOBAL },
390 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, 400 { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
391 { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL }, 401 { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
402 { "maxsessions", sMaxSessions, SSHCFG_ALL },
392 { "banner", sBanner, SSHCFG_ALL }, 403 { "banner", sBanner, SSHCFG_ALL },
393 { "usedns", sUseDNS, SSHCFG_GLOBAL }, 404 { "usedns", sUseDNS, SSHCFG_GLOBAL },
394 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, 405 { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
@@ -403,9 +414,21 @@ static struct {
403 { "match", sMatch, SSHCFG_ALL }, 414 { "match", sMatch, SSHCFG_ALL },
404 { "permitopen", sPermitOpen, SSHCFG_ALL }, 415 { "permitopen", sPermitOpen, SSHCFG_ALL },
405 { "forcecommand", sForceCommand, SSHCFG_ALL }, 416 { "forcecommand", sForceCommand, SSHCFG_ALL },
417 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
406 { NULL, sBadOption, 0 } 418 { NULL, sBadOption, 0 }
407}; 419};
408 420
421static struct {
422 int val;
423 char *text;
424} tunmode_desc[] = {
425 { SSH_TUNMODE_NO, "no" },
426 { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
427 { SSH_TUNMODE_ETHERNET, "ethernet" },
428 { SSH_TUNMODE_YES, "yes" },
429 { -1, NULL }
430};
431
409/* 432/*
410 * Returns the number of the token pointed to by cp or sBadOption. 433 * Returns the number of the token pointed to by cp or sBadOption.
411 */ 434 */
@@ -458,7 +481,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
458 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) 481 if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
459 fatal("bad addr or host: %s (%s)", 482 fatal("bad addr or host: %s (%s)",
460 addr ? addr : "<NULL>", 483 addr ? addr : "<NULL>",
461 gai_strerror(gaierr)); 484 ssh_gai_strerror(gaierr));
462 for (ai = aitop; ai->ai_next; ai = ai->ai_next) 485 for (ai = aitop; ai->ai_next; ai = ai->ai_next)
463 ; 486 ;
464 ai->ai_next = options->listen_addrs; 487 ai->ai_next = options->listen_addrs;
@@ -502,24 +525,8 @@ static int
502match_cfg_line_group(const char *grps, int line, const char *user) 525match_cfg_line_group(const char *grps, int line, const char *user)
503{ 526{
504 int result = 0; 527 int result = 0;
505 u_int ngrps = 0;
506 char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
507 struct passwd *pw; 528 struct passwd *pw;
508 529
509 /*
510 * Even if we do not have a user yet, we still need to check for
511 * valid syntax.
512 */
513 arg = cp = xstrdup(grps);
514 while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
515 if (ngrps >= MAX_MATCH_GROUPS) {
516 error("line %d: too many groups in Match Group", line);
517 result = -1;
518 goto out;
519 }
520 grplist[ngrps++] = p;
521 }
522
523 if (user == NULL) 530 if (user == NULL)
524 goto out; 531 goto out;
525 532
@@ -529,17 +536,16 @@ match_cfg_line_group(const char *grps, int line, const char *user)
529 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 536 } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
530 debug("Can't Match group because user %.100s not in any group " 537 debug("Can't Match group because user %.100s not in any group "
531 "at line %d", user, line); 538 "at line %d", user, line);
532 } else if (ga_match(grplist, ngrps) != 1) { 539 } else if (ga_match_pattern_list(grps) != 1) {
533 debug("user %.100s does not match group %.100s at line %d", 540 debug("user %.100s does not match group list %.100s at line %d",
534 user, arg, line); 541 user, grps, line);
535 } else { 542 } else {
536 debug("user %.100s matched group %.100s at line %d", user, 543 debug("user %.100s matched group list %.100s at line %d", user,
537 arg, line); 544 grps, line);
538 result = 1; 545 result = 1;
539 } 546 }
540out: 547out:
541 ga_free(); 548 ga_free();
542 xfree(arg);
543 return result; 549 return result;
544} 550}
545 551
@@ -592,15 +598,18 @@ match_cfg_line(char **condition, int line, const char *user, const char *host,
592 debug("connection from %.100s matched 'Host " 598 debug("connection from %.100s matched 'Host "
593 "%.100s' at line %d", host, arg, line); 599 "%.100s' at line %d", host, arg, line);
594 } else if (strcasecmp(attrib, "address") == 0) { 600 } else if (strcasecmp(attrib, "address") == 0) {
595 if (!address) { 601 switch (addr_match_list(address, arg)) {
596 result = 0; 602 case 1:
597 continue;
598 }
599 if (match_hostname(address, arg, len) != 1)
600 result = 0;
601 else
602 debug("connection from %.100s matched 'Address " 603 debug("connection from %.100s matched 'Address "
603 "%.100s' at line %d", address, arg, line); 604 "%.100s' at line %d", address, arg, line);
605 break;
606 case 0:
607 case -1:
608 result = 0;
609 break;
610 case -2:
611 return -1;
612 }
604 } else { 613 } else {
605 error("Unsupported Match attribute %s", attrib); 614 error("Unsupported Match attribute %s", attrib);
606 return -1; 615 return -1;
@@ -621,6 +630,8 @@ process_server_config_line(ServerOptions *options, char *line,
621{ 630{
622 char *cp, **charptr, *arg, *p; 631 char *cp, **charptr, *arg, *p;
623 int cmdline = 0, *intptr, value, n; 632 int cmdline = 0, *intptr, value, n;
633 SyslogFacility *log_facility_ptr;
634 LogLevel *log_level_ptr;
624 ServerOpCodes opcode; 635 ServerOpCodes opcode;
625 u_short port; 636 u_short port;
626 u_int i, flags = 0; 637 u_int i, flags = 0;
@@ -686,7 +697,7 @@ process_server_config_line(ServerOptions *options, char *line,
686 697
687 case sServerKeyBits: 698 case sServerKeyBits:
688 intptr = &options->server_key_bits; 699 intptr = &options->server_key_bits;
689parse_int: 700 parse_int:
690 arg = strdelim(&cp); 701 arg = strdelim(&cp);
691 if (!arg || *arg == '\0') 702 if (!arg || *arg == '\0')
692 fatal("%s line %d: missing integer value.", 703 fatal("%s line %d: missing integer value.",
@@ -698,7 +709,7 @@ parse_int:
698 709
699 case sLoginGraceTime: 710 case sLoginGraceTime:
700 intptr = &options->login_grace_time; 711 intptr = &options->login_grace_time;
701parse_time: 712 parse_time:
702 arg = strdelim(&cp); 713 arg = strdelim(&cp);
703 if (!arg || *arg == '\0') 714 if (!arg || *arg == '\0')
704 fatal("%s line %d: missing time value.", 715 fatal("%s line %d: missing time value.",
@@ -767,7 +778,7 @@ parse_time:
767 fatal("%s line %d: too many host keys specified (max %d).", 778 fatal("%s line %d: too many host keys specified (max %d).",
768 filename, linenum, MAX_HOSTKEYS); 779 filename, linenum, MAX_HOSTKEYS);
769 charptr = &options->host_key_files[*intptr]; 780 charptr = &options->host_key_files[*intptr];
770parse_filename: 781 parse_filename:
771 arg = strdelim(&cp); 782 arg = strdelim(&cp);
772 if (!arg || *arg == '\0') 783 if (!arg || *arg == '\0')
773 fatal("%s line %d: missing file name.", 784 fatal("%s line %d: missing file name.",
@@ -804,13 +815,13 @@ parse_filename:
804 fatal("%s line %d: Bad yes/" 815 fatal("%s line %d: Bad yes/"
805 "without-password/forced-commands-only/no " 816 "without-password/forced-commands-only/no "
806 "argument: %s", filename, linenum, arg); 817 "argument: %s", filename, linenum, arg);
807 if (*intptr == -1) 818 if (*activep && *intptr == -1)
808 *intptr = value; 819 *intptr = value;
809 break; 820 break;
810 821
811 case sIgnoreRhosts: 822 case sIgnoreRhosts:
812 intptr = &options->ignore_rhosts; 823 intptr = &options->ignore_rhosts;
813parse_flag: 824 parse_flag:
814 arg = strdelim(&cp); 825 arg = strdelim(&cp);
815 if (!arg || *arg == '\0') 826 if (!arg || *arg == '\0')
816 fatal("%s line %d: missing yes/no argument.", 827 fatal("%s line %d: missing yes/no argument.",
@@ -976,31 +987,35 @@ parse_flag:
976 goto parse_flag; 987 goto parse_flag;
977 988
978 case sLogFacility: 989 case sLogFacility:
979 intptr = (int *) &options->log_facility; 990 log_facility_ptr = &options->log_facility;
980 arg = strdelim(&cp); 991 arg = strdelim(&cp);
981 value = log_facility_number(arg); 992 value = log_facility_number(arg);
982 if (value == SYSLOG_FACILITY_NOT_SET) 993 if (value == SYSLOG_FACILITY_NOT_SET)
983 fatal("%.200s line %d: unsupported log facility '%s'", 994 fatal("%.200s line %d: unsupported log facility '%s'",
984 filename, linenum, arg ? arg : "<NONE>"); 995 filename, linenum, arg ? arg : "<NONE>");
985 if (*intptr == -1) 996 if (*log_facility_ptr == -1)
986 *intptr = (SyslogFacility) value; 997 *log_facility_ptr = (SyslogFacility) value;
987 break; 998 break;
988 999
989 case sLogLevel: 1000 case sLogLevel:
990 intptr = (int *) &options->log_level; 1001 log_level_ptr = &options->log_level;
991 arg = strdelim(&cp); 1002 arg = strdelim(&cp);
992 value = log_level_number(arg); 1003 value = log_level_number(arg);
993 if (value == SYSLOG_LEVEL_NOT_SET) 1004 if (value == SYSLOG_LEVEL_NOT_SET)
994 fatal("%.200s line %d: unsupported log level '%s'", 1005 fatal("%.200s line %d: unsupported log level '%s'",
995 filename, linenum, arg ? arg : "<NONE>"); 1006 filename, linenum, arg ? arg : "<NONE>");
996 if (*intptr == -1) 1007 if (*log_level_ptr == -1)
997 *intptr = (LogLevel) value; 1008 *log_level_ptr = (LogLevel) value;
998 break; 1009 break;
999 1010
1000 case sAllowTcpForwarding: 1011 case sAllowTcpForwarding:
1001 intptr = &options->allow_tcp_forwarding; 1012 intptr = &options->allow_tcp_forwarding;
1002 goto parse_flag; 1013 goto parse_flag;
1003 1014
1015 case sAllowAgentForwarding:
1016 intptr = &options->allow_agent_forwarding;
1017 goto parse_flag;
1018
1004 case sUsePrivilegeSeparation: 1019 case sUsePrivilegeSeparation:
1005 intptr = &use_privsep; 1020 intptr = &use_privsep;
1006 goto parse_flag; 1021 goto parse_flag;
@@ -1142,9 +1157,14 @@ parse_flag:
1142 intptr = &options->max_authtries; 1157 intptr = &options->max_authtries;
1143 goto parse_int; 1158 goto parse_int;
1144 1159
1160 case sMaxSessions:
1161 intptr = &options->max_sessions;
1162 goto parse_int;
1163
1145 case sBanner: 1164 case sBanner:
1146 charptr = &options->banner; 1165 charptr = &options->banner;
1147 goto parse_filename; 1166 goto parse_filename;
1167
1148 /* 1168 /*
1149 * These options can contain %X options expanded at 1169 * These options can contain %X options expanded at
1150 * connect time, so that you can specify paths like: 1170 * connect time, so that you can specify paths like:
@@ -1187,16 +1207,13 @@ parse_flag:
1187 if (!arg || *arg == '\0') 1207 if (!arg || *arg == '\0')
1188 fatal("%s line %d: Missing yes/point-to-point/" 1208 fatal("%s line %d: Missing yes/point-to-point/"
1189 "ethernet/no argument.", filename, linenum); 1209 "ethernet/no argument.", filename, linenum);
1190 value = 0; /* silence compiler */ 1210 value = -1;
1191 if (strcasecmp(arg, "ethernet") == 0) 1211 for (i = 0; tunmode_desc[i].val != -1; i++)
1192 value = SSH_TUNMODE_ETHERNET; 1212 if (strcmp(tunmode_desc[i].text, arg) == 0) {
1193 else if (strcasecmp(arg, "point-to-point") == 0) 1213 value = tunmode_desc[i].val;
1194 value = SSH_TUNMODE_POINTOPOINT; 1214 break;
1195 else if (strcasecmp(arg, "yes") == 0) 1215 }
1196 value = SSH_TUNMODE_YES; 1216 if (value == -1)
1197 else if (strcasecmp(arg, "no") == 0)
1198 value = SSH_TUNMODE_NO;
1199 else
1200 fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1217 fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1201 "no argument: %s", filename, linenum, arg); 1218 "no argument: %s", filename, linenum, arg);
1202 if (*intptr == -1) 1219 if (*intptr == -1)
@@ -1253,6 +1270,17 @@ parse_flag:
1253 options->adm_forced_command = xstrdup(cp + len); 1270 options->adm_forced_command = xstrdup(cp + len);
1254 return 0; 1271 return 0;
1255 1272
1273 case sChrootDirectory:
1274 charptr = &options->chroot_directory;
1275
1276 arg = strdelim(&cp);
1277 if (!arg || *arg == '\0')
1278 fatal("%s line %d: missing file name.",
1279 filename, linenum);
1280 if (*activep && *charptr == NULL)
1281 *charptr = xstrdup(arg);
1282 break;
1283
1256 case sDeprecated: 1284 case sDeprecated:
1257 logit("%s line %d: Deprecated option %s", 1285 logit("%s line %d: Deprecated option %s",
1258 filename, linenum, arg); 1286 filename, linenum, arg);
@@ -1349,17 +1377,22 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1349 M_CP_INTOPT(kerberos_authentication); 1377 M_CP_INTOPT(kerberos_authentication);
1350 M_CP_INTOPT(hostbased_authentication); 1378 M_CP_INTOPT(hostbased_authentication);
1351 M_CP_INTOPT(kbd_interactive_authentication); 1379 M_CP_INTOPT(kbd_interactive_authentication);
1380 M_CP_INTOPT(permit_root_login);
1352 1381
1353 M_CP_INTOPT(allow_tcp_forwarding); 1382 M_CP_INTOPT(allow_tcp_forwarding);
1383 M_CP_INTOPT(allow_agent_forwarding);
1354 M_CP_INTOPT(gateway_ports); 1384 M_CP_INTOPT(gateway_ports);
1355 M_CP_INTOPT(x11_display_offset); 1385 M_CP_INTOPT(x11_display_offset);
1356 M_CP_INTOPT(x11_forwarding); 1386 M_CP_INTOPT(x11_forwarding);
1357 M_CP_INTOPT(x11_use_localhost); 1387 M_CP_INTOPT(x11_use_localhost);
1388 M_CP_INTOPT(max_sessions);
1389 M_CP_INTOPT(max_authtries);
1358 1390
1359 M_CP_STROPT(banner); 1391 M_CP_STROPT(banner);
1360 if (preauth) 1392 if (preauth)
1361 return; 1393 return;
1362 M_CP_STROPT(adm_forced_command); 1394 M_CP_STROPT(adm_forced_command);
1395 M_CP_STROPT(chroot_directory);
1363} 1396}
1364 1397
1365#undef M_CP_INTOPT 1398#undef M_CP_INTOPT
@@ -1387,3 +1420,213 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1387 fatal("%s: terminating, %d bad configuration options", 1420 fatal("%s: terminating, %d bad configuration options",
1388 filename, bad_options); 1421 filename, bad_options);
1389} 1422}
1423
1424static const char *
1425fmt_intarg(ServerOpCodes code, int val)
1426{
1427 if (code == sAddressFamily) {
1428 switch (val) {
1429 case AF_INET:
1430 return "inet";
1431 case AF_INET6:
1432 return "inet6";
1433 case AF_UNSPEC:
1434 return "any";
1435 default:
1436 return "UNKNOWN";
1437 }
1438 }
1439 if (code == sPermitRootLogin) {
1440 switch (val) {
1441 case PERMIT_NO_PASSWD:
1442 return "without-passord";
1443 case PERMIT_FORCED_ONLY:
1444 return "forced-commands-only";
1445 case PERMIT_YES:
1446 return "yes";
1447 }
1448 }
1449 if (code == sProtocol) {
1450 switch (val) {
1451 case SSH_PROTO_1:
1452 return "1";
1453 case SSH_PROTO_2:
1454 return "2";
1455 case (SSH_PROTO_1|SSH_PROTO_2):
1456 return "2,1";
1457 default:
1458 return "UNKNOWN";
1459 }
1460 }
1461 if (code == sGatewayPorts && val == 2)
1462 return "clientspecified";
1463 if (code == sCompression && val == COMP_DELAYED)
1464 return "delayed";
1465 switch (val) {
1466 case -1:
1467 return "unset";
1468 case 0:
1469 return "no";
1470 case 1:
1471 return "yes";
1472 }
1473 return "UNKNOWN";
1474}
1475
1476static const char *
1477lookup_opcode_name(ServerOpCodes code)
1478{
1479 u_int i;
1480
1481 for (i = 0; keywords[i].name != NULL; i++)
1482 if (keywords[i].opcode == code)
1483 return(keywords[i].name);
1484 return "UNKNOWN";
1485}
1486
1487static void
1488dump_cfg_int(ServerOpCodes code, int val)
1489{
1490 printf("%s %d\n", lookup_opcode_name(code), val);
1491}
1492
1493static void
1494dump_cfg_fmtint(ServerOpCodes code, int val)
1495{
1496 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1497}
1498
1499static void
1500dump_cfg_string(ServerOpCodes code, const char *val)
1501{
1502 if (val == NULL)
1503 return;
1504 printf("%s %s\n", lookup_opcode_name(code), val);
1505}
1506
1507static void
1508dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1509{
1510 u_int i;
1511
1512 for (i = 0; i < count; i++)
1513 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
1514}
1515
1516void
1517dump_config(ServerOptions *o)
1518{
1519 u_int i;
1520 int ret;
1521 struct addrinfo *ai;
1522 char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1523
1524 /* these are usually at the top of the config */
1525 for (i = 0; i < o->num_ports; i++)
1526 printf("port %d\n", o->ports[i]);
1527 dump_cfg_fmtint(sProtocol, o->protocol);
1528 dump_cfg_fmtint(sAddressFamily, o->address_family);
1529
1530 /* ListenAddress must be after Port */
1531 for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1532 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1533 sizeof(addr), port, sizeof(port),
1534 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1535 error("getnameinfo failed: %.100s",
1536 (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1537 strerror(errno));
1538 } else {
1539 if (ai->ai_family == AF_INET6)
1540 printf("listenaddress [%s]:%s\n", addr, port);
1541 else
1542 printf("listenaddress %s:%s\n", addr, port);
1543 }
1544 }
1545
1546 /* integer arguments */
1547 dump_cfg_int(sServerKeyBits, o->server_key_bits);
1548 dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1549 dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1550 dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1551 dump_cfg_int(sMaxAuthTries, o->max_authtries);
1552 dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1553 dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1554
1555 /* formatted integer arguments */
1556 dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1557 dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1558 dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1559 dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1560 dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1561 dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1562 o->hostbased_uses_name_from_packet_only);
1563 dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1564 dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1565 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1566 dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1567 dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1568 dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1569 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1570 dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1571 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1572 dump_cfg_fmtint(sKbdInteractiveAuthentication,
1573 o->kbd_interactive_authentication);
1574 dump_cfg_fmtint(sChallengeResponseAuthentication,
1575 o->challenge_response_authentication);
1576 dump_cfg_fmtint(sPrintMotd, o->print_motd);
1577 dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1578 dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1579 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1580 dump_cfg_fmtint(sStrictModes, o->strict_modes);
1581 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1582 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1583 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1584 dump_cfg_fmtint(sUseLogin, o->use_login);
1585 dump_cfg_fmtint(sCompression, o->compression);
1586 dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1587 dump_cfg_fmtint(sUseDNS, o->use_dns);
1588 dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1589 dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1590
1591 /* string arguments */
1592 dump_cfg_string(sPidFile, o->pid_file);
1593 dump_cfg_string(sXAuthLocation, o->xauth_location);
1594 dump_cfg_string(sCiphers, o->ciphers);
1595 dump_cfg_string(sMacs, o->macs);
1596 dump_cfg_string(sBanner, o->banner);
1597 dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1598 dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1599 dump_cfg_string(sForceCommand, o->adm_forced_command);
1600
1601 /* string arguments requiring a lookup */
1602 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1603 dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1604
1605 /* string array arguments */
1606 dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1607 o->host_key_files);
1608 dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1609 dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1610 dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1611 dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1612 dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1613
1614 /* other arguments */
1615 for (i = 0; i < o->num_subsystems; i++)
1616 printf("subsystem %s %s\n", o->subsystem_name[i],
1617 o->subsystem_args[i]);
1618
1619 printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1620 o->max_startups_rate, o->max_startups);
1621
1622 for (i = 0; tunmode_desc[i].val != -1; i++)
1623 if (tunmode_desc[i].val == o->permit_tun) {
1624 s = tunmode_desc[i].text;
1625 break;
1626 }
1627 dump_cfg_string(sPermitTunnel, s);
1628
1629 printf("permitopen");
1630 channel_print_adm_permitted_opens();
1631 printf("\n");
1632}
diff --git a/servconf.h b/servconf.h
index 8a5b950ea..40ac64f13 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.80 2007/02/19 10:45:58 dtucker Exp $ */ 1/* $OpenBSD: servconf.h,v 1.85 2008/06/10 04:50:25 dtucker Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -35,6 +35,10 @@
35#define PERMIT_YES 3 35#define PERMIT_YES 3
36 36
37#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ 37#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
38#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
39
40/* Magic name for internal sftp-server */
41#define INTERNAL_SFTP_NAME "internal-sftp"
38 42
39typedef struct { 43typedef struct {
40 u_int num_ports; 44 u_int num_ports;
@@ -98,6 +102,7 @@ typedef struct {
98 int use_login; /* If true, login(1) is used */ 102 int use_login; /* If true, login(1) is used */
99 int compression; /* If true, compression is allowed */ 103 int compression; /* If true, compression is allowed */
100 int allow_tcp_forwarding; 104 int allow_tcp_forwarding;
105 int allow_agent_forwarding;
101 u_int num_allow_users; 106 u_int num_allow_users;
102 char *allow_users[MAX_ALLOW_USERS]; 107 char *allow_users[MAX_ALLOW_USERS];
103 u_int num_deny_users; 108 u_int num_deny_users;
@@ -119,6 +124,7 @@ typedef struct {
119 int max_startups_rate; 124 int max_startups_rate;
120 int max_startups; 125 int max_startups;
121 int max_authtries; 126 int max_authtries;
127 int max_sessions;
122 char *banner; /* SSH-2 banner message */ 128 char *banner; /* SSH-2 banner message */
123 int use_dns; 129 int use_dns;
124 int client_alive_interval; /* 130 int client_alive_interval; /*
@@ -141,6 +147,8 @@ typedef struct {
141 int permit_tun; 147 int permit_tun;
142 148
143 int num_permitted_opens; 149 int num_permitted_opens;
150
151 char *chroot_directory;
144} ServerOptions; 152} ServerOptions;
145 153
146void initialize_server_options(ServerOptions *); 154void initialize_server_options(ServerOptions *);
@@ -153,5 +161,6 @@ void parse_server_config(ServerOptions *, const char *, Buffer *,
153void parse_server_match_config(ServerOptions *, const char *, const char *, 161void parse_server_match_config(ServerOptions *, const char *, const char *,
154 const char *); 162 const char *);
155void copy_set_server_options(ServerOptions *, ServerOptions *, int); 163void copy_set_server_options(ServerOptions *, ServerOptions *, int);
164void dump_config(ServerOptions *);
156 165
157#endif /* SERVCONF_H */ 166#endif /* SERVCONF_H */
diff --git a/serverloop.c b/serverloop.c
index 7e373f01b..77d9dee75 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.145 2006/10/11 12:38:03 markus Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.153 2008/06/30 12:15:39 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
@@ -56,6 +56,7 @@
56#include <unistd.h> 56#include <unistd.h>
57#include <stdarg.h> 57#include <stdarg.h>
58 58
59#include "openbsd-compat/sys-queue.h"
59#include "xmalloc.h" 60#include "xmalloc.h"
60#include "packet.h" 61#include "packet.h"
61#include "buffer.h" 62#include "buffer.h"
@@ -104,7 +105,7 @@ static int connection_in; /* Connection to client (input). */
104static int connection_out; /* Connection to client (output). */ 105static int connection_out; /* Connection to client (output). */
105static int connection_closed = 0; /* Connection to client closed. */ 106static int connection_closed = 0; /* Connection to client closed. */
106static u_int buffer_high; /* "Soft" max buffer size. */ 107static u_int buffer_high; /* "Soft" max buffer size. */
107static int client_alive_timeouts = 0; 108static int no_more_sessions = 0; /* Disallow further sessions. */
108 109
109/* 110/*
110 * This SIGCHLD kludge is used to detect when the child exits. The server 111 * This SIGCHLD kludge is used to detect when the child exits. The server
@@ -248,7 +249,7 @@ client_alive_check(void)
248 int channel_id; 249 int channel_id;
249 250
250 /* timeout, check to see how many we have had */ 251 /* timeout, check to see how many we have had */
251 if (++client_alive_timeouts > options.client_alive_count_max) { 252 if (++keep_alive_timeouts > options.client_alive_count_max) {
252 logit("Timeout, client not responding."); 253 logit("Timeout, client not responding.");
253 cleanup_exit(255); 254 cleanup_exit(255);
254 } 255 }
@@ -399,7 +400,8 @@ process_input(fd_set *readset)
399 return; 400 return;
400 cleanup_exit(255); 401 cleanup_exit(255);
401 } else if (len < 0) { 402 } else if (len < 0) {
402 if (errno != EINTR && errno != EAGAIN) { 403 if (errno != EINTR && errno != EAGAIN &&
404 errno != EWOULDBLOCK) {
403 verbose("Read error from remote host " 405 verbose("Read error from remote host "
404 "%.100s: %.100s", 406 "%.100s: %.100s",
405 get_remote_ipaddr(), strerror(errno)); 407 get_remote_ipaddr(), strerror(errno));
@@ -417,8 +419,8 @@ process_input(fd_set *readset)
417 if (!fdout_eof && FD_ISSET(fdout, readset)) { 419 if (!fdout_eof && FD_ISSET(fdout, readset)) {
418 errno = 0; 420 errno = 0;
419 len = read(fdout, buf, sizeof(buf)); 421 len = read(fdout, buf, sizeof(buf));
420 if (len < 0 && (errno == EINTR || 422 if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
421 (errno == EAGAIN && !child_terminated))) { 423 errno == EWOULDBLOCK) && !child_terminated))) {
422 /* do nothing */ 424 /* do nothing */
423#ifndef PTY_ZEROREAD 425#ifndef PTY_ZEROREAD
424 } else if (len <= 0) { 426 } else if (len <= 0) {
@@ -436,8 +438,8 @@ process_input(fd_set *readset)
436 if (!fderr_eof && FD_ISSET(fderr, readset)) { 438 if (!fderr_eof && FD_ISSET(fderr, readset)) {
437 errno = 0; 439 errno = 0;
438 len = read(fderr, buf, sizeof(buf)); 440 len = read(fderr, buf, sizeof(buf));
439 if (len < 0 && (errno == EINTR || 441 if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
440 (errno == EAGAIN && !child_terminated))) { 442 errno == EWOULDBLOCK) && !child_terminated))) {
441 /* do nothing */ 443 /* do nothing */
442#ifndef PTY_ZEROREAD 444#ifndef PTY_ZEROREAD
443 } else if (len <= 0) { 445 } else if (len <= 0) {
@@ -468,7 +470,8 @@ process_output(fd_set *writeset)
468 data = buffer_ptr(&stdin_buffer); 470 data = buffer_ptr(&stdin_buffer);
469 dlen = buffer_len(&stdin_buffer); 471 dlen = buffer_len(&stdin_buffer);
470 len = write(fdin, data, dlen); 472 len = write(fdin, data, dlen);
471 if (len < 0 && (errno == EINTR || errno == EAGAIN)) { 473 if (len < 0 &&
474 (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) {
472 /* do nothing */ 475 /* do nothing */
473 } else if (len <= 0) { 476 } else if (len <= 0) {
474 if (fdin != fdout) 477 if (fdin != fdout)
@@ -887,7 +890,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
887 * even if this was generated by something other than 890 * even if this was generated by something other than
888 * the bogus CHANNEL_REQUEST we send for keepalives. 891 * the bogus CHANNEL_REQUEST we send for keepalives.
889 */ 892 */
890 client_alive_timeouts = 0; 893 keep_alive_timeouts = 0;
891} 894}
892 895
893static void 896static void
@@ -938,7 +941,6 @@ static Channel *
938server_request_direct_tcpip(void) 941server_request_direct_tcpip(void)
939{ 942{
940 Channel *c; 943 Channel *c;
941 int sock;
942 char *target, *originator; 944 char *target, *originator;
943 int target_port, originator_port; 945 int target_port, originator_port;
944 946
@@ -948,18 +950,16 @@ server_request_direct_tcpip(void)
948 originator_port = packet_get_int(); 950 originator_port = packet_get_int();
949 packet_check_eom(); 951 packet_check_eom();
950 952
951 debug("server_request_direct_tcpip: originator %s port %d, target %s port %d", 953 debug("server_request_direct_tcpip: originator %s port %d, target %s "
952 originator, originator_port, target, target_port); 954 "port %d", originator, originator_port, target, target_port);
953 955
954 /* XXX check permission */ 956 /* XXX check permission */
955 sock = channel_connect_to(target, target_port); 957 c = channel_connect_to(target, target_port,
956 xfree(target); 958 "direct-tcpip", "direct-tcpip");
959
957 xfree(originator); 960 xfree(originator);
958 if (sock < 0) 961 xfree(target);
959 return NULL; 962
960 c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
961 sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
962 CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
963 return c; 963 return c;
964} 964}
965 965
@@ -1000,7 +1000,7 @@ server_request_tun(void)
1000#if defined(SSH_TUN_FILTER) 1000#if defined(SSH_TUN_FILTER)
1001 if (mode == SSH_TUNMODE_POINTOPOINT) 1001 if (mode == SSH_TUNMODE_POINTOPOINT)
1002 channel_register_filter(c->self, sys_tun_infilter, 1002 channel_register_filter(c->self, sys_tun_infilter,
1003 sys_tun_outfilter); 1003 sys_tun_outfilter, NULL, NULL);
1004#endif 1004#endif
1005 1005
1006 done: 1006 done:
@@ -1016,6 +1016,12 @@ server_request_session(void)
1016 1016
1017 debug("input_session_request"); 1017 debug("input_session_request");
1018 packet_check_eom(); 1018 packet_check_eom();
1019
1020 if (no_more_sessions) {
1021 packet_disconnect("Possible attack: attempt to open a session "
1022 "after additional sessions disabled");
1023 }
1024
1019 /* 1025 /*
1020 * A server session has no fd to read or write until a 1026 * A server session has no fd to read or write until a
1021 * CHANNEL_REQUEST for a shell is made, so we set the type to 1027 * CHANNEL_REQUEST for a shell is made, so we set the type to
@@ -1136,6 +1142,9 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
1136 success = channel_cancel_rport_listener(cancel_address, 1142 success = channel_cancel_rport_listener(cancel_address,
1137 cancel_port); 1143 cancel_port);
1138 xfree(cancel_address); 1144 xfree(cancel_address);
1145 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
1146 no_more_sessions = 1;
1147 success = 1;
1139 } 1148 }
1140 if (want_reply) { 1149 if (want_reply) {
1141 packet_start(success ? 1150 packet_start(success ?
@@ -1163,7 +1172,11 @@ server_input_channel_req(int type, u_int32_t seq, void *ctxt)
1163 if ((c = channel_lookup(id)) == NULL) 1172 if ((c = channel_lookup(id)) == NULL)
1164 packet_disconnect("server_input_channel_req: " 1173 packet_disconnect("server_input_channel_req: "
1165 "unknown channel %d", id); 1174 "unknown channel %d", id);
1166 if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) 1175 if (!strcmp(rtype, "eow@openssh.com")) {
1176 packet_check_eom();
1177 chan_rcvd_eow(c);
1178 } else if ((c->type == SSH_CHANNEL_LARVAL ||
1179 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
1167 success = session_input_channel_req(c, rtype); 1180 success = session_input_channel_req(c, rtype);
1168 if (reply) { 1181 if (reply) {
1169 packet_start(success ? 1182 packet_start(success ?
@@ -1189,8 +1202,9 @@ server_init_dispatch_20(void)
1189 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req); 1202 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
1190 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 1203 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
1191 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); 1204 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
1205 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
1206 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
1192 /* client_alive */ 1207 /* client_alive */
1193 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
1194 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive); 1208 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
1195 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive); 1209 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
1196 /* rekeying */ 1210 /* rekeying */
diff --git a/session.c b/session.c
index 9a606ef8f..93babf957 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.c,v 1.221 2007/01/21 01:41:54 stevesk Exp $ */ 1/* $OpenBSD: session.c,v 1.241 2008/06/16 13:22:53 dtucker 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
@@ -59,6 +59,7 @@
59#include <string.h> 59#include <string.h>
60#include <unistd.h> 60#include <unistd.h>
61 61
62#include "openbsd-compat/sys-queue.h"
62#include "xmalloc.h" 63#include "xmalloc.h"
63#include "ssh.h" 64#include "ssh.h"
64#include "ssh1.h" 65#include "ssh1.h"
@@ -84,9 +85,11 @@
84#include "sshlogin.h" 85#include "sshlogin.h"
85#include "serverloop.h" 86#include "serverloop.h"
86#include "canohost.h" 87#include "canohost.h"
88#include "misc.h"
87#include "session.h" 89#include "session.h"
88#include "kex.h" 90#include "kex.h"
89#include "monitor_wrap.h" 91#include "monitor_wrap.h"
92#include "sftp.h"
90 93
91#if defined(KRB5) && defined(USE_AFS) 94#if defined(KRB5) && defined(USE_AFS)
92#include <kafs.h> 95#include <kafs.h>
@@ -95,13 +98,13 @@
95/* func */ 98/* func */
96 99
97Session *session_new(void); 100Session *session_new(void);
98void session_set_fds(Session *, int, int, int); 101void session_set_fds(Session *, int, int, int, int);
99void session_pty_cleanup(Session *); 102void session_pty_cleanup(Session *);
100void session_proctitle(Session *); 103void session_proctitle(Session *);
101int session_setup_x11fwd(Session *); 104int session_setup_x11fwd(Session *);
102void do_exec_pty(Session *, const char *); 105int do_exec_pty(Session *, const char *);
103void do_exec_no_pty(Session *, const char *); 106int do_exec_no_pty(Session *, const char *);
104void do_exec(Session *, const char *); 107int do_exec(Session *, const char *);
105void do_login(Session *, const char *); 108void do_login(Session *, const char *);
106#ifdef LOGIN_NEEDS_UTMPX 109#ifdef LOGIN_NEEDS_UTMPX
107static void do_pre_login(Session *s); 110static void do_pre_login(Session *s);
@@ -129,8 +132,13 @@ extern Buffer loginmsg;
129const char *original_command = NULL; 132const char *original_command = NULL;
130 133
131/* data */ 134/* data */
132#define MAX_SESSIONS 10 135static int sessions_first_unused = -1;
133Session sessions[MAX_SESSIONS]; 136static int sessions_nalloc = 0;
137static Session *sessions = NULL;
138
139#define SUBSYSTEM_NONE 0
140#define SUBSYSTEM_EXT 1
141#define SUBSYSTEM_INT_SFTP 2
134 142
135#ifdef HAVE_LOGIN_CAP 143#ifdef HAVE_LOGIN_CAP
136login_cap_t *lc; 144login_cap_t *lc;
@@ -160,7 +168,7 @@ static int
160auth_input_request_forwarding(struct passwd * pw) 168auth_input_request_forwarding(struct passwd * pw)
161{ 169{
162 Channel *nc; 170 Channel *nc;
163 int sock; 171 int sock = -1;
164 struct sockaddr_un sunaddr; 172 struct sockaddr_un sunaddr;
165 173
166 if (auth_sock_name != NULL) { 174 if (auth_sock_name != NULL) {
@@ -172,43 +180,48 @@ auth_input_request_forwarding(struct passwd * pw)
172 temporarily_use_uid(pw); 180 temporarily_use_uid(pw);
173 181
174 /* Allocate a buffer for the socket name, and format the name. */ 182 /* Allocate a buffer for the socket name, and format the name. */
175 auth_sock_name = xmalloc(MAXPATHLEN); 183 auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX");
176 auth_sock_dir = xmalloc(MAXPATHLEN);
177 strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
178 184
179 /* Create private directory for socket */ 185 /* Create private directory for socket */
180 if (mkdtemp(auth_sock_dir) == NULL) { 186 if (mkdtemp(auth_sock_dir) == NULL) {
181 packet_send_debug("Agent forwarding disabled: " 187 packet_send_debug("Agent forwarding disabled: "
182 "mkdtemp() failed: %.100s", strerror(errno)); 188 "mkdtemp() failed: %.100s", strerror(errno));
183 restore_uid(); 189 restore_uid();
184 xfree(auth_sock_name);
185 xfree(auth_sock_dir); 190 xfree(auth_sock_dir);
186 auth_sock_name = NULL;
187 auth_sock_dir = NULL; 191 auth_sock_dir = NULL;
188 return 0; 192 goto authsock_err;
189 } 193 }
190 snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld", 194
191 auth_sock_dir, (long) getpid()); 195 xasprintf(&auth_sock_name, "%s/agent.%ld",
196 auth_sock_dir, (long) getpid());
192 197
193 /* Create the socket. */ 198 /* Create the socket. */
194 sock = socket(AF_UNIX, SOCK_STREAM, 0); 199 sock = socket(AF_UNIX, SOCK_STREAM, 0);
195 if (sock < 0) 200 if (sock < 0) {
196 packet_disconnect("socket: %.100s", strerror(errno)); 201 error("socket: %.100s", strerror(errno));
202 restore_uid();
203 goto authsock_err;
204 }
197 205
198 /* Bind it to the name. */ 206 /* Bind it to the name. */
199 memset(&sunaddr, 0, sizeof(sunaddr)); 207 memset(&sunaddr, 0, sizeof(sunaddr));
200 sunaddr.sun_family = AF_UNIX; 208 sunaddr.sun_family = AF_UNIX;
201 strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); 209 strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
202 210
203 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) 211 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
204 packet_disconnect("bind: %.100s", strerror(errno)); 212 error("bind: %.100s", strerror(errno));
213 restore_uid();
214 goto authsock_err;
215 }
205 216
206 /* Restore the privileged uid. */ 217 /* Restore the privileged uid. */
207 restore_uid(); 218 restore_uid();
208 219
209 /* Start listening on the socket. */ 220 /* Start listening on the socket. */
210 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) 221 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
211 packet_disconnect("listen: %.100s", strerror(errno)); 222 error("listen: %.100s", strerror(errno));
223 goto authsock_err;
224 }
212 225
213 /* Allocate a channel for the authentication agent socket. */ 226 /* Allocate a channel for the authentication agent socket. */
214 nc = channel_new("auth socket", 227 nc = channel_new("auth socket",
@@ -217,6 +230,19 @@ auth_input_request_forwarding(struct passwd * pw)
217 0, "auth socket", 1); 230 0, "auth socket", 1);
218 strlcpy(nc->path, auth_sock_name, sizeof(nc->path)); 231 strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
219 return 1; 232 return 1;
233
234 authsock_err:
235 if (auth_sock_name != NULL)
236 xfree(auth_sock_name);
237 if (auth_sock_dir != NULL) {
238 rmdir(auth_sock_dir);
239 xfree(auth_sock_dir);
240 }
241 if (sock != -1)
242 close(sock);
243 auth_sock_name = NULL;
244 auth_sock_dir = NULL;
245 return 0;
220} 246}
221 247
222static void 248static void
@@ -329,7 +355,8 @@ do_authenticated1(Authctxt *authctxt)
329 break; 355 break;
330 356
331 case SSH_CMSG_AGENT_REQUEST_FORWARDING: 357 case SSH_CMSG_AGENT_REQUEST_FORWARDING:
332 if (no_agent_forwarding_flag || compat13) { 358 if (!options.allow_agent_forwarding ||
359 no_agent_forwarding_flag || compat13) {
333 debug("Authentication agent forwarding not permitted for this authentication."); 360 debug("Authentication agent forwarding not permitted for this authentication.");
334 break; 361 break;
335 } 362 }
@@ -365,10 +392,14 @@ do_authenticated1(Authctxt *authctxt)
365 if (type == SSH_CMSG_EXEC_CMD) { 392 if (type == SSH_CMSG_EXEC_CMD) {
366 command = packet_get_string(&dlen); 393 command = packet_get_string(&dlen);
367 debug("Exec command '%.500s'", command); 394 debug("Exec command '%.500s'", command);
368 do_exec(s, command); 395 if (do_exec(s, command) != 0)
396 packet_disconnect(
397 "command execution failed");
369 xfree(command); 398 xfree(command);
370 } else { 399 } else {
371 do_exec(s, NULL); 400 if (do_exec(s, NULL) != 0)
401 packet_disconnect(
402 "shell execution failed");
372 } 403 }
373 packet_check_eom(); 404 packet_check_eom();
374 session_close(s); 405 session_close(s);
@@ -393,46 +424,84 @@ do_authenticated1(Authctxt *authctxt)
393 } 424 }
394} 425}
395 426
427#define USE_PIPES
396/* 428/*
397 * This is called to fork and execute a command when we have no tty. This 429 * This is called to fork and execute a command when we have no tty. This
398 * will call do_child from the child, and server_loop from the parent after 430 * will call do_child from the child, and server_loop from the parent after
399 * setting up file descriptors and such. 431 * setting up file descriptors and such.
400 */ 432 */
401void 433int
402do_exec_no_pty(Session *s, const char *command) 434do_exec_no_pty(Session *s, const char *command)
403{ 435{
404 pid_t pid; 436 pid_t pid;
405 437
406#ifdef USE_PIPES 438#ifdef USE_PIPES
407 int pin[2], pout[2], perr[2]; 439 int pin[2], pout[2], perr[2];
440
408 /* Allocate pipes for communicating with the program. */ 441 /* Allocate pipes for communicating with the program. */
409 if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) 442 if (pipe(pin) < 0) {
410 packet_disconnect("Could not create pipes: %.100s", 443 error("%s: pipe in: %.100s", __func__, strerror(errno));
411 strerror(errno)); 444 return -1;
412#else /* USE_PIPES */ 445 }
446 if (pipe(pout) < 0) {
447 error("%s: pipe out: %.100s", __func__, strerror(errno));
448 close(pin[0]);
449 close(pin[1]);
450 return -1;
451 }
452 if (pipe(perr) < 0) {
453 error("%s: pipe err: %.100s", __func__, strerror(errno));
454 close(pin[0]);
455 close(pin[1]);
456 close(pout[0]);
457 close(pout[1]);
458 return -1;
459 }
460#else
413 int inout[2], err[2]; 461 int inout[2], err[2];
462
414 /* Uses socket pairs to communicate with the program. */ 463 /* Uses socket pairs to communicate with the program. */
415 if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || 464 if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) {
416 socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) 465 error("%s: socketpair #1: %.100s", __func__, strerror(errno));
417 packet_disconnect("Could not create socket pairs: %.100s", 466 return -1;
418 strerror(errno)); 467 }
419#endif /* USE_PIPES */ 468 if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
469 error("%s: socketpair #2: %.100s", __func__, strerror(errno));
470 close(inout[0]);
471 close(inout[1]);
472 return -1;
473 }
474#endif
475
420 if (s == NULL) 476 if (s == NULL)
421 fatal("do_exec_no_pty: no session"); 477 fatal("do_exec_no_pty: no session");
422 478
423 session_proctitle(s); 479 session_proctitle(s);
424 480
425#if defined(USE_PAM)
426 if (options.use_pam && !use_privsep)
427 do_pam_setcred(1);
428#endif /* USE_PAM */
429
430 /* Fork the child. */ 481 /* Fork the child. */
431 if ((pid = fork()) == 0) { 482 switch ((pid = fork())) {
483 case -1:
484 error("%s: fork: %.100s", __func__, strerror(errno));
485#ifdef USE_PIPES
486 close(pin[0]);
487 close(pin[1]);
488 close(pout[0]);
489 close(pout[1]);
490 close(perr[0]);
491 close(perr[1]);
492#else
493 close(inout[0]);
494 close(inout[1]);
495 close(err[0]);
496 close(err[1]);
497#endif
498 return -1;
499 case 0:
432 is_child = 1; 500 is_child = 1;
433 501
434 /* Child. Reinitialize the log since the pid has changed. */ 502 /* Child. Reinitialize the log since the pid has changed. */
435 log_init(__progname, options.log_level, options.log_facility, log_stderr); 503 log_init(__progname, options.log_level,
504 options.log_facility, log_stderr);
436 505
437 /* 506 /*
438 * Create a new session and process group since the 4.4BSD 507 * Create a new session and process group since the 4.4BSD
@@ -462,7 +531,7 @@ do_exec_no_pty(Session *s, const char *command)
462 if (dup2(perr[1], 2) < 0) 531 if (dup2(perr[1], 2) < 0)
463 perror("dup2 stderr"); 532 perror("dup2 stderr");
464 close(perr[1]); 533 close(perr[1]);
465#else /* USE_PIPES */ 534#else
466 /* 535 /*
467 * Redirect stdin, stdout, and stderr. Stdin and stdout will 536 * Redirect stdin, stdout, and stderr. Stdin and stdout will
468 * use the same socket, as some programs (particularly rdist) 537 * use the same socket, as some programs (particularly rdist)
@@ -472,11 +541,14 @@ do_exec_no_pty(Session *s, const char *command)
472 close(err[1]); 541 close(err[1]);
473 if (dup2(inout[0], 0) < 0) /* stdin */ 542 if (dup2(inout[0], 0) < 0) /* stdin */
474 perror("dup2 stdin"); 543 perror("dup2 stdin");
475 if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ 544 if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */
476 perror("dup2 stdout"); 545 perror("dup2 stdout");
546 close(inout[0]);
477 if (dup2(err[0], 2) < 0) /* stderr */ 547 if (dup2(err[0], 2) < 0) /* stderr */
478 perror("dup2 stderr"); 548 perror("dup2 stderr");
479#endif /* USE_PIPES */ 549 close(err[0]);
550#endif
551
480 552
481#ifdef _UNICOS 553#ifdef _UNICOS
482 cray_init_job(s->pw); /* set up cray jid and tmpdir */ 554 cray_init_job(s->pw); /* set up cray jid and tmpdir */
@@ -485,7 +557,10 @@ do_exec_no_pty(Session *s, const char *command)
485 /* Do processing for the child (exec command etc). */ 557 /* Do processing for the child (exec command etc). */
486 do_child(s, command); 558 do_child(s, command);
487 /* NOTREACHED */ 559 /* NOTREACHED */
560 default:
561 break;
488 } 562 }
563
489#ifdef _UNICOS 564#ifdef _UNICOS
490 signal(WJSIGNAL, cray_job_termination_handler); 565 signal(WJSIGNAL, cray_job_termination_handler);
491#endif /* _UNICOS */ 566#endif /* _UNICOS */
@@ -493,11 +568,18 @@ do_exec_no_pty(Session *s, const char *command)
493 if (is_winnt) 568 if (is_winnt)
494 cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); 569 cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
495#endif 570#endif
496 if (pid < 0) 571
497 packet_disconnect("fork failed: %.100s", strerror(errno));
498 s->pid = pid; 572 s->pid = pid;
499 /* Set interactive/non-interactive mode. */ 573 /* Set interactive/non-interactive mode. */
500 packet_set_interactive(s->display != NULL); 574 packet_set_interactive(s->display != NULL);
575
576 /*
577 * Clear loginmsg, since it's the child's responsibility to display
578 * it to the user, otherwise multiple sessions may accumulate
579 * multiple copies of the login messages.
580 */
581 buffer_clear(&loginmsg);
582
501#ifdef USE_PIPES 583#ifdef USE_PIPES
502 /* We are the parent. Close the child sides of the pipes. */ 584 /* We are the parent. Close the child sides of the pipes. */
503 close(pin[0]); 585 close(pin[0]);
@@ -509,35 +591,32 @@ do_exec_no_pty(Session *s, const char *command)
509 close(perr[0]); 591 close(perr[0]);
510 perr[0] = -1; 592 perr[0] = -1;
511 } 593 }
512 session_set_fds(s, pin[1], pout[0], perr[0]); 594 session_set_fds(s, pin[1], pout[0], perr[0], 0);
513 } else { 595 } else {
514 /* Enter the interactive session. */ 596 /* Enter the interactive session. */
515 server_loop(pid, pin[1], pout[0], perr[0]); 597 server_loop(pid, pin[1], pout[0], perr[0]);
516 /* server_loop has closed pin[1], pout[0], and perr[0]. */ 598 /* server_loop has closed pin[1], pout[0], and perr[0]. */
517 } 599 }
518#else /* USE_PIPES */ 600#else
519 /* We are the parent. Close the child sides of the socket pairs. */ 601 /* We are the parent. Close the child sides of the socket pairs. */
520 close(inout[0]); 602 close(inout[0]);
521 close(err[0]); 603 close(err[0]);
522 604
523 /* 605 /*
524 * Clear loginmsg, since it's the child's responsibility to display
525 * it to the user, otherwise multiple sessions may accumulate
526 * multiple copies of the login messages.
527 */
528 buffer_clear(&loginmsg);
529
530 /*
531 * Enter the interactive session. Note: server_loop must be able to 606 * Enter the interactive session. Note: server_loop must be able to
532 * handle the case that fdin and fdout are the same. 607 * handle the case that fdin and fdout are the same.
533 */ 608 */
534 if (compat20) { 609 if (compat20) {
535 session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]); 610 session_set_fds(s, inout[1], inout[1],
611 s->is_subsystem ? -1 : err[1], 0);
612 if (s->is_subsystem)
613 close(err[1]);
536 } else { 614 } else {
537 server_loop(pid, inout[1], inout[1], err[1]); 615 server_loop(pid, inout[1], inout[1], err[1]);
538 /* server_loop has closed inout[1] and err[1]. */ 616 /* server_loop has closed inout[1] and err[1]. */
539 } 617 }
540#endif /* USE_PIPES */ 618#endif
619 return 0;
541} 620}
542 621
543/* 622/*
@@ -546,7 +625,7 @@ do_exec_no_pty(Session *s, const char *command)
546 * setting up file descriptors, controlling tty, updating wtmp, utmp, 625 * setting up file descriptors, controlling tty, updating wtmp, utmp,
547 * lastlog, and other such operations. 626 * lastlog, and other such operations.
548 */ 627 */
549void 628int
550do_exec_pty(Session *s, const char *command) 629do_exec_pty(Session *s, const char *command)
551{ 630{
552 int fdout, ptyfd, ttyfd, ptymaster; 631 int fdout, ptyfd, ttyfd, ptymaster;
@@ -557,20 +636,46 @@ do_exec_pty(Session *s, const char *command)
557 ptyfd = s->ptyfd; 636 ptyfd = s->ptyfd;
558 ttyfd = s->ttyfd; 637 ttyfd = s->ttyfd;
559 638
560#if defined(USE_PAM) 639 /*
561 if (options.use_pam) { 640 * Create another descriptor of the pty master side for use as the
562 do_pam_set_tty(s->tty); 641 * standard input. We could use the original descriptor, but this
563 if (!use_privsep) 642 * simplifies code in server_loop. The descriptor is bidirectional.
564 do_pam_setcred(1); 643 * Do this before forking (and cleanup in the child) so as to
644 * detect and gracefully fail out-of-fd conditions.
645 */
646 if ((fdout = dup(ptyfd)) < 0) {
647 error("%s: dup #1: %s", __func__, strerror(errno));
648 close(ttyfd);
649 close(ptyfd);
650 return -1;
651 }
652 /* we keep a reference to the pty master */
653 if ((ptymaster = dup(ptyfd)) < 0) {
654 error("%s: dup #2: %s", __func__, strerror(errno));
655 close(ttyfd);
656 close(ptyfd);
657 close(fdout);
658 return -1;
565 } 659 }
566#endif
567 660
568 /* Fork the child. */ 661 /* Fork the child. */
569 if ((pid = fork()) == 0) { 662 switch ((pid = fork())) {
663 case -1:
664 error("%s: fork: %.100s", __func__, strerror(errno));
665 close(fdout);
666 close(ptymaster);
667 close(ttyfd);
668 close(ptyfd);
669 return -1;
670 case 0:
570 is_child = 1; 671 is_child = 1;
571 672
673 close(fdout);
674 close(ptymaster);
675
572 /* Child. Reinitialize the log because the pid has changed. */ 676 /* Child. Reinitialize the log because the pid has changed. */
573 log_init(__progname, options.log_level, options.log_facility, log_stderr); 677 log_init(__progname, options.log_level,
678 options.log_facility, log_stderr);
574 /* Close the master side of the pseudo tty. */ 679 /* Close the master side of the pseudo tty. */
575 close(ptyfd); 680 close(ptyfd);
576 681
@@ -601,11 +706,16 @@ do_exec_pty(Session *s, const char *command)
601 do_pre_login(s); 706 do_pre_login(s);
602# endif 707# endif
603#endif 708#endif
604 709 /*
605 /* Do common processing for the child, such as execing the command. */ 710 * Do common processing for the child, such as execing
606 do_child(s, command); 711 * the command.
607 /* NOTREACHED */ 712 */
713 do_child(s, command);
714 /* NOTREACHED */
715 default:
716 break;
608 } 717 }
718
609#ifdef _UNICOS 719#ifdef _UNICOS
610 signal(WJSIGNAL, cray_job_termination_handler); 720 signal(WJSIGNAL, cray_job_termination_handler);
611#endif /* _UNICOS */ 721#endif /* _UNICOS */
@@ -613,36 +723,22 @@ do_exec_pty(Session *s, const char *command)
613 if (is_winnt) 723 if (is_winnt)
614 cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); 724 cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
615#endif 725#endif
616 if (pid < 0) 726
617 packet_disconnect("fork failed: %.100s", strerror(errno));
618 s->pid = pid; 727 s->pid = pid;
619 728
620 /* Parent. Close the slave side of the pseudo tty. */ 729 /* Parent. Close the slave side of the pseudo tty. */
621 close(ttyfd); 730 close(ttyfd);
622 731
623 /*
624 * Create another descriptor of the pty master side for use as the
625 * standard input. We could use the original descriptor, but this
626 * simplifies code in server_loop. The descriptor is bidirectional.
627 */
628 fdout = dup(ptyfd);
629 if (fdout < 0)
630 packet_disconnect("dup #1 failed: %.100s", strerror(errno));
631
632 /* we keep a reference to the pty master */
633 ptymaster = dup(ptyfd);
634 if (ptymaster < 0)
635 packet_disconnect("dup #2 failed: %.100s", strerror(errno));
636 s->ptymaster = ptymaster;
637
638 /* Enter interactive session. */ 732 /* Enter interactive session. */
733 s->ptymaster = ptymaster;
639 packet_set_interactive(1); 734 packet_set_interactive(1);
640 if (compat20) { 735 if (compat20) {
641 session_set_fds(s, ptyfd, fdout, -1); 736 session_set_fds(s, ptyfd, fdout, -1, 1);
642 } else { 737 } else {
643 server_loop(pid, ptyfd, fdout, -1); 738 server_loop(pid, ptyfd, fdout, -1);
644 /* server_loop _has_ closed ptyfd and fdout. */ 739 /* server_loop _has_ closed ptyfd and fdout. */
645 } 740 }
741 return 0;
646} 742}
647 743
648#ifdef LOGIN_NEEDS_UTMPX 744#ifdef LOGIN_NEEDS_UTMPX
@@ -677,16 +773,26 @@ do_pre_login(Session *s)
677 * This is called to fork and execute a command. If another command is 773 * This is called to fork and execute a command. If another command is
678 * to be forced, execute that instead. 774 * to be forced, execute that instead.
679 */ 775 */
680void 776int
681do_exec(Session *s, const char *command) 777do_exec(Session *s, const char *command)
682{ 778{
779 int ret;
780
683 if (options.adm_forced_command) { 781 if (options.adm_forced_command) {
684 original_command = command; 782 original_command = command;
685 command = options.adm_forced_command; 783 command = options.adm_forced_command;
784 if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
785 s->is_subsystem = SUBSYSTEM_INT_SFTP;
786 else if (s->is_subsystem)
787 s->is_subsystem = SUBSYSTEM_EXT;
686 debug("Forced command (config) '%.900s'", command); 788 debug("Forced command (config) '%.900s'", command);
687 } else if (forced_command) { 789 } else if (forced_command) {
688 original_command = command; 790 original_command = command;
689 command = forced_command; 791 command = forced_command;
792 if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
793 s->is_subsystem = SUBSYSTEM_INT_SFTP;
794 else if (s->is_subsystem)
795 s->is_subsystem = SUBSYSTEM_EXT;
690 debug("Forced command (key option) '%.900s'", command); 796 debug("Forced command (key option) '%.900s'", command);
691 } 797 }
692 798
@@ -701,11 +807,10 @@ do_exec(Session *s, const char *command)
701 PRIVSEP(audit_run_command(shell)); 807 PRIVSEP(audit_run_command(shell));
702 } 808 }
703#endif 809#endif
704
705 if (s->ttyfd != -1) 810 if (s->ttyfd != -1)
706 do_exec_pty(s, command); 811 ret = do_exec_pty(s, command);
707 else 812 else
708 do_exec_no_pty(s, command); 813 ret = do_exec_no_pty(s, command);
709 814
710 original_command = NULL; 815 original_command = NULL;
711 816
@@ -715,6 +820,8 @@ do_exec(Session *s, const char *command)
715 * multiple copies of the login messages. 820 * multiple copies of the login messages.
716 */ 821 */
717 buffer_clear(&loginmsg); 822 buffer_clear(&loginmsg);
823
824 return ret;
718} 825}
719 826
720/* administrative, login(1)-like work */ 827/* administrative, login(1)-like work */
@@ -897,8 +1004,9 @@ read_environment_file(char ***env, u_int *envsize,
897 ; 1004 ;
898 if (!*cp || *cp == '#' || *cp == '\n') 1005 if (!*cp || *cp == '#' || *cp == '\n')
899 continue; 1006 continue;
900 if (strchr(cp, '\n')) 1007
901 *strchr(cp, '\n') = '\0'; 1008 cp[strcspn(cp, "\n")] = '\0';
1009
902 value = strchr(cp, '='); 1010 value = strchr(cp, '=');
903 if (value == NULL) { 1011 if (value == NULL) {
904 fprintf(stderr, "Bad line %u in %.100s\n", lineno, 1012 fprintf(stderr, "Bad line %u in %.100s\n", lineno,
@@ -1201,8 +1309,9 @@ do_rc_files(Session *s, const char *shell)
1201 do_xauth = 1309 do_xauth =
1202 s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL; 1310 s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
1203 1311
1204 /* ignore _PATH_SSH_USER_RC for subsystems */ 1312 /* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */
1205 if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) { 1313 if (!s->is_subsystem && options.adm_forced_command == NULL &&
1314 !no_user_rc && stat(_PATH_SSH_USER_RC, &st) >= 0) {
1206 snprintf(cmd, sizeof cmd, "%s -c '%s %s'", 1315 snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
1207 shell, _PATH_BSHELL, _PATH_SSH_USER_RC); 1316 shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
1208 if (debug_flag) 1317 if (debug_flag)
@@ -1283,10 +1392,72 @@ do_nologin(struct passwd *pw)
1283 } 1392 }
1284} 1393}
1285 1394
1395/*
1396 * Chroot into a directory after checking it for safety: all path components
1397 * must be root-owned directories with strict permissions.
1398 */
1399static void
1400safely_chroot(const char *path, uid_t uid)
1401{
1402 const char *cp;
1403 char component[MAXPATHLEN];
1404 struct stat st;
1405
1406 if (*path != '/')
1407 fatal("chroot path does not begin at root");
1408 if (strlen(path) >= sizeof(component))
1409 fatal("chroot path too long");
1410
1411 /*
1412 * Descend the path, checking that each component is a
1413 * root-owned directory with strict permissions.
1414 */
1415 for (cp = path; cp != NULL;) {
1416 if ((cp = strchr(cp, '/')) == NULL)
1417 strlcpy(component, path, sizeof(component));
1418 else {
1419 cp++;
1420 memcpy(component, path, cp - path);
1421 component[cp - path] = '\0';
1422 }
1423
1424 debug3("%s: checking '%s'", __func__, component);
1425
1426 if (stat(component, &st) != 0)
1427 fatal("%s: stat(\"%s\"): %s", __func__,
1428 component, strerror(errno));
1429 if (st.st_uid != 0 || (st.st_mode & 022) != 0)
1430 fatal("bad ownership or modes for chroot "
1431 "directory %s\"%s\"",
1432 cp == NULL ? "" : "component ", component);
1433 if (!S_ISDIR(st.st_mode))
1434 fatal("chroot path %s\"%s\" is not a directory",
1435 cp == NULL ? "" : "component ", component);
1436
1437 }
1438
1439 if (chdir(path) == -1)
1440 fatal("Unable to chdir to chroot path \"%s\": "
1441 "%s", path, strerror(errno));
1442 if (chroot(path) == -1)
1443 fatal("chroot(\"%s\"): %s", path, strerror(errno));
1444 if (chdir("/") == -1)
1445 fatal("%s: chdir(/) after chroot: %s",
1446 __func__, strerror(errno));
1447 verbose("Changed root directory to \"%s\"", path);
1448}
1449
1286/* Set login name, uid, gid, and groups. */ 1450/* Set login name, uid, gid, and groups. */
1287void 1451void
1288do_setusercontext(struct passwd *pw) 1452do_setusercontext(struct passwd *pw)
1289{ 1453{
1454 char *chroot_path, *tmp;
1455
1456#ifdef WITH_SELINUX
1457 /* Cache selinux status for later use */
1458 (void)ssh_selinux_enabled();
1459#endif
1460
1290#ifndef HAVE_CYGWIN 1461#ifndef HAVE_CYGWIN
1291 if (getuid() == 0 || geteuid() == 0) 1462 if (getuid() == 0 || geteuid() == 0)
1292#endif /* HAVE_CYGWIN */ 1463#endif /* HAVE_CYGWIN */
@@ -1300,21 +1471,13 @@ do_setusercontext(struct passwd *pw)
1300# ifdef __bsdi__ 1471# ifdef __bsdi__
1301 setpgid(0, 0); 1472 setpgid(0, 0);
1302# endif 1473# endif
1303#ifdef GSSAPI
1304 if (options.gss_authentication) {
1305 temporarily_use_uid(pw);
1306 ssh_gssapi_storecreds();
1307 restore_uid();
1308 }
1309#endif
1310# ifdef USE_PAM 1474# ifdef USE_PAM
1311 if (options.use_pam) { 1475 if (options.use_pam) {
1312 do_pam_session();
1313 do_pam_setcred(use_privsep); 1476 do_pam_setcred(use_privsep);
1314 } 1477 }
1315# endif /* USE_PAM */ 1478# endif /* USE_PAM */
1316 if (setusercontext(lc, pw, pw->pw_uid, 1479 if (setusercontext(lc, pw, pw->pw_uid,
1317 (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { 1480 (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
1318 perror("unable to set user context"); 1481 perror("unable to set user context");
1319 exit(1); 1482 exit(1);
1320 } 1483 }
@@ -1337,13 +1500,6 @@ do_setusercontext(struct passwd *pw)
1337 exit(1); 1500 exit(1);
1338 } 1501 }
1339 endgrent(); 1502 endgrent();
1340#ifdef GSSAPI
1341 if (options.gss_authentication) {
1342 temporarily_use_uid(pw);
1343 ssh_gssapi_storecreds();
1344 restore_uid();
1345 }
1346#endif
1347# ifdef USE_PAM 1503# ifdef USE_PAM
1348 /* 1504 /*
1349 * PAM credentials may take the form of supplementary groups. 1505 * PAM credentials may take the form of supplementary groups.
@@ -1351,21 +1507,39 @@ do_setusercontext(struct passwd *pw)
1351 * Reestablish them here. 1507 * Reestablish them here.
1352 */ 1508 */
1353 if (options.use_pam) { 1509 if (options.use_pam) {
1354 do_pam_session();
1355 do_pam_setcred(use_privsep); 1510 do_pam_setcred(use_privsep);
1356 } 1511 }
1357# endif /* USE_PAM */ 1512# endif /* USE_PAM */
1358# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) 1513# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
1359 irix_setusercontext(pw); 1514 irix_setusercontext(pw);
1360# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 1515# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1361# ifdef _AIX 1516# ifdef _AIX
1362 aix_usrinfo(pw); 1517 aix_usrinfo(pw);
1363# endif /* _AIX */ 1518# endif /* _AIX */
1364#ifdef USE_LIBIAF 1519# ifdef USE_LIBIAF
1365 if (set_id(pw->pw_name) != 0) { 1520 if (set_id(pw->pw_name) != 0) {
1366 exit(1); 1521 exit(1);
1367 } 1522 }
1368#endif /* USE_LIBIAF */ 1523# endif /* USE_LIBIAF */
1524#endif
1525
1526 if (options.chroot_directory != NULL &&
1527 strcasecmp(options.chroot_directory, "none") != 0) {
1528 tmp = tilde_expand_filename(options.chroot_directory,
1529 pw->pw_uid);
1530 chroot_path = percent_expand(tmp, "h", pw->pw_dir,
1531 "u", pw->pw_name, (char *)NULL);
1532 safely_chroot(chroot_path, pw->pw_uid);
1533 free(tmp);
1534 free(chroot_path);
1535 }
1536
1537#ifdef HAVE_LOGIN_CAP
1538 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
1539 perror("unable to set user context (setuser)");
1540 exit(1);
1541 }
1542#else
1369 /* Permanently switch to the desired uid. */ 1543 /* Permanently switch to the desired uid. */
1370 permanently_set_uid(pw); 1544 permanently_set_uid(pw);
1371#endif 1545#endif
@@ -1464,14 +1638,16 @@ child_close_fds(void)
1464 * environment, closing extra file descriptors, setting the user and group 1638 * environment, closing extra file descriptors, setting the user and group
1465 * ids, and executing the command or shell. 1639 * ids, and executing the command or shell.
1466 */ 1640 */
1641#define ARGV_MAX 10
1467void 1642void
1468do_child(Session *s, const char *command) 1643do_child(Session *s, const char *command)
1469{ 1644{
1470 extern char **environ; 1645 extern char **environ;
1471 char **env; 1646 char **env;
1472 char *argv[10]; 1647 char *argv[ARGV_MAX];
1473 const char *shell, *shell0, *hostname = NULL; 1648 const char *shell, *shell0, *hostname = NULL;
1474 struct passwd *pw = s->pw; 1649 struct passwd *pw = s->pw;
1650 int r = 0;
1475 1651
1476 /* remove hostkey from the child's memory */ 1652 /* remove hostkey from the child's memory */
1477 destroy_sensitive_data(); 1653 destroy_sensitive_data();
@@ -1587,20 +1763,42 @@ do_child(Session *s, const char *command)
1587 1763
1588 /* Change current directory to the user's home directory. */ 1764 /* Change current directory to the user's home directory. */
1589 if (chdir(pw->pw_dir) < 0) { 1765 if (chdir(pw->pw_dir) < 0) {
1590 fprintf(stderr, "Could not chdir to home directory %s: %s\n", 1766 /* Suppress missing homedir warning for chroot case */
1591 pw->pw_dir, strerror(errno));
1592#ifdef HAVE_LOGIN_CAP 1767#ifdef HAVE_LOGIN_CAP
1593 if (login_getcapbool(lc, "requirehome", 0)) 1768 r = login_getcapbool(lc, "requirehome", 0);
1594 exit(1);
1595#endif 1769#endif
1770 if (r || options.chroot_directory == NULL)
1771 fprintf(stderr, "Could not chdir to home "
1772 "directory %s: %s\n", pw->pw_dir,
1773 strerror(errno));
1774 if (r)
1775 exit(1);
1596 } 1776 }
1597 1777
1778 closefrom(STDERR_FILENO + 1);
1779
1598 if (!options.use_login) 1780 if (!options.use_login)
1599 do_rc_files(s, shell); 1781 do_rc_files(s, shell);
1600 1782
1601 /* restore SIGPIPE for child */ 1783 /* restore SIGPIPE for child */
1602 signal(SIGPIPE, SIG_DFL); 1784 signal(SIGPIPE, SIG_DFL);
1603 1785
1786 if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
1787 extern int optind, optreset;
1788 int i;
1789 char *p, *args;
1790
1791 setproctitle("%s@internal-sftp-server", s->pw->pw_name);
1792 args = strdup(command ? command : "sftp-server");
1793 for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
1794 if (i < ARGV_MAX - 1)
1795 argv[i++] = p;
1796 argv[i] = NULL;
1797 optind = optreset = 1;
1798 __progname = argv[0];
1799 exit(sftp_server_main(i, argv, s->pw));
1800 }
1801
1604 if (options.use_login) { 1802 if (options.use_login) {
1605 launch_login(pw, hostname); 1803 launch_login(pw, hostname);
1606 /* NEVERREACHED */ 1804 /* NEVERREACHED */
@@ -1652,43 +1850,79 @@ do_child(Session *s, const char *command)
1652 exit(1); 1850 exit(1);
1653} 1851}
1654 1852
1853void
1854session_unused(int id)
1855{
1856 debug3("%s: session id %d unused", __func__, id);
1857 if (id >= options.max_sessions ||
1858 id >= sessions_nalloc) {
1859 fatal("%s: insane session id %d (max %d nalloc %d)",
1860 __func__, id, options.max_sessions, sessions_nalloc);
1861 }
1862 bzero(&sessions[id], sizeof(*sessions));
1863 sessions[id].self = id;
1864 sessions[id].used = 0;
1865 sessions[id].chanid = -1;
1866 sessions[id].ptyfd = -1;
1867 sessions[id].ttyfd = -1;
1868 sessions[id].ptymaster = -1;
1869 sessions[id].x11_chanids = NULL;
1870 sessions[id].next_unused = sessions_first_unused;
1871 sessions_first_unused = id;
1872}
1873
1655Session * 1874Session *
1656session_new(void) 1875session_new(void)
1657{ 1876{
1658 int i; 1877 Session *s, *tmp;
1659 static int did_init = 0; 1878
1660 if (!did_init) { 1879 if (sessions_first_unused == -1) {
1661 debug("session_new: init"); 1880 if (sessions_nalloc >= options.max_sessions)
1662 for (i = 0; i < MAX_SESSIONS; i++) { 1881 return NULL;
1663 sessions[i].used = 0; 1882 debug2("%s: allocate (allocated %d max %d)",
1883 __func__, sessions_nalloc, options.max_sessions);
1884 tmp = xrealloc(sessions, sessions_nalloc + 1,
1885 sizeof(*sessions));
1886 if (tmp == NULL) {
1887 error("%s: cannot allocate %d sessions",
1888 __func__, sessions_nalloc + 1);
1889 return NULL;
1664 } 1890 }
1665 did_init = 1; 1891 sessions = tmp;
1892 session_unused(sessions_nalloc++);
1666 } 1893 }
1667 for (i = 0; i < MAX_SESSIONS; i++) { 1894
1668 Session *s = &sessions[i]; 1895 if (sessions_first_unused >= sessions_nalloc ||
1669 if (! s->used) { 1896 sessions_first_unused < 0) {
1670 memset(s, 0, sizeof(*s)); 1897 fatal("%s: insane first_unused %d max %d nalloc %d",
1671 s->chanid = -1; 1898 __func__, sessions_first_unused, options.max_sessions,
1672 s->ptyfd = -1; 1899 sessions_nalloc);
1673 s->ttyfd = -1;
1674 s->used = 1;
1675 s->self = i;
1676 s->x11_chanids = NULL;
1677 debug("session_new: session %d", i);
1678 return s;
1679 }
1680 } 1900 }
1681 return NULL; 1901
1902 s = &sessions[sessions_first_unused];
1903 if (s->used) {
1904 fatal("%s: session %d already used",
1905 __func__, sessions_first_unused);
1906 }
1907 sessions_first_unused = s->next_unused;
1908 s->used = 1;
1909 s->next_unused = -1;
1910 debug("session_new: session %d", s->self);
1911
1912 return s;
1682} 1913}
1683 1914
1684static void 1915static void
1685session_dump(void) 1916session_dump(void)
1686{ 1917{
1687 int i; 1918 int i;
1688 for (i = 0; i < MAX_SESSIONS; i++) { 1919 for (i = 0; i < sessions_nalloc; i++) {
1689 Session *s = &sessions[i]; 1920 Session *s = &sessions[i];
1690 debug("dump: used %d session %d %p channel %d pid %ld", 1921
1922 debug("dump: used %d next_unused %d session %d %p "
1923 "channel %d pid %ld",
1691 s->used, 1924 s->used,
1925 s->next_unused,
1692 s->self, 1926 s->self,
1693 s, 1927 s,
1694 s->chanid, 1928 s->chanid,
@@ -1718,7 +1952,7 @@ Session *
1718session_by_tty(char *tty) 1952session_by_tty(char *tty)
1719{ 1953{
1720 int i; 1954 int i;
1721 for (i = 0; i < MAX_SESSIONS; i++) { 1955 for (i = 0; i < sessions_nalloc; i++) {
1722 Session *s = &sessions[i]; 1956 Session *s = &sessions[i];
1723 if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { 1957 if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
1724 debug("session_by_tty: session %d tty %s", i, tty); 1958 debug("session_by_tty: session %d tty %s", i, tty);
@@ -1734,10 +1968,11 @@ static Session *
1734session_by_channel(int id) 1968session_by_channel(int id)
1735{ 1969{
1736 int i; 1970 int i;
1737 for (i = 0; i < MAX_SESSIONS; i++) { 1971 for (i = 0; i < sessions_nalloc; i++) {
1738 Session *s = &sessions[i]; 1972 Session *s = &sessions[i];
1739 if (s->used && s->chanid == id) { 1973 if (s->used && s->chanid == id) {
1740 debug("session_by_channel: session %d channel %d", i, id); 1974 debug("session_by_channel: session %d channel %d",
1975 i, id);
1741 return s; 1976 return s;
1742 } 1977 }
1743 } 1978 }
@@ -1751,7 +1986,7 @@ session_by_x11_channel(int id)
1751{ 1986{
1752 int i, j; 1987 int i, j;
1753 1988
1754 for (i = 0; i < MAX_SESSIONS; i++) { 1989 for (i = 0; i < sessions_nalloc; i++) {
1755 Session *s = &sessions[i]; 1990 Session *s = &sessions[i];
1756 1991
1757 if (s->x11_chanids == NULL || !s->used) 1992 if (s->x11_chanids == NULL || !s->used)
@@ -1774,7 +2009,7 @@ session_by_pid(pid_t pid)
1774{ 2009{
1775 int i; 2010 int i;
1776 debug("session_by_pid: pid %ld", (long)pid); 2011 debug("session_by_pid: pid %ld", (long)pid);
1777 for (i = 0; i < MAX_SESSIONS; i++) { 2012 for (i = 0; i < sessions_nalloc; i++) {
1778 Session *s = &sessions[i]; 2013 Session *s = &sessions[i];
1779 if (s->used && s->pid == pid) 2014 if (s->used && s->pid == pid)
1780 return s; 2015 return s;
@@ -1830,7 +2065,8 @@ session_pty_req(Session *s)
1830 2065
1831 /* Allocate a pty and open it. */ 2066 /* Allocate a pty and open it. */
1832 debug("Allocating pty."); 2067 debug("Allocating pty.");
1833 if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { 2068 if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
2069 sizeof(s->tty)))) {
1834 if (s->term) 2070 if (s->term)
1835 xfree(s->term); 2071 xfree(s->term);
1836 s->term = NULL; 2072 s->term = NULL;
@@ -1873,15 +2109,17 @@ session_subsystem_req(Session *s)
1873 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 2109 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
1874 prog = options.subsystem_command[i]; 2110 prog = options.subsystem_command[i];
1875 cmd = options.subsystem_args[i]; 2111 cmd = options.subsystem_args[i];
1876 if (stat(prog, &st) < 0) { 2112 if (!strcmp(INTERNAL_SFTP_NAME, prog)) {
2113 s->is_subsystem = SUBSYSTEM_INT_SFTP;
2114 } else if (stat(prog, &st) < 0) {
1877 error("subsystem: cannot stat %s: %s", prog, 2115 error("subsystem: cannot stat %s: %s", prog,
1878 strerror(errno)); 2116 strerror(errno));
1879 break; 2117 break;
2118 } else {
2119 s->is_subsystem = SUBSYSTEM_EXT;
1880 } 2120 }
1881 debug("subsystem: exec() %s", cmd); 2121 debug("subsystem: exec() %s", cmd);
1882 s->is_subsystem = 1; 2122 success = do_exec(s, cmd) == 0;
1883 do_exec(s, cmd);
1884 success = 1;
1885 break; 2123 break;
1886 } 2124 }
1887 } 2125 }
@@ -1924,19 +2162,19 @@ static int
1924session_shell_req(Session *s) 2162session_shell_req(Session *s)
1925{ 2163{
1926 packet_check_eom(); 2164 packet_check_eom();
1927 do_exec(s, NULL); 2165 return do_exec(s, NULL) == 0;
1928 return 1;
1929} 2166}
1930 2167
1931static int 2168static int
1932session_exec_req(Session *s) 2169session_exec_req(Session *s)
1933{ 2170{
1934 u_int len; 2171 u_int len, success;
2172
1935 char *command = packet_get_string(&len); 2173 char *command = packet_get_string(&len);
1936 packet_check_eom(); 2174 packet_check_eom();
1937 do_exec(s, command); 2175 success = do_exec(s, command) == 0;
1938 xfree(command); 2176 xfree(command);
1939 return 1; 2177 return success;
1940} 2178}
1941 2179
1942static int 2180static int
@@ -1946,8 +2184,7 @@ session_break_req(Session *s)
1946 packet_get_int(); /* ignored */ 2184 packet_get_int(); /* ignored */
1947 packet_check_eom(); 2185 packet_check_eom();
1948 2186
1949 if (s->ttyfd == -1 || 2187 if (s->ttyfd == -1 || tcsendbreak(s->ttyfd, 0) < 0)
1950 tcsendbreak(s->ttyfd, 0) < 0)
1951 return 0; 2188 return 0;
1952 return 1; 2189 return 1;
1953} 2190}
@@ -1992,7 +2229,7 @@ session_auth_agent_req(Session *s)
1992{ 2229{
1993 static int called = 0; 2230 static int called = 0;
1994 packet_check_eom(); 2231 packet_check_eom();
1995 if (no_agent_forwarding_flag) { 2232 if (no_agent_forwarding_flag || !options.allow_agent_forwarding) {
1996 debug("session_auth_agent_req: no_agent_forwarding_flag"); 2233 debug("session_auth_agent_req: no_agent_forwarding_flag");
1997 return 0; 2234 return 0;
1998 } 2235 }
@@ -2048,7 +2285,7 @@ session_input_channel_req(Channel *c, const char *rtype)
2048} 2285}
2049 2286
2050void 2287void
2051session_set_fds(Session *s, int fdin, int fdout, int fderr) 2288session_set_fds(Session *s, int fdin, int fdout, int fderr, int is_tty)
2052{ 2289{
2053 if (!compat20) 2290 if (!compat20)
2054 fatal("session_set_fds: called for proto != 2.0"); 2291 fatal("session_set_fds: called for proto != 2.0");
@@ -2061,8 +2298,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
2061 channel_set_fds(s->chanid, 2298 channel_set_fds(s->chanid,
2062 fdout, fdin, fderr, 2299 fdout, fdin, fderr,
2063 fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 2300 fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2064 1, 2301 1, is_tty, CHAN_SES_WINDOW_DEFAULT);
2065 CHAN_SES_WINDOW_DEFAULT);
2066} 2302}
2067 2303
2068/* 2304/*
@@ -2094,8 +2330,9 @@ session_pty_cleanup2(Session *s)
2094 * the pty cleanup, so that another process doesn't get this pty 2330 * the pty cleanup, so that another process doesn't get this pty
2095 * while we're still cleaning up. 2331 * while we're still cleaning up.
2096 */ 2332 */
2097 if (close(s->ptymaster) < 0) 2333 if (s->ptymaster != -1 && close(s->ptymaster) < 0)
2098 error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); 2334 error("close(s->ptymaster/%d): %s",
2335 s->ptymaster, strerror(errno));
2099 2336
2100 /* unlink pty from session */ 2337 /* unlink pty from session */
2101 s->ttyfd = -1; 2338 s->ttyfd = -1;
@@ -2203,7 +2440,7 @@ session_exit_message(Session *s, int status)
2203 channel_request_start(s->chanid, "exit-signal", 0); 2440 channel_request_start(s->chanid, "exit-signal", 0);
2204 packet_put_cstring(sig2name(WTERMSIG(status))); 2441 packet_put_cstring(sig2name(WTERMSIG(status)));
2205#ifdef WCOREDUMP 2442#ifdef WCOREDUMP
2206 packet_put_char(WCOREDUMP(status)); 2443 packet_put_char(WCOREDUMP(status)? 1 : 0);
2207#else /* WCOREDUMP */ 2444#else /* WCOREDUMP */
2208 packet_put_char(0); 2445 packet_put_char(0);
2209#endif /* WCOREDUMP */ 2446#endif /* WCOREDUMP */
@@ -2255,7 +2492,6 @@ session_close(Session *s)
2255 xfree(s->auth_data); 2492 xfree(s->auth_data);
2256 if (s->auth_proto) 2493 if (s->auth_proto)
2257 xfree(s->auth_proto); 2494 xfree(s->auth_proto);
2258 s->used = 0;
2259 if (s->env != NULL) { 2495 if (s->env != NULL) {
2260 for (i = 0; i < s->num_env; i++) { 2496 for (i = 0; i < s->num_env; i++) {
2261 xfree(s->env[i].name); 2497 xfree(s->env[i].name);
@@ -2264,6 +2500,7 @@ session_close(Session *s)
2264 xfree(s->env); 2500 xfree(s->env);
2265 } 2501 }
2266 session_proctitle(s); 2502 session_proctitle(s);
2503 session_unused(s->self);
2267} 2504}
2268 2505
2269void 2506void
@@ -2327,7 +2564,7 @@ void
2327session_destroy_all(void (*closefunc)(Session *)) 2564session_destroy_all(void (*closefunc)(Session *))
2328{ 2565{
2329 int i; 2566 int i;
2330 for (i = 0; i < MAX_SESSIONS; i++) { 2567 for (i = 0; i < sessions_nalloc; i++) {
2331 Session *s = &sessions[i]; 2568 Session *s = &sessions[i];
2332 if (s->used) { 2569 if (s->used) {
2333 if (closefunc != NULL) 2570 if (closefunc != NULL)
@@ -2346,7 +2583,7 @@ session_tty_list(void)
2346 char *cp; 2583 char *cp;
2347 2584
2348 buf[0] = '\0'; 2585 buf[0] = '\0';
2349 for (i = 0; i < MAX_SESSIONS; i++) { 2586 for (i = 0; i < sessions_nalloc; i++) {
2350 Session *s = &sessions[i]; 2587 Session *s = &sessions[i];
2351 if (s->used && s->ttyfd != -1) { 2588 if (s->used && s->ttyfd != -1) {
2352 2589
diff --git a/session.h b/session.h
index ee9338e4f..cbb8e3a32 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.h,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: session.h,v 1.30 2008/05/08 12:21:16 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -31,6 +31,7 @@ typedef struct Session Session;
31struct Session { 31struct Session {
32 int used; 32 int used;
33 int self; 33 int self;
34 int next_unused;
34 struct passwd *pw; 35 struct passwd *pw;
35 Authctxt *authctxt; 36 Authctxt *authctxt;
36 pid_t pid; 37 pid_t pid;
@@ -65,6 +66,7 @@ void do_authenticated(Authctxt *);
65void do_cleanup(Authctxt *); 66void do_cleanup(Authctxt *);
66 67
67int session_open(Authctxt *, int); 68int session_open(Authctxt *, int);
69void session_unused(int);
68int session_input_channel_req(Channel *, const char *); 70int session_input_channel_req(Channel *, const char *);
69void session_close_by_pid(pid_t, int); 71void session_close_by_pid(pid_t, int);
70void session_close_by_channel(int, void *); 72void session_close_by_channel(int, void *);
diff --git a/sftp-client.c b/sftp-client.c
index 2746f3245..5e39aa7d2 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-client.c,v 1.76 2007/01/22 11:32:50 djm Exp $ */ 1/* $OpenBSD: sftp-client.c,v 1.86 2008/06/26 06:10:09 djm 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 *
@@ -24,6 +24,9 @@
24 24
25#include <sys/types.h> 25#include <sys/types.h>
26#include <sys/param.h> 26#include <sys/param.h>
27#ifdef HAVE_SYS_STATVFS_H
28#include <sys/statvfs.h>
29#endif
27#include "openbsd-compat/sys-queue.h" 30#include "openbsd-compat/sys-queue.h"
28#ifdef HAVE_SYS_STAT_H 31#ifdef HAVE_SYS_STAT_H
29# include <sys/stat.h> 32# include <sys/stat.h>
@@ -65,6 +68,10 @@ struct sftp_conn {
65 u_int num_requests; 68 u_int num_requests;
66 u_int version; 69 u_int version;
67 u_int msg_id; 70 u_int msg_id;
71#define SFTP_EXT_POSIX_RENAME 0x00000001
72#define SFTP_EXT_STATVFS 0x00000002
73#define SFTP_EXT_FSTATVFS 0x00000004
74 u_int exts;
68}; 75};
69 76
70static void 77static void
@@ -236,10 +243,61 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
236 return(a); 243 return(a);
237} 244}
238 245
246static int
247get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id,
248 int quiet)
249{
250 Buffer msg;
251 u_int type, id, flag;
252
253 buffer_init(&msg);
254 get_msg(fd, &msg);
255
256 type = buffer_get_char(&msg);
257 id = buffer_get_int(&msg);
258
259 debug3("Received statvfs reply T:%u I:%u", type, id);
260 if (id != expected_id)
261 fatal("ID mismatch (%u != %u)", id, expected_id);
262 if (type == SSH2_FXP_STATUS) {
263 int status = buffer_get_int(&msg);
264
265 if (quiet)
266 debug("Couldn't statvfs: %s", fx2txt(status));
267 else
268 error("Couldn't statvfs: %s", fx2txt(status));
269 buffer_free(&msg);
270 return -1;
271 } else if (type != SSH2_FXP_EXTENDED_REPLY) {
272 fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
273 SSH2_FXP_EXTENDED_REPLY, type);
274 }
275
276 bzero(st, sizeof(*st));
277 st->f_bsize = buffer_get_int64(&msg);
278 st->f_frsize = buffer_get_int64(&msg);
279 st->f_blocks = buffer_get_int64(&msg);
280 st->f_bfree = buffer_get_int64(&msg);
281 st->f_bavail = buffer_get_int64(&msg);
282 st->f_files = buffer_get_int64(&msg);
283 st->f_ffree = buffer_get_int64(&msg);
284 st->f_favail = buffer_get_int64(&msg);
285 st->f_fsid = buffer_get_int64(&msg);
286 flag = buffer_get_int64(&msg);
287 st->f_namemax = buffer_get_int64(&msg);
288
289 st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0;
290 st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0;
291
292 buffer_free(&msg);
293
294 return 0;
295}
296
239struct sftp_conn * 297struct sftp_conn *
240do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) 298do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
241{ 299{
242 u_int type; 300 u_int type, exts = 0;
243 int version; 301 int version;
244 Buffer msg; 302 Buffer msg;
245 struct sftp_conn *ret; 303 struct sftp_conn *ret;
@@ -268,8 +326,27 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
268 while (buffer_len(&msg) > 0) { 326 while (buffer_len(&msg) > 0) {
269 char *name = buffer_get_string(&msg, NULL); 327 char *name = buffer_get_string(&msg, NULL);
270 char *value = buffer_get_string(&msg, NULL); 328 char *value = buffer_get_string(&msg, NULL);
271 329 int known = 0;
272 debug2("Init extension: \"%s\"", name); 330
331 if (strcmp(name, "posix-rename@openssh.com") == 0 &&
332 strcmp(value, "1") == 0) {
333 exts |= SFTP_EXT_POSIX_RENAME;
334 known = 1;
335 } else if (strcmp(name, "statvfs@openssh.com") == 0 &&
336 strcmp(value, "2") == 0) {
337 exts |= SFTP_EXT_STATVFS;
338 known = 1;
339 } if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
340 strcmp(value, "2") == 0) {
341 exts |= SFTP_EXT_FSTATVFS;
342 known = 1;
343 }
344 if (known) {
345 debug2("Server supports extension \"%s\" revision %s",
346 name, value);
347 } else {
348 debug2("Unrecognised server extension \"%s\"", name);
349 }
273 xfree(name); 350 xfree(name);
274 xfree(value); 351 xfree(value);
275 } 352 }
@@ -283,6 +360,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
283 ret->num_requests = num_requests; 360 ret->num_requests = num_requests;
284 ret->version = version; 361 ret->version = version;
285 ret->msg_id = 1; 362 ret->msg_id = 1;
363 ret->exts = exts;
286 364
287 /* Some filexfer v.0 servers don't support large packets */ 365 /* Some filexfer v.0 servers don't support large packets */
288 if (version == 0) 366 if (version == 0)
@@ -534,6 +612,7 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet)
534 return(get_decode_stat(conn->fd_in, id, quiet)); 612 return(get_decode_stat(conn->fd_in, id, quiet));
535} 613}
536 614
615#ifdef notyet
537Attrib * 616Attrib *
538do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) 617do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
539{ 618{
@@ -545,6 +624,7 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
545 624
546 return(get_decode_stat(conn->fd_in, id, quiet)); 625 return(get_decode_stat(conn->fd_in, id, quiet));
547} 626}
627#endif
548 628
549int 629int
550do_setstat(struct sftp_conn *conn, char *path, Attrib *a) 630do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
@@ -637,13 +717,20 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
637 717
638 /* Send rename request */ 718 /* Send rename request */
639 id = conn->msg_id++; 719 id = conn->msg_id++;
640 buffer_put_char(&msg, SSH2_FXP_RENAME); 720 if ((conn->exts & SFTP_EXT_POSIX_RENAME)) {
641 buffer_put_int(&msg, id); 721 buffer_put_char(&msg, SSH2_FXP_EXTENDED);
722 buffer_put_int(&msg, id);
723 buffer_put_cstring(&msg, "posix-rename@openssh.com");
724 } else {
725 buffer_put_char(&msg, SSH2_FXP_RENAME);
726 buffer_put_int(&msg, id);
727 }
642 buffer_put_cstring(&msg, oldpath); 728 buffer_put_cstring(&msg, oldpath);
643 buffer_put_cstring(&msg, newpath); 729 buffer_put_cstring(&msg, newpath);
644 send_msg(conn->fd_out, &msg); 730 send_msg(conn->fd_out, &msg);
645 debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath, 731 debug3("Sent message %s \"%s\" -> \"%s\"",
646 newpath); 732 (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" :
733 "SSH2_FXP_RENAME", oldpath, newpath);
647 buffer_free(&msg); 734 buffer_free(&msg);
648 735
649 status = get_status(conn->fd_in, id); 736 status = get_status(conn->fd_in, id);
@@ -686,6 +773,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
686 return(status); 773 return(status);
687} 774}
688 775
776#ifdef notyet
689char * 777char *
690do_readlink(struct sftp_conn *conn, char *path) 778do_readlink(struct sftp_conn *conn, char *path)
691{ 779{
@@ -732,6 +820,61 @@ do_readlink(struct sftp_conn *conn, char *path)
732 820
733 return(filename); 821 return(filename);
734} 822}
823#endif
824
825int
826do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
827 int quiet)
828{
829 Buffer msg;
830 u_int id;
831
832 if ((conn->exts & SFTP_EXT_STATVFS) == 0) {
833 error("Server does not support statvfs@openssh.com extension");
834 return -1;
835 }
836
837 id = conn->msg_id++;
838
839 buffer_init(&msg);
840 buffer_clear(&msg);
841 buffer_put_char(&msg, SSH2_FXP_EXTENDED);
842 buffer_put_int(&msg, id);
843 buffer_put_cstring(&msg, "statvfs@openssh.com");
844 buffer_put_cstring(&msg, path);
845 send_msg(conn->fd_out, &msg);
846 buffer_free(&msg);
847
848 return get_decode_statvfs(conn->fd_in, st, id, quiet);
849}
850
851#ifdef notyet
852int
853do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len,
854 struct sftp_statvfs *st, int quiet)
855{
856 Buffer msg;
857 u_int id;
858
859 if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) {
860 error("Server does not support fstatvfs@openssh.com extension");
861 return -1;
862 }
863
864 id = conn->msg_id++;
865
866 buffer_init(&msg);
867 buffer_clear(&msg);
868 buffer_put_char(&msg, SSH2_FXP_EXTENDED);
869 buffer_put_int(&msg, id);
870 buffer_put_cstring(&msg, "fstatvfs@openssh.com");
871 buffer_put_string(&msg, handle, handle_len);
872 send_msg(conn->fd_out, &msg);
873 buffer_free(&msg);
874
875 return get_decode_statvfs(conn->fd_in, st, id, quiet);
876}
877#endif
735 878
736static void 879static void
737send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, 880send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
@@ -777,7 +920,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
777 if (a == NULL) 920 if (a == NULL)
778 return(-1); 921 return(-1);
779 922
780 /* XXX: should we preserve set[ug]id? */ 923 /* Do not preserve set[ug]id here, as we do not preserve ownership */
781 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 924 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
782 mode = a->perm & 0777; 925 mode = a->perm & 0777;
783 else 926 else
@@ -819,6 +962,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
819 if (local_fd == -1) { 962 if (local_fd == -1) {
820 error("Couldn't open local file \"%s\" for writing: %s", 963 error("Couldn't open local file \"%s\" for writing: %s",
821 local_path, strerror(errno)); 964 local_path, strerror(errno));
965 do_close(conn, handle, handle_len);
822 buffer_free(&msg); 966 buffer_free(&msg);
823 xfree(handle); 967 xfree(handle);
824 return(-1); 968 return(-1);
@@ -992,9 +1136,10 @@ int
992do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, 1136do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
993 int pflag) 1137 int pflag)
994{ 1138{
995 int local_fd, status; 1139 int local_fd;
1140 int status = SSH2_FX_OK;
996 u_int handle_len, id, type; 1141 u_int handle_len, id, type;
997 u_int64_t offset; 1142 off_t offset;
998 char *handle, *data; 1143 char *handle, *data;
999 Buffer msg; 1144 Buffer msg;
1000 struct stat sb; 1145 struct stat sb;
@@ -1004,7 +1149,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1004 struct outstanding_ack { 1149 struct outstanding_ack {
1005 u_int id; 1150 u_int id;
1006 u_int len; 1151 u_int len;
1007 u_int64_t offset; 1152 off_t offset;
1008 TAILQ_ENTRY(outstanding_ack) tq; 1153 TAILQ_ENTRY(outstanding_ack) tq;
1009 }; 1154 };
1010 TAILQ_HEAD(ackhead, outstanding_ack) acks; 1155 TAILQ_HEAD(ackhead, outstanding_ack) acks;
@@ -1054,7 +1199,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1054 if (handle == NULL) { 1199 if (handle == NULL) {
1055 close(local_fd); 1200 close(local_fd);
1056 buffer_free(&msg); 1201 buffer_free(&msg);
1057 return(-1); 1202 return -1;
1058 } 1203 }
1059 1204
1060 startid = ackid = id + 1; 1205 startid = ackid = id + 1;
@@ -1074,11 +1219,12 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1074 * Simulate an EOF on interrupt, allowing ACKs from the 1219 * Simulate an EOF on interrupt, allowing ACKs from the
1075 * server to drain. 1220 * server to drain.
1076 */ 1221 */
1077 if (interrupted) 1222 if (interrupted || status != SSH2_FX_OK)
1078 len = 0; 1223 len = 0;
1079 else do 1224 else do
1080 len = read(local_fd, data, conn->transfer_buflen); 1225 len = read(local_fd, data, conn->transfer_buflen);
1081 while ((len == -1) && (errno == EINTR || errno == EAGAIN)); 1226 while ((len == -1) &&
1227 (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
1082 1228
1083 if (len == -1) 1229 if (len == -1)
1084 fatal("Couldn't read from \"%s\": %s", local_path, 1230 fatal("Couldn't read from \"%s\": %s", local_path,
@@ -1130,46 +1276,40 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1130 if (ack == NULL) 1276 if (ack == NULL)
1131 fatal("Can't find request for ID %u", r_id); 1277 fatal("Can't find request for ID %u", r_id);
1132 TAILQ_REMOVE(&acks, ack, tq); 1278 TAILQ_REMOVE(&acks, ack, tq);
1133 1279 debug3("In write loop, ack for %u %u bytes at %lld",
1134 if (status != SSH2_FX_OK) { 1280 ack->id, ack->len, (long long)ack->offset);
1135 error("Couldn't write to remote file \"%s\": %s",
1136 remote_path, fx2txt(status));
1137 if (showprogress)
1138 stop_progress_meter();
1139 do_close(conn, handle, handle_len);
1140 close(local_fd);
1141 xfree(data);
1142 xfree(ack);
1143 status = -1;
1144 goto done;
1145 }
1146 debug3("In write loop, ack for %u %u bytes at %llu",
1147 ack->id, ack->len, (unsigned long long)ack->offset);
1148 ++ackid; 1281 ++ackid;
1149 xfree(ack); 1282 xfree(ack);
1150 } 1283 }
1151 offset += len; 1284 offset += len;
1285 if (offset < 0)
1286 fatal("%s: offset < 0", __func__);
1152 } 1287 }
1288 buffer_free(&msg);
1289
1153 if (showprogress) 1290 if (showprogress)
1154 stop_progress_meter(); 1291 stop_progress_meter();
1155 xfree(data); 1292 xfree(data);
1156 1293
1294 if (status != SSH2_FX_OK) {
1295 error("Couldn't write to remote file \"%s\": %s",
1296 remote_path, fx2txt(status));
1297 status = -1;
1298 }
1299
1157 if (close(local_fd) == -1) { 1300 if (close(local_fd) == -1) {
1158 error("Couldn't close local file \"%s\": %s", local_path, 1301 error("Couldn't close local file \"%s\": %s", local_path,
1159 strerror(errno)); 1302 strerror(errno));
1160 do_close(conn, handle, handle_len);
1161 status = -1; 1303 status = -1;
1162 goto done;
1163 } 1304 }
1164 1305
1165 /* Override umask and utimes if asked */ 1306 /* Override umask and utimes if asked */
1166 if (pflag) 1307 if (pflag)
1167 do_fsetstat(conn, handle, handle_len, &a); 1308 do_fsetstat(conn, handle, handle_len, &a);
1168 1309
1169 status = do_close(conn, handle, handle_len); 1310 if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
1170 1311 status = -1;
1171done:
1172 xfree(handle); 1312 xfree(handle);
1173 buffer_free(&msg); 1313
1174 return(status); 1314 return status;
1175} 1315}
diff --git a/sftp-client.h b/sftp-client.h
index c8a41f377..edb46790f 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-client.h,v 1.14 2005/04/26 12:59:02 jmc Exp $ */ 1/* $OpenBSD: sftp-client.h,v 1.17 2008/06/08 20:15:29 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 4 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@@ -30,6 +30,24 @@ struct SFTP_DIRENT {
30}; 30};
31 31
32/* 32/*
33 * Used for statvfs responses on the wire from the server, because the
34 * server's native format may be larger than the client's.
35 */
36struct sftp_statvfs {
37 u_int64_t f_bsize;
38 u_int64_t f_frsize;
39 u_int64_t f_blocks;
40 u_int64_t f_bfree;
41 u_int64_t f_bavail;
42 u_int64_t f_files;
43 u_int64_t f_ffree;
44 u_int64_t f_favail;
45 u_int64_t f_fsid;
46 u_int64_t f_flag;
47 u_int64_t f_namemax;
48};
49
50/*
33 * Initialise a SSH filexfer connection. Returns NULL on error or 51 * Initialise a SSH filexfer connection. Returns NULL on error or
34 * a pointer to a initialized sftp_conn struct on success. 52 * a pointer to a initialized sftp_conn struct on success.
35 */ 53 */
@@ -61,9 +79,6 @@ Attrib *do_stat(struct sftp_conn *, char *, int);
61/* Get file attributes of 'path' (does not follow symlinks) */ 79/* Get file attributes of 'path' (does not follow symlinks) */
62Attrib *do_lstat(struct sftp_conn *, char *, int); 80Attrib *do_lstat(struct sftp_conn *, char *, int);
63 81
64/* Get file attributes of open file 'handle' */
65Attrib *do_fstat(struct sftp_conn *, char *, u_int, int);
66
67/* Set file attributes of 'path' */ 82/* Set file attributes of 'path' */
68int do_setstat(struct sftp_conn *, char *, Attrib *); 83int do_setstat(struct sftp_conn *, char *, Attrib *);
69 84
@@ -73,15 +88,15 @@ int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *);
73/* Canonicalise 'path' - caller must free result */ 88/* Canonicalise 'path' - caller must free result */
74char *do_realpath(struct sftp_conn *, char *); 89char *do_realpath(struct sftp_conn *, char *);
75 90
91/* Get statistics for filesystem hosting file at "path" */
92int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
93
76/* Rename 'oldpath' to 'newpath' */ 94/* Rename 'oldpath' to 'newpath' */
77int do_rename(struct sftp_conn *, char *, char *); 95int do_rename(struct sftp_conn *, char *, char *);
78 96
79/* Rename 'oldpath' to 'newpath' */ 97/* Rename 'oldpath' to 'newpath' */
80int do_symlink(struct sftp_conn *, char *, char *); 98int do_symlink(struct sftp_conn *, char *, char *);
81 99
82/* Return target of symlink 'path' - caller must free result */
83char *do_readlink(struct sftp_conn *, char *);
84
85/* XXX: add callbacks to do_download/do_upload so we can do progress meter */ 100/* XXX: add callbacks to do_download/do_upload so we can do progress meter */
86 101
87/* 102/*
diff --git a/sftp-server-main.c b/sftp-server-main.c
new file mode 100644
index 000000000..2b14569e4
--- /dev/null
+++ b/sftp-server-main.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: sftp-server-main.c,v 1.3 2008/03/26 23:44:41 djm Exp $ */
2/*
3 * Copyright (c) 2008 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 <pwd.h>
22#include <stdarg.h>
23#include <stdio.h>
24#include <unistd.h>
25
26#include "log.h"
27#include "sftp.h"
28#include "misc.h"
29
30void
31cleanup_exit(int i)
32{
33 sftp_server_cleanup_exit(i);
34}
35
36int
37main(int argc, char **argv)
38{
39 struct passwd *user_pw;
40
41 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
42 sanitise_stdfd();
43
44 if ((user_pw = getpwuid(getuid())) == NULL) {
45 fprintf(stderr, "No user found for uid %lu", (u_long)getuid());
46 return 1;
47 }
48
49 return (sftp_server_main(argc, argv, user_pw));
50}
diff --git a/sftp-server.0 b/sftp-server.0
index 0837fff9b..941e99e14 100644
--- a/sftp-server.0
+++ b/sftp-server.0
@@ -31,6 +31,10 @@ DESCRIPTION
31 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of 31 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of
32 debugging output. The default is ERROR. 32 debugging output. The default is ERROR.
33 33
34 For logging to work, sftp-server must be able to access /dev/log. Use of
35 sftp-server in a chroot configuation therefore requires that syslogd(8)
36 establish a logging socket inside the chroot directory.
37
34SEE ALSO 38SEE ALSO
35 sftp(1), ssh(1), sshd_config(5), sshd(8) 39 sftp(1), ssh(1), sshd_config(5), sshd(8)
36 40
@@ -43,4 +47,4 @@ HISTORY
43AUTHORS 47AUTHORS
44 Markus Friedl <markus@openbsd.org> 48 Markus Friedl <markus@openbsd.org>
45 49
46OpenBSD 4.2 June 5, 2007 1 50OpenBSD 4.4 July 18, 2008 1
diff --git a/sftp-server.8 b/sftp-server.8
index 7452eca27..74c1e4bc5 100644
--- a/sftp-server.8
+++ b/sftp-server.8
@@ -1,4 +1,4 @@
1.\" $OpenBSD: sftp-server.8,v 1.12 2007/05/31 19:20:16 jmc Exp $ 1.\" $OpenBSD: sftp-server.8,v 1.14 2008/07/18 22:51:01 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 2000 Markus Friedl. All rights reserved. 3.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
4.\" 4.\"
@@ -22,7 +22,7 @@
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\" 24.\"
25.Dd $Mdocdate: June 5 2007 $ 25.Dd $Mdocdate: July 18 2008 $
26.Dt SFTP-SERVER 8 26.Dt SFTP-SERVER 8
27.Os 27.Os
28.Sh NAME 28.Sh NAME
@@ -72,6 +72,16 @@ DEBUG and DEBUG1 are equivalent.
72DEBUG2 and DEBUG3 each specify higher levels of debugging output. 72DEBUG2 and DEBUG3 each specify higher levels of debugging output.
73The default is ERROR. 73The default is ERROR.
74.El 74.El
75.Pp
76For logging to work,
77.Nm
78must be able to access
79.Pa /dev/log .
80Use of
81.Nm
82in a chroot configuation therefore requires that
83.Xr syslogd 8
84establish a logging socket inside the chroot directory.
75.Sh SEE ALSO 85.Sh SEE ALSO
76.Xr sftp 1 , 86.Xr sftp 1 ,
77.Xr ssh 1 , 87.Xr ssh 1 ,
diff --git a/sftp-server.c b/sftp-server.c
index 76edebc5a..24c4ff717 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-server.c,v 1.73 2007/05/17 07:55:29 djm Exp $ */ 1/* $OpenBSD: sftp-server.c,v 1.84 2008/06/26 06:10:09 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
4 * 4 *
@@ -23,6 +23,12 @@
23#ifdef HAVE_SYS_TIME_H 23#ifdef HAVE_SYS_TIME_H
24# include <sys/time.h> 24# include <sys/time.h>
25#endif 25#endif
26#ifdef HAVE_SYS_MOUNT_H
27#include <sys/mount.h>
28#endif
29#ifdef HAVE_SYS_STATVFS_H
30#include <sys/statvfs.h>
31#endif
26 32
27#include <dirent.h> 33#include <dirent.h>
28#include <errno.h> 34#include <errno.h>
@@ -98,6 +104,9 @@ errno_to_portable(int unixerrno)
98 case EINVAL: 104 case EINVAL:
99 ret = SSH2_FX_BAD_MESSAGE; 105 ret = SSH2_FX_BAD_MESSAGE;
100 break; 106 break;
107 case ENOSYS:
108 ret = SSH2_FX_OP_UNSUPPORTED;
109 break;
101 default: 110 default:
102 ret = SSH2_FX_FAILURE; 111 ret = SSH2_FX_FAILURE;
103 break; 112 break;
@@ -169,6 +178,7 @@ struct Handle {
169 int fd; 178 int fd;
170 char *name; 179 char *name;
171 u_int64_t bytes_read, bytes_write; 180 u_int64_t bytes_read, bytes_write;
181 int next_unused;
172}; 182};
173 183
174enum { 184enum {
@@ -177,40 +187,46 @@ enum {
177 HANDLE_FILE 187 HANDLE_FILE
178}; 188};
179 189
180Handle handles[100]; 190Handle *handles = NULL;
191u_int num_handles = 0;
192int first_unused_handle = -1;
181 193
182static void 194static void handle_unused(int i)
183handle_init(void)
184{ 195{
185 u_int i; 196 handles[i].use = HANDLE_UNUSED;
186 197 handles[i].next_unused = first_unused_handle;
187 for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) 198 first_unused_handle = i;
188 handles[i].use = HANDLE_UNUSED;
189} 199}
190 200
191static int 201static int
192handle_new(int use, const char *name, int fd, DIR *dirp) 202handle_new(int use, const char *name, int fd, DIR *dirp)
193{ 203{
194 u_int i; 204 int i;
195 205
196 for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) { 206 if (first_unused_handle == -1) {
197 if (handles[i].use == HANDLE_UNUSED) { 207 if (num_handles + 1 <= num_handles)
198 handles[i].use = use; 208 return -1;
199 handles[i].dirp = dirp; 209 num_handles++;
200 handles[i].fd = fd; 210 handles = xrealloc(handles, num_handles, sizeof(Handle));
201 handles[i].name = xstrdup(name); 211 handle_unused(num_handles - 1);
202 handles[i].bytes_read = handles[i].bytes_write = 0;
203 return i;
204 }
205 } 212 }
206 return -1; 213
214 i = first_unused_handle;
215 first_unused_handle = handles[i].next_unused;
216
217 handles[i].use = use;
218 handles[i].dirp = dirp;
219 handles[i].fd = fd;
220 handles[i].name = xstrdup(name);
221 handles[i].bytes_read = handles[i].bytes_write = 0;
222
223 return i;
207} 224}
208 225
209static int 226static int
210handle_is_ok(int i, int type) 227handle_is_ok(int i, int type)
211{ 228{
212 return i >= 0 && (u_int)i < sizeof(handles)/sizeof(Handle) && 229 return i >= 0 && (u_int)i < num_handles && handles[i].use == type;
213 handles[i].use == type;
214} 230}
215 231
216static int 232static int
@@ -300,12 +316,12 @@ handle_close(int handle)
300 316
301 if (handle_is_ok(handle, HANDLE_FILE)) { 317 if (handle_is_ok(handle, HANDLE_FILE)) {
302 ret = close(handles[handle].fd); 318 ret = close(handles[handle].fd);
303 handles[handle].use = HANDLE_UNUSED;
304 xfree(handles[handle].name); 319 xfree(handles[handle].name);
320 handle_unused(handle);
305 } else if (handle_is_ok(handle, HANDLE_DIR)) { 321 } else if (handle_is_ok(handle, HANDLE_DIR)) {
306 ret = closedir(handles[handle].dirp); 322 ret = closedir(handles[handle].dirp);
307 handles[handle].use = HANDLE_UNUSED;
308 xfree(handles[handle].name); 323 xfree(handles[handle].name);
324 handle_unused(handle);
309 } else { 325 } else {
310 errno = ENOENT; 326 errno = ENOENT;
311 } 327 }
@@ -333,7 +349,7 @@ handle_log_exit(void)
333{ 349{
334 u_int i; 350 u_int i;
335 351
336 for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) 352 for (i = 0; i < num_handles; i++)
337 if (handles[i].use != HANDLE_UNUSED) 353 if (handles[i].use != HANDLE_UNUSED)
338 handle_log_close(i, "forced"); 354 handle_log_close(i, "forced");
339} 355}
@@ -468,6 +484,33 @@ send_attrib(u_int32_t id, const Attrib *a)
468 buffer_free(&msg); 484 buffer_free(&msg);
469} 485}
470 486
487static void
488send_statvfs(u_int32_t id, struct statvfs *st)
489{
490 Buffer msg;
491 u_int64_t flag;
492
493 flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0;
494 flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0;
495
496 buffer_init(&msg);
497 buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY);
498 buffer_put_int(&msg, id);
499 buffer_put_int64(&msg, st->f_bsize);
500 buffer_put_int64(&msg, st->f_frsize);
501 buffer_put_int64(&msg, st->f_blocks);
502 buffer_put_int64(&msg, st->f_bfree);
503 buffer_put_int64(&msg, st->f_bavail);
504 buffer_put_int64(&msg, st->f_files);
505 buffer_put_int64(&msg, st->f_ffree);
506 buffer_put_int64(&msg, st->f_favail);
507 buffer_put_int64(&msg, FSID_TO_ULONG(st->f_fsid));
508 buffer_put_int64(&msg, flag);
509 buffer_put_int64(&msg, st->f_namemax);
510 send_msg(&msg);
511 buffer_free(&msg);
512}
513
471/* parse incoming */ 514/* parse incoming */
472 515
473static void 516static void
@@ -480,6 +523,15 @@ process_init(void)
480 buffer_init(&msg); 523 buffer_init(&msg);
481 buffer_put_char(&msg, SSH2_FXP_VERSION); 524 buffer_put_char(&msg, SSH2_FXP_VERSION);
482 buffer_put_int(&msg, SSH2_FILEXFER_VERSION); 525 buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
526 /* POSIX rename extension */
527 buffer_put_cstring(&msg, "posix-rename@openssh.com");
528 buffer_put_cstring(&msg, "1"); /* version */
529 /* statvfs extension */
530 buffer_put_cstring(&msg, "statvfs@openssh.com");
531 buffer_put_cstring(&msg, "2"); /* version */
532 /* fstatvfs extension */
533 buffer_put_cstring(&msg, "fstatvfs@openssh.com");
534 buffer_put_cstring(&msg, "2"); /* version */
483 send_msg(&msg); 535 send_msg(&msg);
484 buffer_free(&msg); 536 buffer_free(&msg);
485} 537}
@@ -711,7 +763,7 @@ process_setstat(void)
711 } 763 }
712 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 764 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
713 logit("set \"%s\" mode %04o", name, a->perm); 765 logit("set \"%s\" mode %04o", name, a->perm);
714 ret = chmod(name, a->perm & 0777); 766 ret = chmod(name, a->perm & 07777);
715 if (ret == -1) 767 if (ret == -1)
716 status = errno_to_portable(errno); 768 status = errno_to_portable(errno);
717 } 769 }
@@ -765,9 +817,9 @@ process_fsetstat(void)
765 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 817 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
766 logit("set \"%s\" mode %04o", name, a->perm); 818 logit("set \"%s\" mode %04o", name, a->perm);
767#ifdef HAVE_FCHMOD 819#ifdef HAVE_FCHMOD
768 ret = fchmod(fd, a->perm & 0777); 820 ret = fchmod(fd, a->perm & 07777);
769#else 821#else
770 ret = chmod(name, a->perm & 0777); 822 ret = chmod(name, a->perm & 07777);
771#endif 823#endif
772 if (ret == -1) 824 if (ret == -1)
773 status = errno_to_portable(errno); 825 status = errno_to_portable(errno);
@@ -918,7 +970,7 @@ process_mkdir(void)
918 name = get_string(NULL); 970 name = get_string(NULL);
919 a = get_attrib(); 971 a = get_attrib();
920 mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? 972 mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
921 a->perm & 0777 : 0777; 973 a->perm & 07777 : 0777;
922 debug3("request %u: mkdir", id); 974 debug3("request %u: mkdir", id);
923 logit("mkdir name \"%s\" mode 0%o", name, mode); 975 logit("mkdir name \"%s\" mode 0%o", name, mode);
924 ret = mkdir(name, mode); 976 ret = mkdir(name, mode);
@@ -990,6 +1042,9 @@ process_rename(void)
990 /* Race-free rename of regular files */ 1042 /* Race-free rename of regular files */
991 if (link(oldpath, newpath) == -1) { 1043 if (link(oldpath, newpath) == -1) {
992 if (errno == EOPNOTSUPP 1044 if (errno == EOPNOTSUPP
1045#ifdef EXDEV
1046 || errno == EXDEV
1047#endif
993#ifdef LINK_OPNOTSUPP_ERRNO 1048#ifdef LINK_OPNOTSUPP_ERRNO
994 || errno == LINK_OPNOTSUPP_ERRNO 1049 || errno == LINK_OPNOTSUPP_ERRNO
995#endif 1050#endif
@@ -1073,6 +1128,59 @@ process_symlink(void)
1073} 1128}
1074 1129
1075static void 1130static void
1131process_extended_posix_rename(u_int32_t id)
1132{
1133 char *oldpath, *newpath;
1134
1135 oldpath = get_string(NULL);
1136 newpath = get_string(NULL);
1137 debug3("request %u: posix-rename", id);
1138 logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
1139 if (rename(oldpath, newpath) == -1)
1140 send_status(id, errno_to_portable(errno));
1141 else
1142 send_status(id, SSH2_FX_OK);
1143 xfree(oldpath);
1144 xfree(newpath);
1145}
1146
1147static void
1148process_extended_statvfs(u_int32_t id)
1149{
1150 char *path;
1151 struct statvfs st;
1152
1153 path = get_string(NULL);
1154 debug3("request %u: statfs", id);
1155 logit("statfs \"%s\"", path);
1156
1157 if (statvfs(path, &st) != 0)
1158 send_status(id, errno_to_portable(errno));
1159 else
1160 send_statvfs(id, &st);
1161 xfree(path);
1162}
1163
1164static void
1165process_extended_fstatvfs(u_int32_t id)
1166{
1167 int handle, fd;
1168 struct statvfs st;
1169
1170 handle = get_handle();
1171 debug("request %u: fstatvfs \"%s\" (handle %u)",
1172 id, handle_to_name(handle), handle);
1173 if ((fd = handle_to_fd(handle)) < 0) {
1174 send_status(id, SSH2_FX_FAILURE);
1175 return;
1176 }
1177 if (fstatvfs(fd, &st) != 0)
1178 send_status(id, errno_to_portable(errno));
1179 else
1180 send_statvfs(id, &st);
1181}
1182
1183static void
1076process_extended(void) 1184process_extended(void)
1077{ 1185{
1078 u_int32_t id; 1186 u_int32_t id;
@@ -1080,7 +1188,14 @@ process_extended(void)
1080 1188
1081 id = get_int(); 1189 id = get_int();
1082 request = get_string(NULL); 1190 request = get_string(NULL);
1083 send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ 1191 if (strcmp(request, "posix-rename@openssh.com") == 0)
1192 process_extended_posix_rename(id);
1193 else if (strcmp(request, "statvfs@openssh.com") == 0)
1194 process_extended_statvfs(id);
1195 else if (strcmp(request, "fstatvfs@openssh.com") == 0)
1196 process_extended_fstatvfs(id);
1197 else
1198 send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */
1084 xfree(request); 1199 xfree(request);
1085} 1200}
1086 1201
@@ -1103,7 +1218,7 @@ process(void)
1103 if (msg_len > SFTP_MAX_MSG_LENGTH) { 1218 if (msg_len > SFTP_MAX_MSG_LENGTH) {
1104 error("bad message from %s local user %s", 1219 error("bad message from %s local user %s",
1105 client_addr, pw->pw_name); 1220 client_addr, pw->pw_name);
1106 cleanup_exit(11); 1221 sftp_server_cleanup_exit(11);
1107 } 1222 }
1108 if (buf_len < msg_len + 4) 1223 if (buf_len < msg_len + 4)
1109 return; 1224 return;
@@ -1176,18 +1291,22 @@ process(void)
1176 break; 1291 break;
1177 } 1292 }
1178 /* discard the remaining bytes from the current packet */ 1293 /* discard the remaining bytes from the current packet */
1179 if (buf_len < buffer_len(&iqueue)) 1294 if (buf_len < buffer_len(&iqueue)) {
1180 fatal("iqueue grew unexpectedly"); 1295 error("iqueue grew unexpectedly");
1296 sftp_server_cleanup_exit(255);
1297 }
1181 consumed = buf_len - buffer_len(&iqueue); 1298 consumed = buf_len - buffer_len(&iqueue);
1182 if (msg_len < consumed) 1299 if (msg_len < consumed) {
1183 fatal("msg_len %d < consumed %d", msg_len, consumed); 1300 error("msg_len %d < consumed %d", msg_len, consumed);
1301 sftp_server_cleanup_exit(255);
1302 }
1184 if (msg_len > consumed) 1303 if (msg_len > consumed)
1185 buffer_consume(&iqueue, msg_len - consumed); 1304 buffer_consume(&iqueue, msg_len - consumed);
1186} 1305}
1187 1306
1188/* Cleanup handler that logs active handles upon normal exit */ 1307/* Cleanup handler that logs active handles upon normal exit */
1189void 1308void
1190cleanup_exit(int i) 1309sftp_server_cleanup_exit(int i)
1191{ 1310{
1192 if (pw != NULL && client_addr != NULL) { 1311 if (pw != NULL && client_addr != NULL) {
1193 handle_log_exit(); 1312 handle_log_exit();
@@ -1198,7 +1317,7 @@ cleanup_exit(int i)
1198} 1317}
1199 1318
1200static void 1319static void
1201usage(void) 1320sftp_server_usage(void)
1202{ 1321{
1203 extern char *__progname; 1322 extern char *__progname;
1204 1323
@@ -1208,7 +1327,7 @@ usage(void)
1208} 1327}
1209 1328
1210int 1329int
1211main(int argc, char **argv) 1330sftp_server_main(int argc, char **argv, struct passwd *user_pw)
1212{ 1331{
1213 fd_set *rset, *wset; 1332 fd_set *rset, *wset;
1214 int in, out, max, ch, skipargs = 0, log_stderr = 0; 1333 int in, out, max, ch, skipargs = 0, log_stderr = 0;
@@ -1219,9 +1338,6 @@ main(int argc, char **argv)
1219 extern char *optarg; 1338 extern char *optarg;
1220 extern char *__progname; 1339 extern char *__progname;
1221 1340
1222 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1223 sanitise_stdfd();
1224
1225 __progname = ssh_get_progname(argv[0]); 1341 __progname = ssh_get_progname(argv[0]);
1226 log_init(__progname, log_level, log_facility, log_stderr); 1342 log_init(__progname, log_level, log_facility, log_stderr);
1227 1343
@@ -1244,12 +1360,12 @@ main(int argc, char **argv)
1244 break; 1360 break;
1245 case 'f': 1361 case 'f':
1246 log_facility = log_facility_number(optarg); 1362 log_facility = log_facility_number(optarg);
1247 if (log_level == SYSLOG_FACILITY_NOT_SET) 1363 if (log_facility == SYSLOG_FACILITY_NOT_SET)
1248 error("Invalid log facility \"%s\"", optarg); 1364 error("Invalid log facility \"%s\"", optarg);
1249 break; 1365 break;
1250 case 'h': 1366 case 'h':
1251 default: 1367 default:
1252 usage(); 1368 sftp_server_usage();
1253 } 1369 }
1254 } 1370 }
1255 1371
@@ -1257,22 +1373,20 @@ main(int argc, char **argv)
1257 1373
1258 if ((cp = getenv("SSH_CONNECTION")) != NULL) { 1374 if ((cp = getenv("SSH_CONNECTION")) != NULL) {
1259 client_addr = xstrdup(cp); 1375 client_addr = xstrdup(cp);
1260 if ((cp = strchr(client_addr, ' ')) == NULL) 1376 if ((cp = strchr(client_addr, ' ')) == NULL) {
1261 fatal("Malformed SSH_CONNECTION variable: \"%s\"", 1377 error("Malformed SSH_CONNECTION variable: \"%s\"",
1262 getenv("SSH_CONNECTION")); 1378 getenv("SSH_CONNECTION"));
1379 sftp_server_cleanup_exit(255);
1380 }
1263 *cp = '\0'; 1381 *cp = '\0';
1264 } else 1382 } else
1265 client_addr = xstrdup("UNKNOWN"); 1383 client_addr = xstrdup("UNKNOWN");
1266 1384
1267 if ((pw = getpwuid(getuid())) == NULL) 1385 pw = pwcopy(user_pw);
1268 fatal("No user found for uid %lu", (u_long)getuid());
1269 pw = pwcopy(pw);
1270 1386
1271 logit("session opened for local user %s from [%s]", 1387 logit("session opened for local user %s from [%s]",
1272 pw->pw_name, client_addr); 1388 pw->pw_name, client_addr);
1273 1389
1274 handle_init();
1275
1276 in = dup(STDIN_FILENO); 1390 in = dup(STDIN_FILENO);
1277 out = dup(STDOUT_FILENO); 1391 out = dup(STDOUT_FILENO);
1278 1392
@@ -1315,7 +1429,7 @@ main(int argc, char **argv)
1315 if (errno == EINTR) 1429 if (errno == EINTR)
1316 continue; 1430 continue;
1317 error("select: %s", strerror(errno)); 1431 error("select: %s", strerror(errno));
1318 cleanup_exit(2); 1432 sftp_server_cleanup_exit(2);
1319 } 1433 }
1320 1434
1321 /* copy stdin to iqueue */ 1435 /* copy stdin to iqueue */
@@ -1323,10 +1437,10 @@ main(int argc, char **argv)
1323 len = read(in, buf, sizeof buf); 1437 len = read(in, buf, sizeof buf);
1324 if (len == 0) { 1438 if (len == 0) {
1325 debug("read eof"); 1439 debug("read eof");
1326 cleanup_exit(0); 1440 sftp_server_cleanup_exit(0);
1327 } else if (len < 0) { 1441 } else if (len < 0) {
1328 error("read: %s", strerror(errno)); 1442 error("read: %s", strerror(errno));
1329 cleanup_exit(1); 1443 sftp_server_cleanup_exit(1);
1330 } else { 1444 } else {
1331 buffer_append(&iqueue, buf, len); 1445 buffer_append(&iqueue, buf, len);
1332 } 1446 }
@@ -1336,7 +1450,7 @@ main(int argc, char **argv)
1336 len = write(out, buffer_ptr(&oqueue), olen); 1450 len = write(out, buffer_ptr(&oqueue), olen);
1337 if (len < 0) { 1451 if (len < 0) {
1338 error("write: %s", strerror(errno)); 1452 error("write: %s", strerror(errno));
1339 cleanup_exit(1); 1453 sftp_server_cleanup_exit(1);
1340 } else { 1454 } else {
1341 buffer_consume(&oqueue, len); 1455 buffer_consume(&oqueue, len);
1342 } 1456 }
diff --git a/sftp.0 b/sftp.0
index ee2691f4a..965e1fa18 100644
--- a/sftp.0
+++ b/sftp.0
@@ -43,8 +43,8 @@ DESCRIPTION
43 batchfile of `-' may be used to indicate standard input. sftp 43 batchfile of `-' may be used to indicate standard input. sftp
44 will abort if any of the following commands fail: get, put, 44 will abort if any of the following commands fail: get, put,
45 rename, ln, rm, mkdir, chdir, ls, lchdir, chmod, chown, chgrp, 45 rename, ln, rm, mkdir, chdir, ls, lchdir, chmod, chown, chgrp,
46 lpwd and lmkdir. Termination on error can be suppressed on a 46 lpwd, df, and lmkdir. Termination on error can be suppressed on
47 command by command basis by prefixing the command with a `-' 47 a command by command basis by prefixing the command with a `-'
48 character (for example, -rm /tmp/blah*). 48 character (for example, -rm /tmp/blah*).
49 49
50 -C Enables compression (via ssh's -C flag). 50 -C Enables compression (via ssh's -C flag).
@@ -117,7 +117,7 @@ DESCRIPTION
117 -R num_requests 117 -R num_requests
118 Specify how many requests may be outstanding at any one time. 118 Specify how many requests may be outstanding at any one time.
119 Increasing this may slightly improve file transfer speed but will 119 Increasing this may slightly improve file transfer speed but will
120 increase memory usage. The default is 16 outstanding requests. 120 increase memory usage. The default is 64 outstanding requests.
121 121
122 -S program 122 -S program
123 Name of the program to use for the encrypted connection. The 123 Name of the program to use for the encrypted connection. The
@@ -155,6 +155,14 @@ INTERACTIVE COMMANDS
155 Change owner of file path to own. path may contain glob(3) char- 155 Change owner of file path to own. path may contain glob(3) char-
156 acters and may match multiple files. own must be a numeric UID. 156 acters and may match multiple files. own must be a numeric UID.
157 157
158 df [-hi] [path]
159 Display usage information for the filesystem holding the current
160 directory (or path if specified). If the -h flag is specified,
161 the capacity information will be displayed using "human-readable"
162 suffixes. The -i flag requests display of inode information in
163 addition to capacity information. This command is only supported
164 on servers that implement the ``statvfs@openssh.com'' extension.
165
158 exit Quit sftp. 166 exit Quit sftp.
159 167
160 get [-P] remote-path [local-path] 168 get [-P] remote-path [local-path]
@@ -263,4 +271,4 @@ SEE ALSO
263 T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- 271 T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
264 filexfer-00.txt, January 2001, work in progress material. 272 filexfer-00.txt, January 2001, work in progress material.
265 273
266OpenBSD 4.2 June 5, 2007 4 274OpenBSD 4.4 July 15, 2008 5
diff --git a/sftp.1 b/sftp.1
index 6e025bc99..b4f9a6884 100644
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: sftp.1,v 1.64 2007/05/31 19:20:16 jmc Exp $ 1.\" $OpenBSD: sftp.1,v 1.67 2008/07/15 02:23:14 djm Exp $
2.\" 2.\"
3.\" Copyright (c) 2001 Damien Miller. All rights reserved. 3.\" Copyright (c) 2001 Damien Miller. All rights reserved.
4.\" 4.\"
@@ -22,7 +22,7 @@
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\" 24.\"
25.Dd $Mdocdate: June 5 2007 $ 25.Dd $Mdocdate: July 15 2008 $
26.Dt SFTP 1 26.Dt SFTP 1
27.Os 27.Os
28.Sh NAME 28.Sh NAME
@@ -112,7 +112,8 @@ will abort if any of the following
112commands fail: 112commands fail:
113.Ic get , put , rename , ln , 113.Ic get , put , rename , ln ,
114.Ic rm , mkdir , chdir , ls , 114.Ic rm , mkdir , chdir , ls ,
115.Ic lchdir , chmod , chown , chgrp , lpwd 115.Ic lchdir , chmod , chown ,
116.Ic chgrp , lpwd , df ,
116and 117and
117.Ic lmkdir . 118.Ic lmkdir .
118Termination on error can be suppressed on a command by command basis by 119Termination on error can be suppressed on a command by command basis by
@@ -203,7 +204,7 @@ This option may be useful in debugging the client and server.
203Specify how many requests may be outstanding at any one time. 204Specify how many requests may be outstanding at any one time.
204Increasing this may slightly improve file transfer speed 205Increasing this may slightly improve file transfer speed
205but will increase memory usage. 206but will increase memory usage.
206The default is 16 outstanding requests. 207The default is 64 outstanding requests.
207.It Fl S Ar program 208.It Fl S Ar program
208Name of the 209Name of the
209.Ar program 210.Ar program
@@ -272,6 +273,24 @@ may contain
272characters and may match multiple files. 273characters and may match multiple files.
273.Ar own 274.Ar own
274must be a numeric UID. 275must be a numeric UID.
276.It Xo Ic df
277.Op Fl hi
278.Op Ar path
279.Xc
280Display usage information for the filesystem holding the current directory
281(or
282.Ar path
283if specified).
284If the
285.Fl h
286flag is specified, the capacity information will be displayed using
287"human-readable" suffixes.
288The
289.Fl i
290flag requests display of inode information in addition to capacity information.
291This command is only supported on servers that implement the
292.Dq statvfs@openssh.com
293extension.
275.It Ic exit 294.It Ic exit
276Quit 295Quit
277.Nm sftp . 296.Nm sftp .
diff --git a/sftp.c b/sftp.c
index f0d5dd557..e1aa49d0f 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.96 2007/01/03 04:09:15 stevesk Exp $ */ 1/* $OpenBSD: sftp.c,v 1.103 2008/07/13 22:16:03 djm 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 *
@@ -25,7 +25,11 @@
25#include <sys/param.h> 25#include <sys/param.h>
26#include <sys/socket.h> 26#include <sys/socket.h>
27#include <sys/wait.h> 27#include <sys/wait.h>
28#ifdef HAVE_SYS_STATVFS_H
29#include <sys/statvfs.h>
30#endif
28 31
32#include <ctype.h>
29#include <errno.h> 33#include <errno.h>
30 34
31#ifdef HAVE_PATHS_H 35#ifdef HAVE_PATHS_H
@@ -43,6 +47,14 @@ typedef void EditLine;
43#include <unistd.h> 47#include <unistd.h>
44#include <stdarg.h> 48#include <stdarg.h>
45 49
50#ifdef HAVE_UTIL_H
51# include <util.h>
52#endif
53
54#ifdef HAVE_LIBUTIL_H
55# include <libutil.h>
56#endif
57
46#include "xmalloc.h" 58#include "xmalloc.h"
47#include "log.h" 59#include "log.h"
48#include "pathnames.h" 60#include "pathnames.h"
@@ -63,7 +75,7 @@ int batchmode = 0;
63size_t copy_buffer_len = 32768; 75size_t copy_buffer_len = 32768;
64 76
65/* Number of concurrent outstanding requests */ 77/* Number of concurrent outstanding requests */
66size_t num_requests = 16; 78size_t num_requests = 64;
67 79
68/* PID of ssh transport process */ 80/* PID of ssh transport process */
69static pid_t sshpid = -1; 81static pid_t sshpid = -1;
@@ -103,6 +115,7 @@ extern char *__progname;
103#define I_CHGRP 2 115#define I_CHGRP 2
104#define I_CHMOD 3 116#define I_CHMOD 3
105#define I_CHOWN 4 117#define I_CHOWN 4
118#define I_DF 24
106#define I_GET 5 119#define I_GET 5
107#define I_HELP 6 120#define I_HELP 6
108#define I_LCHDIR 7 121#define I_LCHDIR 7
@@ -135,6 +148,7 @@ static const struct CMD cmds[] = {
135 { "chgrp", I_CHGRP }, 148 { "chgrp", I_CHGRP },
136 { "chmod", I_CHMOD }, 149 { "chmod", I_CHMOD },
137 { "chown", I_CHOWN }, 150 { "chown", I_CHOWN },
151 { "df", I_DF },
138 { "dir", I_LS }, 152 { "dir", I_LS },
139 { "exit", I_QUIT }, 153 { "exit", I_QUIT },
140 { "get", I_GET }, 154 { "get", I_GET },
@@ -199,6 +213,8 @@ help(void)
199 printf("chgrp grp path Change group of file 'path' to 'grp'\n"); 213 printf("chgrp grp path Change group of file 'path' to 'grp'\n");
200 printf("chmod mode path Change permissions of file 'path' to 'mode'\n"); 214 printf("chmod mode path Change permissions of file 'path' to 'mode'\n");
201 printf("chown own path Change owner of file 'path' to 'own'\n"); 215 printf("chown own path Change owner of file 'path' to 'own'\n");
216 printf("df [path] Display statistics for current directory or\n");
217 printf(" filesystem containing 'path'\n");
202 printf("help Display this help text\n"); 218 printf("help Display this help text\n");
203 printf("get remote-path [local-path] Download file\n"); 219 printf("get remote-path [local-path] Download file\n");
204 printf("lls [ls-options [path]] Display local directory listing\n"); 220 printf("lls [ls-options [path]] Display local directory listing\n");
@@ -346,144 +362,105 @@ infer_path(const char *p, char **ifp)
346} 362}
347 363
348static int 364static int
349parse_getput_flags(const char **cpp, int *pflag) 365parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag)
350{ 366{
351 const char *cp = *cpp; 367 extern int opterr, optind, optopt, optreset;
368 int ch;
352 369
353 /* Check for flags */ 370 optind = optreset = 1;
354 if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) { 371 opterr = 0;
355 switch (cp[1]) { 372
373 *pflag = 0;
374 while ((ch = getopt(argc, argv, "Pp")) != -1) {
375 switch (ch) {
356 case 'p': 376 case 'p':
357 case 'P': 377 case 'P':
358 *pflag = 1; 378 *pflag = 1;
359 break; 379 break;
360 default: 380 default:
361 error("Invalid flag -%c", cp[1]); 381 error("%s: Invalid flag -%c", cmd, optopt);
362 return(-1); 382 return -1;
363 } 383 }
364 cp += 2;
365 *cpp = cp + strspn(cp, WHITESPACE);
366 } 384 }
367 385
368 return(0); 386 return optind;
369} 387}
370 388
371static int 389static int
372parse_ls_flags(const char **cpp, int *lflag) 390parse_ls_flags(char **argv, int argc, int *lflag)
373{ 391{
374 const char *cp = *cpp; 392 extern int opterr, optind, optopt, optreset;
393 int ch;
375 394
376 /* Defaults */ 395 optind = optreset = 1;
377 *lflag = LS_NAME_SORT; 396 opterr = 0;
378 397
379 /* Check for flags */ 398 *lflag = LS_NAME_SORT;
380 if (cp++[0] == '-') { 399 while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) {
381 for (; strchr(WHITESPACE, *cp) == NULL; cp++) { 400 switch (ch) {
382 switch (*cp) { 401 case '1':
383 case 'l': 402 *lflag &= ~VIEW_FLAGS;
384 *lflag &= ~VIEW_FLAGS; 403 *lflag |= LS_SHORT_VIEW;
385 *lflag |= LS_LONG_VIEW; 404 break;
386 break; 405 case 'S':
387 case '1': 406 *lflag &= ~SORT_FLAGS;
388 *lflag &= ~VIEW_FLAGS; 407 *lflag |= LS_SIZE_SORT;
389 *lflag |= LS_SHORT_VIEW; 408 break;
390 break; 409 case 'a':
391 case 'n': 410 *lflag |= LS_SHOW_ALL;
392 *lflag &= ~VIEW_FLAGS; 411 break;
393 *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; 412 case 'f':
394 break; 413 *lflag &= ~SORT_FLAGS;
395 case 'S': 414 break;
396 *lflag &= ~SORT_FLAGS; 415 case 'l':
397 *lflag |= LS_SIZE_SORT; 416 *lflag &= ~VIEW_FLAGS;
398 break; 417 *lflag |= LS_LONG_VIEW;
399 case 't': 418 break;
400 *lflag &= ~SORT_FLAGS; 419 case 'n':
401 *lflag |= LS_TIME_SORT; 420 *lflag &= ~VIEW_FLAGS;
402 break; 421 *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
403 case 'r': 422 break;
404 *lflag |= LS_REVERSE_SORT; 423 case 'r':
405 break; 424 *lflag |= LS_REVERSE_SORT;
406 case 'f': 425 break;
407 *lflag &= ~SORT_FLAGS; 426 case 't':
408 break; 427 *lflag &= ~SORT_FLAGS;
409 case 'a': 428 *lflag |= LS_TIME_SORT;
410 *lflag |= LS_SHOW_ALL; 429 break;
411 break; 430 default:
412 default: 431 error("ls: Invalid flag -%c", optopt);
413 error("Invalid flag -%c", *cp); 432 return -1;
414 return(-1);
415 }
416 } 433 }
417 *cpp = cp + strspn(cp, WHITESPACE);
418 } 434 }
419 435
420 return(0); 436 return optind;
421} 437}
422 438
423static int 439static int
424get_pathname(const char **cpp, char **path) 440parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
425{ 441{
426 const char *cp = *cpp, *end; 442 extern int opterr, optind, optopt, optreset;
427 char quot; 443 int ch;
428 u_int i, j;
429
430 cp += strspn(cp, WHITESPACE);
431 if (!*cp) {
432 *cpp = cp;
433 *path = NULL;
434 return (0);
435 }
436
437 *path = xmalloc(strlen(cp) + 1);
438
439 /* Check for quoted filenames */
440 if (*cp == '\"' || *cp == '\'') {
441 quot = *cp++;
442 444
443 /* Search for terminating quote, unescape some chars */ 445 optind = optreset = 1;
444 for (i = j = 0; i <= strlen(cp); i++) { 446 opterr = 0;
445 if (cp[i] == quot) { /* Found quote */
446 i++;
447 (*path)[j] = '\0';
448 break;
449 }
450 if (cp[i] == '\0') { /* End of string */
451 error("Unterminated quote");
452 goto fail;
453 }
454 if (cp[i] == '\\') { /* Escaped characters */
455 i++;
456 if (cp[i] != '\'' && cp[i] != '\"' &&
457 cp[i] != '\\') {
458 error("Bad escaped character '\\%c'",
459 cp[i]);
460 goto fail;
461 }
462 }
463 (*path)[j++] = cp[i];
464 }
465 447
466 if (j == 0) { 448 *hflag = *iflag = 0;
467 error("Empty quotes"); 449 while ((ch = getopt(argc, argv, "hi")) != -1) {
468 goto fail; 450 switch (ch) {
451 case 'h':
452 *hflag = 1;
453 break;
454 case 'i':
455 *iflag = 1;
456 break;
457 default:
458 error("%s: Invalid flag -%c", cmd, optopt);
459 return -1;
469 } 460 }
470 *cpp = cp + i + strspn(cp + i, WHITESPACE);
471 } else {
472 /* Read to end of filename */
473 end = strpbrk(cp, WHITESPACE);
474 if (end == NULL)
475 end = strchr(cp, '\0');
476 *cpp = end + strspn(end, WHITESPACE);
477
478 memcpy(*path, cp, end - cp);
479 (*path)[end - cp] = '\0';
480 } 461 }
481 return (0);
482 462
483 fail: 463 return optind;
484 xfree(*path);
485 *path = NULL;
486 return (-1);
487} 464}
488 465
489static int 466static int
@@ -499,17 +476,6 @@ is_dir(char *path)
499} 476}
500 477
501static int 478static int
502is_reg(char *path)
503{
504 struct stat sb;
505
506 if (stat(path, &sb) == -1)
507 fatal("stat %s: %s", path, strerror(errno));
508
509 return(S_ISREG(sb.st_mode));
510}
511
512static int
513remote_is_dir(struct sftp_conn *conn, char *path) 479remote_is_dir(struct sftp_conn *conn, char *path)
514{ 480{
515 Attrib *a; 481 Attrib *a;
@@ -597,6 +563,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
597 glob_t g; 563 glob_t g;
598 int err = 0; 564 int err = 0;
599 int i; 565 int i;
566 struct stat sb;
600 567
601 if (dst) { 568 if (dst) {
602 tmp_dst = xstrdup(dst); 569 tmp_dst = xstrdup(dst);
@@ -605,7 +572,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
605 572
606 memset(&g, 0, sizeof(g)); 573 memset(&g, 0, sizeof(g));
607 debug3("Looking up %s", src); 574 debug3("Looking up %s", src);
608 if (glob(src, 0, NULL, &g)) { 575 if (glob(src, GLOB_NOCHECK, NULL, &g)) {
609 error("File \"%s\" not found.", src); 576 error("File \"%s\" not found.", src);
610 err = -1; 577 err = -1;
611 goto out; 578 goto out;
@@ -620,7 +587,13 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
620 } 587 }
621 588
622 for (i = 0; g.gl_pathv[i] && !interrupted; i++) { 589 for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
623 if (!is_reg(g.gl_pathv[i])) { 590 if (stat(g.gl_pathv[i], &sb) == -1) {
591 err = -1;
592 error("stat %s: %s", g.gl_pathv[i], strerror(errno));
593 continue;
594 }
595
596 if (!S_ISREG(sb.st_mode)) {
624 error("skipping non-regular file %s", 597 error("skipping non-regular file %s",
625 g.gl_pathv[i]); 598 g.gl_pathv[i]);
626 continue; 599 continue;
@@ -867,14 +840,238 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
867} 840}
868 841
869static int 842static int
870parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, 843do_df(struct sftp_conn *conn, char *path, int hflag, int iflag)
844{
845 struct sftp_statvfs st;
846 char s_used[FMT_SCALED_STRSIZE];
847 char s_avail[FMT_SCALED_STRSIZE];
848 char s_root[FMT_SCALED_STRSIZE];
849 char s_total[FMT_SCALED_STRSIZE];
850
851 if (do_statvfs(conn, path, &st, 1) == -1)
852 return -1;
853 if (iflag) {
854 printf(" Inodes Used Avail "
855 "(root) %%Capacity\n");
856 printf("%11llu %11llu %11llu %11llu %3llu%%\n",
857 (unsigned long long)st.f_files,
858 (unsigned long long)(st.f_files - st.f_ffree),
859 (unsigned long long)st.f_favail,
860 (unsigned long long)st.f_ffree,
861 (unsigned long long)(100 * (st.f_files - st.f_ffree) /
862 st.f_files));
863 } else if (hflag) {
864 strlcpy(s_used, "error", sizeof(s_used));
865 strlcpy(s_avail, "error", sizeof(s_avail));
866 strlcpy(s_root, "error", sizeof(s_root));
867 strlcpy(s_total, "error", sizeof(s_total));
868 fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used);
869 fmt_scaled(st.f_bavail * st.f_frsize, s_avail);
870 fmt_scaled(st.f_bfree * st.f_frsize, s_root);
871 fmt_scaled(st.f_blocks * st.f_frsize, s_total);
872 printf(" Size Used Avail (root) %%Capacity\n");
873 printf("%7sB %7sB %7sB %7sB %3llu%%\n",
874 s_total, s_used, s_avail, s_root,
875 (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
876 st.f_blocks));
877 } else {
878 printf(" Size Used Avail "
879 "(root) %%Capacity\n");
880 printf("%12llu %12llu %12llu %12llu %3llu%%\n",
881 (unsigned long long)(st.f_frsize * st.f_blocks / 1024),
882 (unsigned long long)(st.f_frsize *
883 (st.f_blocks - st.f_bfree) / 1024),
884 (unsigned long long)(st.f_frsize * st.f_bavail / 1024),
885 (unsigned long long)(st.f_frsize * st.f_bfree / 1024),
886 (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
887 st.f_blocks));
888 }
889 return 0;
890}
891
892/*
893 * Undo escaping of glob sequences in place. Used to undo extra escaping
894 * applied in makeargv() when the string is destined for a function that
895 * does not glob it.
896 */
897static void
898undo_glob_escape(char *s)
899{
900 size_t i, j;
901
902 for (i = j = 0;;) {
903 if (s[i] == '\0') {
904 s[j] = '\0';
905 return;
906 }
907 if (s[i] != '\\') {
908 s[j++] = s[i++];
909 continue;
910 }
911 /* s[i] == '\\' */
912 ++i;
913 switch (s[i]) {
914 case '?':
915 case '[':
916 case '*':
917 case '\\':
918 s[j++] = s[i++];
919 break;
920 case '\0':
921 s[j++] = '\\';
922 s[j] = '\0';
923 return;
924 default:
925 s[j++] = '\\';
926 s[j++] = s[i++];
927 break;
928 }
929 }
930}
931
932/*
933 * Split a string into an argument vector using sh(1)-style quoting,
934 * comment and escaping rules, but with some tweaks to handle glob(3)
935 * wildcards.
936 * Returns NULL on error or a NULL-terminated array of arguments.
937 */
938#define MAXARGS 128
939#define MAXARGLEN 8192
940static char **
941makeargv(const char *arg, int *argcp)
942{
943 int argc, quot;
944 size_t i, j;
945 static char argvs[MAXARGLEN];
946 static char *argv[MAXARGS + 1];
947 enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;
948
949 *argcp = argc = 0;
950 if (strlen(arg) > sizeof(argvs) - 1) {
951 args_too_longs:
952 error("string too long");
953 return NULL;
954 }
955 state = MA_START;
956 i = j = 0;
957 for (;;) {
958 if (isspace(arg[i])) {
959 if (state == MA_UNQUOTED) {
960 /* Terminate current argument */
961 argvs[j++] = '\0';
962 argc++;
963 state = MA_START;
964 } else if (state != MA_START)
965 argvs[j++] = arg[i];
966 } else if (arg[i] == '"' || arg[i] == '\'') {
967 q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
968 if (state == MA_START) {
969 argv[argc] = argvs + j;
970 state = q;
971 } else if (state == MA_UNQUOTED)
972 state = q;
973 else if (state == q)
974 state = MA_UNQUOTED;
975 else
976 argvs[j++] = arg[i];
977 } else if (arg[i] == '\\') {
978 if (state == MA_SQUOTE || state == MA_DQUOTE) {
979 quot = state == MA_SQUOTE ? '\'' : '"';
980 /* Unescape quote we are in */
981 /* XXX support \n and friends? */
982 if (arg[i + 1] == quot) {
983 i++;
984 argvs[j++] = arg[i];
985 } else if (arg[i + 1] == '?' ||
986 arg[i + 1] == '[' || arg[i + 1] == '*') {
987 /*
988 * Special case for sftp: append
989 * double-escaped glob sequence -
990 * glob will undo one level of
991 * escaping. NB. string can grow here.
992 */
993 if (j >= sizeof(argvs) - 5)
994 goto args_too_longs;
995 argvs[j++] = '\\';
996 argvs[j++] = arg[i++];
997 argvs[j++] = '\\';
998 argvs[j++] = arg[i];
999 } else {
1000 argvs[j++] = arg[i++];
1001 argvs[j++] = arg[i];
1002 }
1003 } else {
1004 if (state == MA_START) {
1005 argv[argc] = argvs + j;
1006 state = MA_UNQUOTED;
1007 }
1008 if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
1009 arg[i + 1] == '*' || arg[i + 1] == '\\') {
1010 /*
1011 * Special case for sftp: append
1012 * escaped glob sequence -
1013 * glob will undo one level of
1014 * escaping.
1015 */
1016 argvs[j++] = arg[i++];
1017 argvs[j++] = arg[i];
1018 } else {
1019 /* Unescape everything */
1020 /* XXX support \n and friends? */
1021 i++;
1022 argvs[j++] = arg[i];
1023 }
1024 }
1025 } else if (arg[i] == '#') {
1026 if (state == MA_SQUOTE || state == MA_DQUOTE)
1027 argvs[j++] = arg[i];
1028 else
1029 goto string_done;
1030 } else if (arg[i] == '\0') {
1031 if (state == MA_SQUOTE || state == MA_DQUOTE) {
1032 error("Unterminated quoted argument");
1033 return NULL;
1034 }
1035 string_done:
1036 if (state == MA_UNQUOTED) {
1037 argvs[j++] = '\0';
1038 argc++;
1039 }
1040 break;
1041 } else {
1042 if (state == MA_START) {
1043 argv[argc] = argvs + j;
1044 state = MA_UNQUOTED;
1045 }
1046 if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
1047 (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
1048 /*
1049 * Special case for sftp: escape quoted
1050 * glob(3) wildcards. NB. string can grow
1051 * here.
1052 */
1053 if (j >= sizeof(argvs) - 3)
1054 goto args_too_longs;
1055 argvs[j++] = '\\';
1056 argvs[j++] = arg[i];
1057 } else
1058 argvs[j++] = arg[i];
1059 }
1060 i++;
1061 }
1062 *argcp = argc;
1063 return argv;
1064}
1065
1066static int
1067parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
871 unsigned long *n_arg, char **path1, char **path2) 1068 unsigned long *n_arg, char **path1, char **path2)
872{ 1069{
873 const char *cmd, *cp = *cpp; 1070 const char *cmd, *cp = *cpp;
874 char *cp2; 1071 char *cp2, **argv;
875 int base = 0; 1072 int base = 0;
876 long l; 1073 long l;
877 int i, cmdnum; 1074 int i, cmdnum, optidx, argc;
878 1075
879 /* Skip leading whitespace */ 1076 /* Skip leading whitespace */
880 cp = cp + strspn(cp, WHITESPACE); 1077 cp = cp + strspn(cp, WHITESPACE);
@@ -890,17 +1087,13 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
890 cp++; 1087 cp++;
891 } 1088 }
892 1089
1090 if ((argv = makeargv(cp, &argc)) == NULL)
1091 return -1;
1092
893 /* Figure out which command we have */ 1093 /* Figure out which command we have */
894 for (i = 0; cmds[i].c; i++) { 1094 for (i = 0; cmds[i].c != NULL; i++) {
895 int cmdlen = strlen(cmds[i].c); 1095 if (strcasecmp(cmds[i].c, argv[0]) == 0)
896
897 /* Check for command followed by whitespace */
898 if (!strncasecmp(cp, cmds[i].c, cmdlen) &&
899 strchr(WHITESPACE, cp[cmdlen])) {
900 cp += cmdlen;
901 cp = cp + strspn(cp, WHITESPACE);
902 break; 1096 break;
903 }
904 } 1097 }
905 cmdnum = cmds[i].n; 1098 cmdnum = cmds[i].n;
906 cmd = cmds[i].c; 1099 cmd = cmds[i].c;
@@ -911,40 +1104,44 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
911 cmdnum = I_SHELL; 1104 cmdnum = I_SHELL;
912 } else if (cmdnum == -1) { 1105 } else if (cmdnum == -1) {
913 error("Invalid command."); 1106 error("Invalid command.");
914 return (-1); 1107 return -1;
915 } 1108 }
916 1109
917 /* Get arguments and parse flags */ 1110 /* Get arguments and parse flags */
918 *lflag = *pflag = *n_arg = 0; 1111 *lflag = *pflag = *hflag = *n_arg = 0;
919 *path1 = *path2 = NULL; 1112 *path1 = *path2 = NULL;
1113 optidx = 1;
920 switch (cmdnum) { 1114 switch (cmdnum) {
921 case I_GET: 1115 case I_GET:
922 case I_PUT: 1116 case I_PUT:
923 if (parse_getput_flags(&cp, pflag)) 1117 if ((optidx = parse_getput_flags(cmd, argv, argc, pflag)) == -1)
924 return(-1); 1118 return -1;
925 /* Get first pathname (mandatory) */ 1119 /* Get first pathname (mandatory) */
926 if (get_pathname(&cp, path1)) 1120 if (argc - optidx < 1) {
927 return(-1);
928 if (*path1 == NULL) {
929 error("You must specify at least one path after a " 1121 error("You must specify at least one path after a "
930 "%s command.", cmd); 1122 "%s command.", cmd);
931 return(-1); 1123 return -1;
1124 }
1125 *path1 = xstrdup(argv[optidx]);
1126 /* Get second pathname (optional) */
1127 if (argc - optidx > 1) {
1128 *path2 = xstrdup(argv[optidx + 1]);
1129 /* Destination is not globbed */
1130 undo_glob_escape(*path2);
932 } 1131 }
933 /* Try to get second pathname (optional) */
934 if (get_pathname(&cp, path2))
935 return(-1);
936 break; 1132 break;
937 case I_RENAME: 1133 case I_RENAME:
938 case I_SYMLINK: 1134 case I_SYMLINK:
939 if (get_pathname(&cp, path1)) 1135 if (argc - optidx < 2) {
940 return(-1);
941 if (get_pathname(&cp, path2))
942 return(-1);
943 if (!*path1 || !*path2) {
944 error("You must specify two paths after a %s " 1136 error("You must specify two paths after a %s "
945 "command.", cmd); 1137 "command.", cmd);
946 return(-1); 1138 return -1;
947 } 1139 }
1140 *path1 = xstrdup(argv[optidx]);
1141 *path2 = xstrdup(argv[optidx + 1]);
1142 /* Paths are not globbed */
1143 undo_glob_escape(*path1);
1144 undo_glob_escape(*path2);
948 break; 1145 break;
949 case I_RM: 1146 case I_RM:
950 case I_MKDIR: 1147 case I_MKDIR:
@@ -953,59 +1150,69 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
953 case I_LCHDIR: 1150 case I_LCHDIR:
954 case I_LMKDIR: 1151 case I_LMKDIR:
955 /* Get pathname (mandatory) */ 1152 /* Get pathname (mandatory) */
956 if (get_pathname(&cp, path1)) 1153 if (argc - optidx < 1) {
957 return(-1);
958 if (*path1 == NULL) {
959 error("You must specify a path after a %s command.", 1154 error("You must specify a path after a %s command.",
960 cmd); 1155 cmd);
961 return(-1); 1156 return -1;
1157 }
1158 *path1 = xstrdup(argv[optidx]);
1159 /* Only "rm" globs */
1160 if (cmdnum != I_RM)
1161 undo_glob_escape(*path1);
1162 break;
1163 case I_DF:
1164 if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
1165 iflag)) == -1)
1166 return -1;
1167 /* Default to current directory if no path specified */
1168 if (argc - optidx < 1)
1169 *path1 = NULL;
1170 else {
1171 *path1 = xstrdup(argv[optidx]);
1172 undo_glob_escape(*path1);
962 } 1173 }
963 break; 1174 break;
964 case I_LS: 1175 case I_LS:
965 if (parse_ls_flags(&cp, lflag)) 1176 if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
966 return(-1); 1177 return(-1);
967 /* Path is optional */ 1178 /* Path is optional */
968 if (get_pathname(&cp, path1)) 1179 if (argc - optidx > 0)
969 return(-1); 1180 *path1 = xstrdup(argv[optidx]);
970 break; 1181 break;
971 case I_LLS: 1182 case I_LLS:
1183 /* Skip ls command and following whitespace */
1184 cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
972 case I_SHELL: 1185 case I_SHELL:
973 /* Uses the rest of the line */ 1186 /* Uses the rest of the line */
974 break; 1187 break;
975 case I_LUMASK: 1188 case I_LUMASK:
976 base = 8;
977 case I_CHMOD: 1189 case I_CHMOD:
978 base = 8; 1190 base = 8;
979 case I_CHOWN: 1191 case I_CHOWN:
980 case I_CHGRP: 1192 case I_CHGRP:
981 /* Get numeric arg (mandatory) */ 1193 /* Get numeric arg (mandatory) */
1194 if (argc - optidx < 1)
1195 goto need_num_arg;
982 errno = 0; 1196 errno = 0;
983 l = strtol(cp, &cp2, base); 1197 l = strtol(argv[optidx], &cp2, base);
984 if (cp2 == cp || ((l == LONG_MIN || l == LONG_MAX) && 1198 if (cp2 == argv[optidx] || *cp2 != '\0' ||
985 errno == ERANGE) || l < 0) { 1199 ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
1200 l < 0) {
1201 need_num_arg:
986 error("You must supply a numeric argument " 1202 error("You must supply a numeric argument "
987 "to the %s command.", cmd); 1203 "to the %s command.", cmd);
988 return(-1); 1204 return -1;
989 } 1205 }
990 cp = cp2;
991 *n_arg = l; 1206 *n_arg = l;
992 if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp)) 1207 if (cmdnum == I_LUMASK)
993 break; 1208 break;
994 if (cmdnum == I_LUMASK || !strchr(WHITESPACE, *cp)) {
995 error("You must supply a numeric argument "
996 "to the %s command.", cmd);
997 return(-1);
998 }
999 cp += strspn(cp, WHITESPACE);
1000
1001 /* Get pathname (mandatory) */ 1209 /* Get pathname (mandatory) */
1002 if (get_pathname(&cp, path1)) 1210 if (argc - optidx < 2) {
1003 return(-1);
1004 if (*path1 == NULL) {
1005 error("You must specify a path after a %s command.", 1211 error("You must specify a path after a %s command.",
1006 cmd); 1212 cmd);
1007 return(-1); 1213 return -1;
1008 } 1214 }
1215 *path1 = xstrdup(argv[optidx + 1]);
1009 break; 1216 break;
1010 case I_QUIT: 1217 case I_QUIT:
1011 case I_PWD: 1218 case I_PWD:
@@ -1027,7 +1234,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1027 int err_abort) 1234 int err_abort)
1028{ 1235{
1029 char *path1, *path2, *tmp; 1236 char *path1, *path2, *tmp;
1030 int pflag, lflag, iflag, cmdnum, i; 1237 int pflag, lflag, iflag, hflag, cmdnum, i;
1031 unsigned long n_arg; 1238 unsigned long n_arg;
1032 Attrib a, *aa; 1239 Attrib a, *aa;
1033 char path_buf[MAXPATHLEN]; 1240 char path_buf[MAXPATHLEN];
@@ -1035,7 +1242,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1035 glob_t g; 1242 glob_t g;
1036 1243
1037 path1 = path2 = NULL; 1244 path1 = path2 = NULL;
1038 cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, 1245 cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg,
1039 &path1, &path2); 1246 &path1, &path2);
1040 1247
1041 if (iflag != 0) 1248 if (iflag != 0)
@@ -1129,6 +1336,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1129 path1 = make_absolute(path1, *pwd); 1336 path1 = make_absolute(path1, *pwd);
1130 err = do_globbed_ls(conn, path1, tmp, lflag); 1337 err = do_globbed_ls(conn, path1, tmp, lflag);
1131 break; 1338 break;
1339 case I_DF:
1340 /* Default to current directory if no path specified */
1341 if (path1 == NULL)
1342 path1 = xstrdup(*pwd);
1343 path1 = make_absolute(path1, *pwd);
1344 err = do_df(conn, path1, hflag, iflag);
1345 break;
1132 case I_LCHDIR: 1346 case I_LCHDIR:
1133 if (chdir(path1) == -1) { 1347 if (chdir(path1) == -1) {
1134 error("Couldn't change local directory to " 1348 error("Couldn't change local directory to "
diff --git a/sftp.h b/sftp.h
index 610c0b758..2bde8bb7f 100644
--- a/sftp.h
+++ b/sftp.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.h,v 1.5 2006/03/25 22:22:43 djm Exp $ */ 1/* $OpenBSD: sftp.h,v 1.9 2008/06/13 00:12:02 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -79,6 +79,10 @@
79#define SSH2_FXF_TRUNC 0x00000010 79#define SSH2_FXF_TRUNC 0x00000010
80#define SSH2_FXF_EXCL 0x00000020 80#define SSH2_FXF_EXCL 0x00000020
81 81
82/* statvfs@openssh.com f_flag flags */
83#define SSH2_FXE_STATVFS_ST_RDONLY 0x00000001
84#define SSH2_FXE_STATVFS_ST_NOSUID 0x00000002
85
82/* status messages */ 86/* status messages */
83#define SSH2_FX_OK 0 87#define SSH2_FX_OK 0
84#define SSH2_FX_EOF 1 88#define SSH2_FX_EOF 1
@@ -90,3 +94,8 @@
90#define SSH2_FX_CONNECTION_LOST 7 94#define SSH2_FX_CONNECTION_LOST 7
91#define SSH2_FX_OP_UNSUPPORTED 8 95#define SSH2_FX_OP_UNSUPPORTED 8
92#define SSH2_FX_MAX 8 96#define SSH2_FX_MAX 8
97
98struct passwd;
99
100int sftp_server_main(int, char **, struct passwd *);
101void sftp_server_cleanup_exit(int) __attribute__((noreturn));
diff --git a/ssh-add.0 b/ssh-add.0
index 210b2afda..3652bb5e5 100644
--- a/ssh-add.0
+++ b/ssh-add.0
@@ -103,4 +103,4 @@ AUTHORS
103 ated OpenSSH. Markus Friedl contributed the support for SSH protocol 103 ated OpenSSH. Markus Friedl contributed the support for SSH protocol
104 versions 1.5 and 2.0. 104 versions 1.5 and 2.0.
105 105
106OpenBSD 4.2 June 12, 2007 2 106OpenBSD 4.4 June 12, 2007 2
diff --git a/ssh-add.c b/ssh-add.c
index 4dc46f6db..7a43282f2 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.89 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.90 2007/09/09 11:38:01 sobrado 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,6 +42,7 @@
42#include <sys/param.h> 42#include <sys/param.h>
43 43
44#include <openssl/evp.h> 44#include <openssl/evp.h>
45#include "openbsd-compat/openssl-compat.h"
45 46
46#include <fcntl.h> 47#include <fcntl.h>
47#include <pwd.h> 48#include <pwd.h>
@@ -309,7 +310,7 @@ do_file(AuthenticationConnection *ac, int deleting, char *file)
309static void 310static void
310usage(void) 311usage(void)
311{ 312{
312 fprintf(stderr, "Usage: %s [options] [file ...]\n", __progname); 313 fprintf(stderr, "usage: %s [options] [file ...]\n", __progname);
313 fprintf(stderr, "Options:\n"); 314 fprintf(stderr, "Options:\n");
314 fprintf(stderr, " -l List fingerprints of all identities.\n"); 315 fprintf(stderr, " -l List fingerprints of all identities.\n");
315 fprintf(stderr, " -L List public key parameters of all identities.\n"); 316 fprintf(stderr, " -L List public key parameters of all identities.\n");
diff --git a/ssh-agent.0 b/ssh-agent.0
index 823456a26..90348a6b2 100644
--- a/ssh-agent.0
+++ b/ssh-agent.0
@@ -4,7 +4,7 @@ NAME
4 ssh-agent - authentication agent 4 ssh-agent - authentication agent
5 5
6SYNOPSIS 6SYNOPSIS
7 ssh-agent [-a bind_address] [-c | -s] [-t life] [-d] [command [args ...]] 7 ssh-agent [-c | -s] [-d] [-a bind_address] [-t life] [command [arg ...]]
8 ssh-agent [-c | -s] -k 8 ssh-agent [-c | -s] -k
9 9
10DESCRIPTION 10DESCRIPTION
@@ -24,12 +24,15 @@ DESCRIPTION
24 -c Generate C-shell commands on stdout. This is the default if 24 -c Generate C-shell commands on stdout. This is the default if
25 SHELL looks like it's a csh style of shell. 25 SHELL looks like it's a csh style of shell.
26 26
27 -s Generate Bourne shell commands on stdout. This is the default if 27 -d Debug mode. When this option is specified ssh-agent will not
28 SHELL does not look like it's a csh style of shell. 28 fork.
29 29
30 -k Kill the current agent (given by the SSH_AGENT_PID environment 30 -k Kill the current agent (given by the SSH_AGENT_PID environment
31 variable). 31 variable).
32 32
33 -s Generate Bourne shell commands on stdout. This is the default if
34 SHELL does not look like it's a csh style of shell.
35
33 -t life 36 -t life
34 Set a default value for the maximum lifetime of identities added 37 Set a default value for the maximum lifetime of identities added
35 to the agent. The lifetime may be specified in seconds or in a 38 to the agent. The lifetime may be specified in seconds or in a
@@ -37,9 +40,6 @@ DESCRIPTION
37 for an identity with ssh-add(1) overrides this value. Without 40 for an identity with ssh-add(1) overrides this value. Without
38 this option the default maximum lifetime is forever. 41 this option the default maximum lifetime is forever.
39 42
40 -d Debug mode. When this option is specified ssh-agent will not
41 fork.
42
43 If a commandline is given, this is executed as a subprocess of the agent. 43 If a commandline is given, this is executed as a subprocess of the agent.
44 When the command dies, so does the agent. 44 When the command dies, so does the agent.
45 45
@@ -114,4 +114,4 @@ AUTHORS
114 ated OpenSSH. Markus Friedl contributed the support for SSH protocol 114 ated OpenSSH. Markus Friedl contributed the support for SSH protocol
115 versions 1.5 and 2.0. 115 versions 1.5 and 2.0.
116 116
117OpenBSD 4.2 June 5, 2007 2 117OpenBSD 4.4 June 5, 2007 2
diff --git a/ssh-agent.1 b/ssh-agent.1
index 1b5a5bb2a..6a5dc62af 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-agent.1,v 1.45 2007/05/31 19:20:16 jmc Exp $ 1.\" $OpenBSD: ssh-agent.1,v 1.46 2007/09/09 11:38:01 sobrado 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,11 +42,11 @@
42.Nd authentication agent 42.Nd authentication agent
43.Sh SYNOPSIS 43.Sh SYNOPSIS
44.Nm ssh-agent 44.Nm ssh-agent
45.Op Fl a Ar bind_address
46.Op Fl c Li | Fl s 45.Op Fl c Li | Fl s
47.Op Fl t Ar life
48.Op Fl d 46.Op Fl d
49.Op Ar command Op Ar args ... 47.Op Fl a Ar bind_address
48.Op Fl t Ar life
49.Op Ar command Op Ar arg ...
50.Nm ssh-agent 50.Nm ssh-agent
51.Op Fl c Li | Fl s 51.Op Fl c Li | Fl s
52.Fl k 52.Fl k
@@ -77,16 +77,21 @@ Generate C-shell commands on
77This is the default if 77This is the default if
78.Ev SHELL 78.Ev SHELL
79looks like it's a csh style of shell. 79looks like it's a csh style of shell.
80.It Fl d
81Debug mode.
82When this option is specified
83.Nm
84will not fork.
85.It Fl k
86Kill the current agent (given by the
87.Ev SSH_AGENT_PID
88environment variable).
80.It Fl s 89.It Fl s
81Generate Bourne shell commands on 90Generate Bourne shell commands on
82.Dv stdout . 91.Dv stdout .
83This is the default if 92This is the default if
84.Ev SHELL 93.Ev SHELL
85does not look like it's a csh style of shell. 94does not look like it's a csh style of shell.
86.It Fl k
87Kill the current agent (given by the
88.Ev SSH_AGENT_PID
89environment variable).
90.It Fl t Ar life 95.It Fl t Ar life
91Set a default value for the maximum lifetime of identities added to the agent. 96Set a default value for the maximum lifetime of identities added to the agent.
92The lifetime may be specified in seconds or in a time format specified in 97The lifetime may be specified in seconds or in a time format specified in
@@ -95,11 +100,6 @@ A lifetime specified for an identity with
95.Xr ssh-add 1 100.Xr ssh-add 1
96overrides this value. 101overrides this value.
97Without this option the default maximum lifetime is forever. 102Without this option the default maximum lifetime is forever.
98.It Fl d
99Debug mode.
100When this option is specified
101.Nm
102will not fork.
103.El 103.El
104.Pp 104.Pp
105If a commandline is given, this is executed as a subprocess of the agent. 105If a commandline is given, this is executed as a subprocess of the agent.
diff --git a/ssh-agent.c b/ssh-agent.c
index c3d5e5a75..9123cfe6b 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.155 2007/03/19 12:16:42 dtucker Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.159 2008/06/28 14:05:15 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
@@ -51,6 +51,7 @@
51 51
52#include <openssl/evp.h> 52#include <openssl/evp.h>
53#include <openssl/md5.h> 53#include <openssl/md5.h>
54#include "openbsd-compat/openssl-compat.h"
54 55
55#include <errno.h> 56#include <errno.h>
56#include <fcntl.h> 57#include <fcntl.h>
@@ -311,6 +312,7 @@ process_sign_request2(SocketEntry *e)
311 u_char *blob, *data, *signature = NULL; 312 u_char *blob, *data, *signature = NULL;
312 u_int blen, dlen, slen = 0; 313 u_int blen, dlen, slen = 0;
313 extern int datafellows; 314 extern int datafellows;
315 int odatafellows;
314 int ok = -1, flags; 316 int ok = -1, flags;
315 Buffer msg; 317 Buffer msg;
316 Key *key; 318 Key *key;
@@ -321,6 +323,7 @@ process_sign_request2(SocketEntry *e)
321 data = buffer_get_string(&e->request, &dlen); 323 data = buffer_get_string(&e->request, &dlen);
322 324
323 flags = buffer_get_int(&e->request); 325 flags = buffer_get_int(&e->request);
326 odatafellows = datafellows;
324 if (flags & SSH_AGENT_OLD_SIGNATURE) 327 if (flags & SSH_AGENT_OLD_SIGNATURE)
325 datafellows = SSH_BUG_SIGBLOB; 328 datafellows = SSH_BUG_SIGBLOB;
326 329
@@ -346,6 +349,7 @@ process_sign_request2(SocketEntry *e)
346 xfree(blob); 349 xfree(blob);
347 if (signature != NULL) 350 if (signature != NULL)
348 xfree(signature); 351 xfree(signature);
352 datafellows = odatafellows;
349} 353}
350 354
351/* shared */ 355/* shared */
@@ -457,6 +461,7 @@ static void
457process_add_identity(SocketEntry *e, int version) 461process_add_identity(SocketEntry *e, int version)
458{ 462{
459 Idtab *tab = idtab_lookup(version); 463 Idtab *tab = idtab_lookup(version);
464 Identity *id;
460 int type, success = 0, death = 0, confirm = 0; 465 int type, success = 0, death = 0, confirm = 0;
461 char *type_name, *comment; 466 char *type_name, *comment;
462 Key *k = NULL; 467 Key *k = NULL;
@@ -524,9 +529,8 @@ process_add_identity(SocketEntry *e, int version)
524 xfree(comment); 529 xfree(comment);
525 goto send; 530 goto send;
526 } 531 }
527 success = 1;
528 while (buffer_len(&e->request)) { 532 while (buffer_len(&e->request)) {
529 switch (buffer_get_char(&e->request)) { 533 switch ((type = buffer_get_char(&e->request))) {
530 case SSH_AGENT_CONSTRAIN_LIFETIME: 534 case SSH_AGENT_CONSTRAIN_LIFETIME:
531 death = time(NULL) + buffer_get_int(&e->request); 535 death = time(NULL) + buffer_get_int(&e->request);
532 break; 536 break;
@@ -534,24 +538,29 @@ process_add_identity(SocketEntry *e, int version)
534 confirm = 1; 538 confirm = 1;
535 break; 539 break;
536 default: 540 default:
537 break; 541 error("process_add_identity: "
542 "Unknown constraint type %d", type);
543 xfree(comment);
544 key_free(k);
545 goto send;
538 } 546 }
539 } 547 }
548 success = 1;
540 if (lifetime && !death) 549 if (lifetime && !death)
541 death = time(NULL) + lifetime; 550 death = time(NULL) + lifetime;
542 if (lookup_identity(k, version) == NULL) { 551 if ((id = lookup_identity(k, version)) == NULL) {
543 Identity *id = xmalloc(sizeof(Identity)); 552 id = xmalloc(sizeof(Identity));
544 id->key = k; 553 id->key = k;
545 id->comment = comment;
546 id->death = death;
547 id->confirm = confirm;
548 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 554 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
549 /* Increment the number of identities. */ 555 /* Increment the number of identities. */
550 tab->nentries++; 556 tab->nentries++;
551 } else { 557 } else {
552 key_free(k); 558 key_free(k);
553 xfree(comment); 559 xfree(id->comment);
554 } 560 }
561 id->comment = comment;
562 id->death = death;
563 id->confirm = confirm;
555send: 564send:
556 buffer_put_int(&e->output, 1); 565 buffer_put_int(&e->output, 1);
557 buffer_put_char(&e->output, 566 buffer_put_char(&e->output,
@@ -602,10 +611,10 @@ no_identities(SocketEntry *e, u_int type)
602 611
603#ifdef SMARTCARD 612#ifdef SMARTCARD
604static void 613static void
605process_add_smartcard_key (SocketEntry *e) 614process_add_smartcard_key(SocketEntry *e)
606{ 615{
607 char *sc_reader_id = NULL, *pin; 616 char *sc_reader_id = NULL, *pin;
608 int i, version, success = 0, death = 0, confirm = 0; 617 int i, type, version, success = 0, death = 0, confirm = 0;
609 Key **keys, *k; 618 Key **keys, *k;
610 Identity *id; 619 Identity *id;
611 Idtab *tab; 620 Idtab *tab;
@@ -614,7 +623,7 @@ process_add_smartcard_key (SocketEntry *e)
614 pin = buffer_get_string(&e->request, NULL); 623 pin = buffer_get_string(&e->request, NULL);
615 624
616 while (buffer_len(&e->request)) { 625 while (buffer_len(&e->request)) {
617 switch (buffer_get_char(&e->request)) { 626 switch ((type = buffer_get_char(&e->request))) {
618 case SSH_AGENT_CONSTRAIN_LIFETIME: 627 case SSH_AGENT_CONSTRAIN_LIFETIME:
619 death = time(NULL) + buffer_get_int(&e->request); 628 death = time(NULL) + buffer_get_int(&e->request);
620 break; 629 break;
@@ -622,7 +631,11 @@ process_add_smartcard_key (SocketEntry *e)
622 confirm = 1; 631 confirm = 1;
623 break; 632 break;
624 default: 633 default:
625 break; 634 error("process_add_smartcard_key: "
635 "Unknown constraint type %d", type);
636 xfree(sc_reader_id);
637 xfree(pin);
638 goto send;
626 } 639 }
627 } 640 }
628 if (lifetime && !death) 641 if (lifetime && !death)
@@ -948,7 +961,8 @@ after_select(fd_set *readset, fd_set *writeset)
948 buffer_ptr(&sockets[i].output), 961 buffer_ptr(&sockets[i].output),
949 buffer_len(&sockets[i].output)); 962 buffer_len(&sockets[i].output));
950 if (len == -1 && (errno == EAGAIN || 963 if (len == -1 && (errno == EAGAIN ||
951 errno == EINTR)) 964 errno == EINTR ||
965 errno == EWOULDBLOCK))
952 continue; 966 continue;
953 break; 967 break;
954 } while (1); 968 } while (1);
@@ -962,7 +976,8 @@ after_select(fd_set *readset, fd_set *writeset)
962 do { 976 do {
963 len = read(sockets[i].fd, buf, sizeof(buf)); 977 len = read(sockets[i].fd, buf, sizeof(buf));
964 if (len == -1 && (errno == EAGAIN || 978 if (len == -1 && (errno == EAGAIN ||
965 errno == EINTR)) 979 errno == EINTR ||
980 errno == EWOULDBLOCK))
966 continue; 981 continue;
967 break; 982 break;
968 } while (1); 983 } while (1);
@@ -1016,7 +1031,7 @@ check_parent_exists(void)
1016static void 1031static void
1017usage(void) 1032usage(void)
1018{ 1033{
1019 fprintf(stderr, "Usage: %s [options] [command [args ...]]\n", 1034 fprintf(stderr, "usage: %s [options] [command [arg ...]]\n",
1020 __progname); 1035 __progname);
1021 fprintf(stderr, "Options:\n"); 1036 fprintf(stderr, "Options:\n");
1022 fprintf(stderr, " -c Generate C-shell commands on stdout.\n"); 1037 fprintf(stderr, " -c Generate C-shell commands on stdout.\n");
diff --git a/ssh-keygen.0 b/ssh-keygen.0
index 2f8ee264e..ca8b5cf8c 100644
--- a/ssh-keygen.0
+++ b/ssh-keygen.0
@@ -130,7 +130,9 @@ DESCRIPTION
130 130
131 -l Show fingerprint of specified public key file. Private RSA1 keys 131 -l Show fingerprint of specified public key file. Private RSA1 keys
132 are also supported. For RSA and DSA keys ssh-keygen tries to 132 are also supported. For RSA and DSA keys ssh-keygen tries to
133 find the matching public key file and prints its fingerprint. 133 find the matching public key file and prints its fingerprint. If
134 combined with -v, an ASCII art representation of the key is sup-
135 plied with the fingerprint.
134 136
135 -M memory 137 -M memory
136 Specify the amount of memory to use (in megabytes) when generat- 138 Specify the amount of memory to use (in megabytes) when generat-
@@ -284,4 +286,4 @@ AUTHORS
284 created OpenSSH. Markus Friedl contributed the support for SSH protocol 286 created OpenSSH. Markus Friedl contributed the support for SSH protocol
285 versions 1.5 and 2.0. 287 versions 1.5 and 2.0.
286 288
287OpenBSD 4.2 June 5, 2007 5 289OpenBSD 4.4 June 12, 2008 5
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 4e629de74..3fff59e77 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.75 2007/05/31 19:20:16 jmc Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.78 2008/06/12 19:10:09 jmc Exp $
2.\" 2.\"
3.\" -*- nroff -*- 3.\" -*- nroff -*-
4.\" 4.\"
@@ -37,7 +37,7 @@
37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39.\" 39.\"
40.Dd $Mdocdate: June 5 2007 $ 40.Dd $Mdocdate: June 12 2008 $
41.Dt SSH-KEYGEN 1 41.Dt SSH-KEYGEN 1
42.Os 42.Os
43.Sh NAME 43.Sh NAME
@@ -262,6 +262,9 @@ Private RSA1 keys are also supported.
262For RSA and DSA keys 262For RSA and DSA keys
263.Nm 263.Nm
264tries to find the matching public key file and prints its fingerprint. 264tries to find the matching public key file and prints its fingerprint.
265If combined with
266.Fl v ,
267an ASCII art representation of the key is supplied with the fingerprint.
265.It Fl M Ar memory 268.It Fl M Ar memory
266Specify the amount of memory to use (in megabytes) when generating 269Specify the amount of memory to use (in megabytes) when generating
267candidate moduli for DH-GEX. 270candidate moduli for DH-GEX.
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 04a9b939a..f7e284062 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.160 2007/01/21 01:41:54 stevesk Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.171 2008/07/13 21:22:52 sthen 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
@@ -21,6 +21,7 @@
21 21
22#include <openssl/evp.h> 22#include <openssl/evp.h>
23#include <openssl/pem.h> 23#include <openssl/pem.h>
24#include "openbsd-compat/openssl-compat.h"
24 25
25#include <errno.h> 26#include <errno.h>
26#include <fcntl.h> 27#include <fcntl.h>
@@ -71,6 +72,8 @@ int change_comment = 0;
71 72
72int quiet = 0; 73int quiet = 0;
73 74
75int log_level = SYSLOG_LEVEL_INFO;
76
74/* Flag indicating that we want to hash a known_hosts file */ 77/* Flag indicating that we want to hash a known_hosts file */
75int hash_hosts = 0; 78int hash_hosts = 0;
76/* Flag indicating that we want lookup a host in known_hosts file */ 79/* Flag indicating that we want lookup a host in known_hosts file */
@@ -141,8 +144,7 @@ ask_filename(struct passwd *pw, const char *prompt)
141 fprintf(stderr, "%s (%s): ", prompt, identity_file); 144 fprintf(stderr, "%s (%s): ", prompt, identity_file);
142 if (fgets(buf, sizeof(buf), stdin) == NULL) 145 if (fgets(buf, sizeof(buf), stdin) == NULL)
143 exit(1); 146 exit(1);
144 if (strchr(buf, '\n')) 147 buf[strcspn(buf, "\n")] = '\0';
145 *strchr(buf, '\n') = 0;
146 if (strcmp(buf, "") != 0) 148 if (strcmp(buf, "") != 0)
147 strlcpy(identity_file, buf, sizeof(identity_file)); 149 strlcpy(identity_file, buf, sizeof(identity_file));
148 have_identity = 1; 150 have_identity = 1;
@@ -504,8 +506,8 @@ do_fingerprint(struct passwd *pw)
504{ 506{
505 FILE *f; 507 FILE *f;
506 Key *public; 508 Key *public;
507 char *comment = NULL, *cp, *ep, line[16*1024], *fp; 509 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
508 int i, skip = 0, num = 1, invalid = 1; 510 int i, skip = 0, num = 0, invalid = 1;
509 enum fp_rep rep; 511 enum fp_rep rep;
510 enum fp_type fptype; 512 enum fp_type fptype;
511 struct stat st; 513 struct stat st;
@@ -522,9 +524,14 @@ do_fingerprint(struct passwd *pw)
522 public = key_load_public(identity_file, &comment); 524 public = key_load_public(identity_file, &comment);
523 if (public != NULL) { 525 if (public != NULL) {
524 fp = key_fingerprint(public, fptype, rep); 526 fp = key_fingerprint(public, fptype, rep);
525 printf("%u %s %s\n", key_size(public), fp, comment); 527 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
528 printf("%u %s %s (%s)\n", key_size(public), fp, comment,
529 key_type(public));
530 if (log_level >= SYSLOG_LEVEL_VERBOSE)
531 printf("%s\n", ra);
526 key_free(public); 532 key_free(public);
527 xfree(comment); 533 xfree(comment);
534 xfree(ra);
528 xfree(fp); 535 xfree(fp);
529 exit(0); 536 exit(0);
530 } 537 }
@@ -536,9 +543,9 @@ do_fingerprint(struct passwd *pw)
536 f = fopen(identity_file, "r"); 543 f = fopen(identity_file, "r");
537 if (f != NULL) { 544 if (f != NULL) {
538 while (fgets(line, sizeof(line), f)) { 545 while (fgets(line, sizeof(line), f)) {
539 i = strlen(line) - 1; 546 if ((cp = strchr(line, '\n')) == NULL) {
540 if (line[i] != '\n') { 547 error("line %d too long: %.40s...",
541 error("line %d too long: %.40s...", num, line); 548 num + 1, line);
542 skip = 1; 549 skip = 1;
543 continue; 550 continue;
544 } 551 }
@@ -547,7 +554,7 @@ do_fingerprint(struct passwd *pw)
547 skip = 0; 554 skip = 0;
548 continue; 555 continue;
549 } 556 }
550 line[i] = '\0'; 557 *cp = '\0';
551 558
552 /* Skip leading whitespace, empty and comment lines. */ 559 /* Skip leading whitespace, empty and comment lines. */
553 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 560 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@@ -582,8 +589,12 @@ do_fingerprint(struct passwd *pw)
582 } 589 }
583 comment = *cp ? cp : comment; 590 comment = *cp ? cp : comment;
584 fp = key_fingerprint(public, fptype, rep); 591 fp = key_fingerprint(public, fptype, rep);
585 printf("%u %s %s\n", key_size(public), fp, 592 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
586 comment ? comment : "no comment"); 593 printf("%u %s %s (%s)\n", key_size(public), fp,
594 comment ? comment : "no comment", key_type(public));
595 if (log_level >= SYSLOG_LEVEL_VERBOSE)
596 printf("%s\n", ra);
597 xfree(ra);
587 xfree(fp); 598 xfree(fp);
588 key_free(public); 599 key_free(public);
589 invalid = 0; 600 invalid = 0;
@@ -598,14 +609,31 @@ do_fingerprint(struct passwd *pw)
598} 609}
599 610
600static void 611static void
601print_host(FILE *f, char *name, Key *public, int hash) 612print_host(FILE *f, const char *name, Key *public, int hash)
602{ 613{
603 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 614 if (print_fingerprint) {
604 fatal("hash_host failed"); 615 enum fp_rep rep;
605 fprintf(f, "%s ", name); 616 enum fp_type fptype;
606 if (!key_write(public, f)) 617 char *fp, *ra;
607 fatal("key_write failed"); 618
608 fprintf(f, "\n"); 619 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
620 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
621 fp = key_fingerprint(public, fptype, rep);
622 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
623 printf("%u %s %s (%s)\n", key_size(public), fp, name,
624 key_type(public));
625 if (log_level >= SYSLOG_LEVEL_VERBOSE)
626 printf("%s\n", ra);
627 xfree(ra);
628 xfree(fp);
629 } else {
630 if (hash && (name = host_hash(name, NULL, 0)) == NULL)
631 fatal("hash_host failed");
632 fprintf(f, "%s ", name);
633 if (!key_write(public, f))
634 fatal("key_write failed");
635 fprintf(f, "\n");
636 }
609} 637}
610 638
611static void 639static void
@@ -615,7 +643,7 @@ do_known_hosts(struct passwd *pw, const char *name)
615 Key *public; 643 Key *public;
616 char *cp, *cp2, *kp, *kp2; 644 char *cp, *cp2, *kp, *kp2;
617 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; 645 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
618 int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; 646 int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
619 647
620 if (!have_identity) { 648 if (!have_identity) {
621 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 649 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@@ -650,19 +678,18 @@ do_known_hosts(struct passwd *pw, const char *name)
650 } 678 }
651 679
652 while (fgets(line, sizeof(line), in)) { 680 while (fgets(line, sizeof(line), in)) {
653 num++; 681 if ((cp = strchr(line, '\n')) == NULL) {
654 i = strlen(line) - 1; 682 error("line %d too long: %.40s...", num + 1, line);
655 if (line[i] != '\n') {
656 error("line %d too long: %.40s...", num, line);
657 skip = 1; 683 skip = 1;
658 invalid = 1; 684 invalid = 1;
659 continue; 685 continue;
660 } 686 }
687 num++;
661 if (skip) { 688 if (skip) {
662 skip = 0; 689 skip = 0;
663 continue; 690 continue;
664 } 691 }
665 line[i] = '\0'; 692 *cp = '\0';
666 693
667 /* Skip leading whitespace, empty and comment lines. */ 694 /* Skip leading whitespace, empty and comment lines. */
668 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 695 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@@ -726,7 +753,8 @@ do_known_hosts(struct passwd *pw, const char *name)
726 printf("# Host %s found: " 753 printf("# Host %s found: "
727 "line %d type %s\n", name, 754 "line %d type %s\n", name,
728 num, key_type(public)); 755 num, key_type(public));
729 print_host(out, cp, public, hash_hosts); 756 print_host(out, name, public,
757 hash_hosts);
730 } 758 }
731 if (delete_host && !c) 759 if (delete_host && !c)
732 print_host(out, cp, public, 0); 760 print_host(out, cp, public, 0);
@@ -750,7 +778,7 @@ do_known_hosts(struct passwd *pw, const char *name)
750 fclose(in); 778 fclose(in);
751 779
752 if (invalid) { 780 if (invalid) {
753 fprintf(stderr, "%s is not a valid known_host file.\n", 781 fprintf(stderr, "%s is not a valid known_hosts file.\n",
754 identity_file); 782 identity_file);
755 if (inplace) { 783 if (inplace) {
756 fprintf(stderr, "Not replacing existing known_hosts " 784 fprintf(stderr, "Not replacing existing known_hosts "
@@ -962,8 +990,7 @@ do_change_comment(struct passwd *pw)
962 key_free(private); 990 key_free(private);
963 exit(1); 991 exit(1);
964 } 992 }
965 if (strchr(new_comment, '\n')) 993 new_comment[strcspn(new_comment, "\n")] = '\0';
966 *strchr(new_comment, '\n') = 0;
967 } 994 }
968 995
969 /* Save the file using the new passphrase. */ 996 /* Save the file using the new passphrase. */
@@ -1006,7 +1033,7 @@ do_change_comment(struct passwd *pw)
1006static void 1033static void
1007usage(void) 1034usage(void)
1008{ 1035{
1009 fprintf(stderr, "Usage: %s [options]\n", __progname); 1036 fprintf(stderr, "usage: %s [options]\n", __progname);
1010 fprintf(stderr, "Options:\n"); 1037 fprintf(stderr, "Options:\n");
1011 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); 1038 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n");
1012 fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); 1039 fprintf(stderr, " -B Show bubblebabble digest of key file.\n");
@@ -1059,7 +1086,6 @@ main(int argc, char **argv)
1059 int opt, type, fd, download = 0; 1086 int opt, type, fd, download = 0;
1060 u_int32_t memory = 0, generator_wanted = 0, trials = 100; 1087 u_int32_t memory = 0, generator_wanted = 0, trials = 100;
1061 int do_gen_candidates = 0, do_screen_candidates = 0; 1088 int do_gen_candidates = 0, do_screen_candidates = 0;
1062 int log_level = SYSLOG_LEVEL_INFO;
1063 BIGNUM *start = NULL; 1089 BIGNUM *start = NULL;
1064 FILE *f; 1090 FILE *f;
1065 const char *errstr; 1091 const char *errstr;
@@ -1232,6 +1258,10 @@ main(int argc, char **argv)
1232 printf("Can only have one of -p and -c.\n"); 1258 printf("Can only have one of -p and -c.\n");
1233 usage(); 1259 usage();
1234 } 1260 }
1261 if (print_fingerprint && (delete_host || hash_hosts)) {
1262 printf("Cannot use -l with -D or -R.\n");
1263 usage();
1264 }
1235 if (delete_host || hash_hosts || find_host) 1265 if (delete_host || hash_hosts || find_host)
1236 do_known_hosts(pw, rr_hostname); 1266 do_known_hosts(pw, rr_hostname);
1237 if (print_fingerprint || print_bubblebabble) 1267 if (print_fingerprint || print_bubblebabble)
@@ -1436,10 +1466,15 @@ passphrase_again:
1436 1466
1437 if (!quiet) { 1467 if (!quiet) {
1438 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 1468 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
1469 char *ra = key_fingerprint(public, SSH_FP_MD5,
1470 SSH_FP_RANDOMART);
1439 printf("Your public key has been saved in %s.\n", 1471 printf("Your public key has been saved in %s.\n",
1440 identity_file); 1472 identity_file);
1441 printf("The key fingerprint is:\n"); 1473 printf("The key fingerprint is:\n");
1442 printf("%s %s\n", fp, comment); 1474 printf("%s %s\n", fp, comment);
1475 printf("The key's randomart image is:\n");
1476 printf("%s\n", ra);
1477 xfree(ra);
1443 xfree(fp); 1478 xfree(fp);
1444 } 1479 }
1445 1480
diff --git a/ssh-keyscan.0 b/ssh-keyscan.0
index 64d23c436..5cd68816c 100644
--- a/ssh-keyscan.0
+++ b/ssh-keyscan.0
@@ -50,7 +50,7 @@ DESCRIPTION
50 The possible values are ``rsa1'' for protocol version 1 and 50 The possible values are ``rsa1'' for protocol version 1 and
51 ``rsa'' or ``dsa'' for protocol version 2. Multiple values may 51 ``rsa'' or ``dsa'' for protocol version 2. Multiple values may
52 be specified by separating them with commas. The default is 52 be specified by separating them with commas. The default is
53 ``rsa1''. 53 ``rsa''.
54 54
55 -v Verbose mode. Causes ssh-keyscan to print debugging messages 55 -v Verbose mode. Causes ssh-keyscan to print debugging messages
56 about its progress. 56 about its progress.
@@ -104,4 +104,4 @@ BUGS
104 This is because it opens a connection to the ssh port, reads the public 104 This is because it opens a connection to the ssh port, reads the public
105 key, and drops the connection as soon as it gets the key. 105 key, and drops the connection as soon as it gets the key.
106 106
107OpenBSD 4.2 June 5, 2007 2 107OpenBSD 4.4 April 30, 2008 2
diff --git a/ssh-keyscan.1 b/ssh-keyscan.1
index 005e57a2b..8a4f3bcba 100644
--- a/ssh-keyscan.1
+++ b/ssh-keyscan.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keyscan.1,v 1.23 2007/05/31 19:20:16 jmc Exp $ 1.\" $OpenBSD: ssh-keyscan.1,v 1.24 2008/04/30 10:14:03 djm 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: June 5 2007 $ 9.Dd $Mdocdate: April 30 2008 $
10.Dt SSH-KEYSCAN 1 10.Dt SSH-KEYSCAN 1
11.Os 11.Os
12.Sh NAME 12.Sh NAME
@@ -94,7 +94,7 @@ or
94for protocol version 2. 94for protocol version 2.
95Multiple values may be specified by separating them with commas. 95Multiple values may be specified by separating them with commas.
96The default is 96The default is
97.Dq rsa1 . 97.Dq rsa .
98.It Fl v 98.It Fl v
99Verbose mode. 99Verbose mode.
100Causes 100Causes
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index b19864007..d81077764 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keyscan.c,v 1.74 2006/10/06 02:29:19 djm Exp $ */ 1/* $OpenBSD: ssh-keyscan.c,v 1.76 2008/04/30 10:14:03 djm 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 *
@@ -56,7 +56,7 @@ int ssh_port = SSH_DEFAULT_PORT;
56#define KT_DSA 2 56#define KT_DSA 2
57#define KT_RSA 4 57#define KT_RSA 4
58 58
59int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */ 59int get_keytypes = KT_RSA; /* Get only RSA keys by default */
60 60
61int hash_hosts = 0; /* Hash hostname on output */ 61int hash_hosts = 0; /* Hash hostname on output */
62 62
@@ -410,7 +410,7 @@ tcpconnect(char *host)
410 hints.ai_family = IPv4or6; 410 hints.ai_family = IPv4or6;
411 hints.ai_socktype = SOCK_STREAM; 411 hints.ai_socktype = SOCK_STREAM;
412 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) 412 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
413 fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr)); 413 fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr));
414 for (ai = aitop; ai; ai = ai->ai_next) { 414 for (ai = aitop; ai; ai = ai->ai_next) {
415 s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 415 s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
416 if (s < 0) { 416 if (s < 0) {
@@ -656,7 +656,7 @@ conloop(void)
656 memcpy(e, read_wait, read_wait_nfdset * sizeof(fd_mask)); 656 memcpy(e, read_wait, read_wait_nfdset * sizeof(fd_mask));
657 657
658 while (select(maxfd, r, NULL, e, &seltime) == -1 && 658 while (select(maxfd, r, NULL, e, &seltime) == -1 &&
659 (errno == EAGAIN || errno == EINTR)) 659 (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
660 ; 660 ;
661 661
662 for (i = 0; i < maxfd; i++) { 662 for (i = 0; i < maxfd; i++) {
diff --git a/ssh-keysign.0 b/ssh-keysign.0
index 32d3c6a7a..07ffeca5c 100644
--- a/ssh-keysign.0
+++ b/ssh-keysign.0
@@ -39,4 +39,4 @@ HISTORY
39AUTHORS 39AUTHORS
40 Markus Friedl <markus@openbsd.org> 40 Markus Friedl <markus@openbsd.org>
41 41
42OpenBSD 4.2 June 5, 2007 1 42OpenBSD 4.4 May 31, 2007 1
diff --git a/ssh-keysign.8 b/ssh-keysign.8
index 814bcb66e..3ba54b935 100644
--- a/ssh-keysign.8
+++ b/ssh-keysign.8
@@ -22,7 +22,7 @@
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\" 24.\"
25.Dd $Mdocdate: June 5 2007 $ 25.Dd $Mdocdate: May 31 2007 $
26.Dt SSH-KEYSIGN 8 26.Dt SSH-KEYSIGN 8
27.Os 27.Os
28.Sh NAME 28.Sh NAME
diff --git a/ssh-rand-helper.0 b/ssh-rand-helper.0
index 131e0bf3a..e1d31c1cd 100644
--- a/ssh-rand-helper.0
+++ b/ssh-rand-helper.0
@@ -48,4 +48,4 @@ AUTHORS
48SEE ALSO 48SEE ALSO
49 ssh(1), ssh-add(1), ssh-keygen(1), sshd(8) 49 ssh(1), ssh-add(1), ssh-keygen(1), sshd(8)
50 50
51OpenBSD 4.2 April 14, 2002 1 51OpenBSD 4.4 April 14, 2002 1
diff --git a/ssh.0 b/ssh.0
index 8ec0bb397..21e5ac9a3 100644
--- a/ssh.0
+++ b/ssh.0
@@ -130,6 +130,11 @@ DESCRIPTION
130 The recommended way to start X11 programs at a remote site is 130 The recommended way to start X11 programs at a remote site is
131 with something like ssh -f host xterm. 131 with something like ssh -f host xterm.
132 132
133 If the ExitOnForwardFailure configuration option is set to
134 ``yes'', then a client started with -f will wait for all remote
135 port forwards to be successfully established before placing it-
136 self in the background.
137
133 -g Allows remote hosts to connect to local forwarded ports. 138 -g Allows remote hosts to connect to local forwarded ports.
134 139
135 -I smartcard_device 140 -I smartcard_device
@@ -274,13 +279,14 @@ DESCRIPTION
274 User 279 User
275 UserKnownHostsFile 280 UserKnownHostsFile
276 VerifyHostKeyDNS 281 VerifyHostKeyDNS
282 VisualHostKey
277 XAuthLocation 283 XAuthLocation
278 284
279 -p port 285 -p port
280 Port to connect to on the remote host. This can be specified on 286 Port to connect to on the remote host. This can be specified on
281 a per-host basis in the configuration file. 287 a per-host basis in the configuration file.
282 288
283 -q Quiet mode. Causes all warning and diagnostic messages to be 289 -q Quiet mode. Causes most warning and diagnostic messages to be
284 suppressed. 290 suppressed.
285 291
286 -R [bind_address:]port:host:hostport 292 -R [bind_address:]port:host:hostport
@@ -571,12 +577,27 @@ VERIFYING HOST KEYS
571 577
572 $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key 578 $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
573 579
574 If the fingerprint is already known, it can be matched and verified, and 580 If the fingerprint is already known, it can be matched and the key can be
575 the key can be accepted. If the fingerprint is unknown, an alternative 581 accepted or rejected. Because of the difficulty of comparing host keys
576 method of verification is available: SSH fingerprints verified by DNS. 582 just by looking at hex strings, there is also support to compare host
577 An additional resource record (RR), SSHFP, is added to a zonefile and the 583 keys visually, using random art. By setting the VisualHostKey option to
578 connecting client is able to match the fingerprint with that of the key 584 ``yes'', a small ASCII graphic gets displayed on every login to a server,
579 presented. 585 no matter if the session itself is interactive or not. By learning the
586 pattern a known server produces, a user can easily find out that the host
587 key has changed when a completely different pattern is displayed. Be-
588 cause these patterns are not unambiguous however, a pattern that looks
589 similar to the pattern remembered only gives a good probability that the
590 host key is the same, not guaranteed proof.
591
592 To get a listing of the fingerprints along with their random art for all
593 known hosts, the following command line can be used:
594
595 $ ssh-keygen -lv -f ~/.ssh/known_hosts
596
597 If the fingerprint is unknown, an alternative method of verification is
598 available: SSH fingerprints verified by DNS. An additional resource
599 record (RR), SSHFP, is added to a zonefile and the connecting client is
600 able to match the fingerprint with that of the key presented.
580 601
581 In this example, we are connecting a client to a server, 602 In this example, we are connecting a client to a server,
582 ``host.example.com''. The SSHFP resource records should first be added 603 ``host.example.com''. The SSHFP resource records should first be added
@@ -714,6 +735,13 @@ FILES
714 host-based authentication without permitting login with 735 host-based authentication without permitting login with
715 rlogin/rsh. 736 rlogin/rsh.
716 737
738 ~/.ssh/
739 This directory is the default location for all user-specific con-
740 figuration and authentication information. There is no general
741 requirement to keep the entire contents of this directory secret,
742 but the recommended permissions are read/write/execute for the
743 user, and not accessible by others.
744
717 ~/.ssh/authorized_keys 745 ~/.ssh/authorized_keys
718 Lists the public keys (RSA/DSA) that can be used for logging in 746 Lists the public keys (RSA/DSA) that can be used for logging in
719 as this user. The format of this file is described in the 747 as this user. The format of this file is described in the
@@ -825,6 +853,10 @@ SEE ALSO
825 853
826 The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006. 854 The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006.
827 855
856 A. Perrig and D. Song, Hash Visualization: a New Technique to improve
857 Real-World Security, 1999, International Workshop on Cryptographic
858 Techniques and E-Commerce (CrypTEC '99).
859
828AUTHORS 860AUTHORS
829 OpenSSH is a derivative of the original and free ssh 1.2.12 release by 861 OpenSSH is a derivative of the original and free ssh 1.2.12 release by
830 Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo 862 Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo
@@ -832,4 +864,4 @@ AUTHORS
832 created OpenSSH. Markus Friedl contributed the support for SSH protocol 864 created OpenSSH. Markus Friedl contributed the support for SSH protocol
833 versions 1.5 and 2.0. 865 versions 1.5 and 2.0.
834 866
835OpenBSD 4.2 June 12, 2007 13 867OpenBSD 4.4 July 2, 2008 14
diff --git a/ssh.1 b/ssh.1
index 1bf6b5e1c..1883578f2 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh.1,v 1.270 2007/06/12 13:43:55 jmc Exp $ 37.\" $OpenBSD: ssh.1,v 1.277 2008/07/02 13:47:39 djm Exp $
38.Dd $Mdocdate: June 12 2007 $ 38.Dd $Mdocdate: July 2 2008 $
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -290,6 +290,15 @@ This implies
290The recommended way to start X11 programs at a remote site is with 290The recommended way to start X11 programs at a remote site is with
291something like 291something like
292.Ic ssh -f host xterm . 292.Ic ssh -f host xterm .
293.Pp
294If the
295.Cm ExitOnForwardFailure
296configuration option is set to
297.Dq yes ,
298then a client started with
299.Fl f
300will wait for all remote port forwards to be successfully established
301before placing itself in the background.
293.It Fl g 302.It Fl g
294Allows remote hosts to connect to local forwarded ports. 303Allows remote hosts to connect to local forwarded ports.
295.It Fl I Ar smartcard_device 304.It Fl I Ar smartcard_device
@@ -498,6 +507,7 @@ For full details of the options listed below, and their possible values, see
498.It User 507.It User
499.It UserKnownHostsFile 508.It UserKnownHostsFile
500.It VerifyHostKeyDNS 509.It VerifyHostKeyDNS
510.It VisualHostKey
501.It XAuthLocation 511.It XAuthLocation
502.El 512.El
503.It Fl p Ar port 513.It Fl p Ar port
@@ -506,7 +516,7 @@ This can be specified on a
506per-host basis in the configuration file. 516per-host basis in the configuration file.
507.It Fl q 517.It Fl q
508Quiet mode. 518Quiet mode.
509Causes all warning and diagnostic messages to be suppressed. 519Causes most warning and diagnostic messages to be suppressed.
510.It Fl R Xo 520.It Fl R Xo
511.Sm off 521.Sm off
512.Oo Ar bind_address : Oc 522.Oo Ar bind_address : Oc
@@ -1027,9 +1037,31 @@ Fingerprints can be determined using
1027.Pp 1037.Pp
1028.Dl $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key 1038.Dl $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
1029.Pp 1039.Pp
1030If the fingerprint is already known, 1040If the fingerprint is already known, it can be matched
1031it can be matched and verified, 1041and the key can be accepted or rejected.
1032and the key can be accepted. 1042Because of the difficulty of comparing host keys
1043just by looking at hex strings,
1044there is also support to compare host keys visually,
1045using
1046.Em random art .
1047By setting the
1048.Cm VisualHostKey
1049option to
1050.Dq yes ,
1051a small ASCII graphic gets displayed on every login to a server, no matter
1052if the session itself is interactive or not.
1053By learning the pattern a known server produces, a user can easily
1054find out that the host key has changed when a completely different pattern
1055is displayed.
1056Because these patterns are not unambiguous however, a pattern that looks
1057similar to the pattern remembered only gives a good probability that the
1058host key is the same, not guaranteed proof.
1059.Pp
1060To get a listing of the fingerprints along with their random art for
1061all known hosts, the following command line can be used:
1062.Pp
1063.Dl $ ssh-keygen -lv -f ~/.ssh/known_hosts
1064.Pp
1033If the fingerprint is unknown, 1065If the fingerprint is unknown,
1034an alternative method of verification is available: 1066an alternative method of verification is available:
1035SSH fingerprints verified by DNS. 1067SSH fingerprints verified by DNS.
@@ -1245,6 +1277,13 @@ This file is used in exactly the same way as
1245but allows host-based authentication without permitting login with 1277but allows host-based authentication without permitting login with
1246rlogin/rsh. 1278rlogin/rsh.
1247.Pp 1279.Pp
1280.It ~/.ssh/
1281This directory is the default location for all user-specific configuration
1282and authentication information.
1283There is no general requirement to keep the entire contents of this directory
1284secret, but the recommended permissions are read/write/execute for the user,
1285and not accessible by others.
1286.Pp
1248.It ~/.ssh/authorized_keys 1287.It ~/.ssh/authorized_keys
1249Lists the public keys (RSA/DSA) that can be used for logging in as this user. 1288Lists the public keys (RSA/DSA) that can be used for logging in as this user.
1250The format of this file is described in the 1289The format of this file is described in the
@@ -1426,6 +1465,13 @@ manual page for more information.
1426.%T "The Secure Shell (SSH) Public Key File Format" 1465.%T "The Secure Shell (SSH) Public Key File Format"
1427.%D 2006 1466.%D 2006
1428.Re 1467.Re
1468.Rs
1469.%T "Hash Visualization: a New Technique to improve Real-World Security"
1470.%A A. Perrig
1471.%A D. Song
1472.%D 1999
1473.%O "International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99)"
1474.Re
1429.Sh AUTHORS 1475.Sh AUTHORS
1430OpenSSH is a derivative of the original and free 1476OpenSSH is a derivative of the original and free
1431ssh 1.2.12 release by Tatu Ylonen. 1477ssh 1.2.12 release by Tatu Ylonen.
diff --git a/ssh.c b/ssh.c
index d3a7ffc9b..e2dd67d68 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.301 2007/08/07 07:32:53 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.318 2008/07/02 13:47:39 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,6 @@
49#include <sys/resource.h> 49#include <sys/resource.h>
50#include <sys/ioctl.h> 50#include <sys/ioctl.h>
51#include <sys/socket.h> 51#include <sys/socket.h>
52#include <sys/un.h>
53 52
54#include <ctype.h> 53#include <ctype.h>
55#include <errno.h> 54#include <errno.h>
@@ -72,6 +71,8 @@
72 71
73#include <openssl/evp.h> 72#include <openssl/evp.h>
74#include <openssl/err.h> 73#include <openssl/err.h>
74#include "openbsd-compat/openssl-compat.h"
75#include "openbsd-compat/sys-queue.h"
75 76
76#include "xmalloc.h" 77#include "xmalloc.h"
77#include "ssh.h" 78#include "ssh.h"
@@ -97,7 +98,6 @@
97#include "sshpty.h" 98#include "sshpty.h"
98#include "match.h" 99#include "match.h"
99#include "msg.h" 100#include "msg.h"
100#include "monitor_fdpass.h"
101#include "uidswap.h" 101#include "uidswap.h"
102#include "version.h" 102#include "version.h"
103 103
@@ -107,7 +107,7 @@
107 107
108extern char *__progname; 108extern char *__progname;
109 109
110/* Flag indicating whether debug mode is on. This can be set on the command line. */ 110/* Flag indicating whether debug mode is on. May be set on the command line. */
111int debug_flag = 0; 111int debug_flag = 0;
112 112
113/* Flag indicating whether a tty should be allocated */ 113/* Flag indicating whether a tty should be allocated */
@@ -164,20 +164,14 @@ Buffer command;
164int subsystem_flag = 0; 164int subsystem_flag = 0;
165 165
166/* # of replies received for global requests */ 166/* # of replies received for global requests */
167static int client_global_request_id = 0; 167static int remote_forward_confirms_received = 0;
168 168
169/* pid of proxycommand child process */ 169/* pid of proxycommand child process */
170pid_t proxy_command_pid = 0; 170pid_t proxy_command_pid = 0;
171 171
172/* fd to control socket */ 172/* mux.c */
173int control_fd = -1; 173extern int muxserver_sock;
174 174extern u_int muxclient_command;
175/* Multiplexing control command */
176static u_int mux_command = 0;
177
178/* Only used in control client mode */
179volatile sig_atomic_t control_client_terminate = 0;
180u_int control_server_pid = 0;
181 175
182/* Prints a help message to the user. This function never returns. */ 176/* Prints a help message to the user. This function never returns. */
183 177
@@ -198,7 +192,10 @@ usage(void)
198static int ssh_session(void); 192static int ssh_session(void);
199static int ssh_session2(void); 193static int ssh_session2(void);
200static void load_public_identity_files(void); 194static void load_public_identity_files(void);
201static void control_client(const char *path); 195
196/* from muxclient.c */
197void muxclient(const char *);
198void muxserver_listen(void);
202 199
203/* 200/*
204 * Main program for the ssh client. 201 * Main program for the ssh client.
@@ -210,7 +207,7 @@ main(int ac, char **av)
210 char *p, *cp, *line, buf[256]; 207 char *p, *cp, *line, buf[256];
211 struct stat st; 208 struct stat st;
212 struct passwd *pw; 209 struct passwd *pw;
213 int dummy; 210 int dummy, timeout_ms;
214 extern int optind, optreset; 211 extern int optind, optreset;
215 extern char *optarg; 212 extern char *optarg;
216 struct servent *sp; 213 struct servent *sp;
@@ -264,15 +261,18 @@ main(int ac, char **av)
264 */ 261 */
265 umask(022); 262 umask(022);
266 263
267 /* Initialize option structure to indicate that no values have been set. */ 264 /*
265 * Initialize option structure to indicate that no values have been
266 * set.
267 */
268 initialize_options(&options); 268 initialize_options(&options);
269 269
270 /* Parse command-line arguments. */ 270 /* Parse command-line arguments. */
271 host = NULL; 271 host = NULL;
272 272
273 again: 273 again:
274 while ((opt = getopt(ac, av, 274 while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
275 "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) { 275 "ACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) {
276 switch (opt) { 276 switch (opt) {
277 case '1': 277 case '1':
278 options.protocol = SSH_PROTO_1; 278 options.protocol = SSH_PROTO_1;
@@ -308,9 +308,9 @@ main(int ac, char **av)
308 break; 308 break;
309 case 'O': 309 case 'O':
310 if (strcmp(optarg, "check") == 0) 310 if (strcmp(optarg, "check") == 0)
311 mux_command = SSHMUX_COMMAND_ALIVE_CHECK; 311 muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
312 else if (strcmp(optarg, "exit") == 0) 312 else if (strcmp(optarg, "exit") == 0)
313 mux_command = SSHMUX_COMMAND_TERMINATE; 313 muxclient_command = SSHMUX_COMMAND_TERMINATE;
314 else 314 else
315 fatal("Invalid multiplex command."); 315 fatal("Invalid multiplex command.");
316 break; 316 break;
@@ -377,7 +377,8 @@ main(int ac, char **av)
377 options.tun_open = SSH_TUNMODE_DEFAULT; 377 options.tun_open = SSH_TUNMODE_DEFAULT;
378 options.tun_local = a2tun(optarg, &options.tun_remote); 378 options.tun_local = a2tun(optarg, &options.tun_remote);
379 if (options.tun_local == SSH_TUNID_ERR) { 379 if (options.tun_local == SSH_TUNID_ERR) {
380 fprintf(stderr, "Bad tun device '%s'\n", optarg); 380 fprintf(stderr,
381 "Bad tun device '%s'\n", optarg);
381 exit(255); 382 exit(255);
382 } 383 }
383 break; 384 break;
@@ -480,7 +481,8 @@ main(int ac, char **av)
480 } 481 }
481 if (cp != NULL) { 482 if (cp != NULL) {
482 fwd.listen_port = a2port(cp); 483 fwd.listen_port = a2port(cp);
483 fwd.listen_host = cleanhostname(fwd.listen_host); 484 fwd.listen_host =
485 cleanhostname(fwd.listen_host);
484 } else { 486 } else {
485 fwd.listen_port = a2port(fwd.listen_host); 487 fwd.listen_port = a2port(fwd.listen_host);
486 fwd.listen_host = NULL; 488 fwd.listen_host = NULL;
@@ -586,8 +588,10 @@ main(int ac, char **av)
586 } 588 }
587 589
588 /* Cannot fork to background if no command. */ 590 /* Cannot fork to background if no command. */
589 if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) 591 if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
590 fatal("Cannot fork into background without a command to execute."); 592 !no_shell_flag)
593 fatal("Cannot fork into background without a command "
594 "to execute.");
591 595
592 /* Allocate a tty by default if no command specified. */ 596 /* Allocate a tty by default if no command specified. */
593 if (buffer_len(&command) == 0) 597 if (buffer_len(&command) == 0)
@@ -599,7 +603,8 @@ main(int ac, char **av)
599 /* Do not allocate a tty if stdin is not a tty. */ 603 /* Do not allocate a tty if stdin is not a tty. */
600 if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { 604 if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
601 if (tty_flag) 605 if (tty_flag)
602 logit("Pseudo-terminal will not be allocated because stdin is not a terminal."); 606 logit("Pseudo-terminal will not be allocated because "
607 "stdin is not a terminal.");
603 tty_flag = 0; 608 tty_flag = 0;
604 } 609 }
605 610
@@ -607,7 +612,8 @@ main(int ac, char **av)
607 * Initialize "log" output. Since we are the client all output 612 * Initialize "log" output. Since we are the client all output
608 * actually goes to stderr. 613 * actually goes to stderr.
609 */ 614 */
610 log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, 615 log_init(av[0],
616 options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
611 SYSLOG_FACILITY_USER, 1); 617 SYSLOG_FACILITY_USER, 1);
612 618
613 /* 619 /*
@@ -641,6 +647,28 @@ main(int ac, char **av)
641 if (options.user == NULL) 647 if (options.user == NULL)
642 options.user = xstrdup(pw->pw_name); 648 options.user = xstrdup(pw->pw_name);
643 649
650 /* Get default port if port has not been set. */
651 if (options.port == 0) {
652 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
653 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
654 }
655
656 if (options.local_command != NULL) {
657 char thishost[NI_MAXHOST];
658
659 if (gethostname(thishost, sizeof(thishost)) == -1)
660 fatal("gethostname: %s", strerror(errno));
661 snprintf(buf, sizeof(buf), "%d", options.port);
662 debug3("expanding LocalCommand: %s", options.local_command);
663 cp = options.local_command;
664 options.local_command = percent_expand(cp, "d", pw->pw_dir,
665 "h", options.hostname? options.hostname : host,
666 "l", thishost, "n", host, "r", options.user, "p", buf,
667 "u", pw->pw_name, (char *)NULL);
668 debug3("expanded LocalCommand: %s", options.local_command);
669 xfree(cp);
670 }
671
644 if (options.hostname != NULL) 672 if (options.hostname != NULL)
645 host = options.hostname; 673 host = options.hostname;
646 674
@@ -651,18 +679,16 @@ main(int ac, char **av)
651 *p = (char)tolower(*p); 679 *p = (char)tolower(*p);
652 } 680 }
653 681
654 /* Get default port if port has not been set. */
655 if (options.port == 0) {
656 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
657 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
658 }
659
660 if (options.proxy_command != NULL && 682 if (options.proxy_command != NULL &&
661 strcmp(options.proxy_command, "none") == 0) 683 strcmp(options.proxy_command, "none") == 0) {
684 xfree(options.proxy_command);
662 options.proxy_command = NULL; 685 options.proxy_command = NULL;
686 }
663 if (options.control_path != NULL && 687 if (options.control_path != NULL &&
664 strcmp(options.control_path, "none") == 0) 688 strcmp(options.control_path, "none") == 0) {
689 xfree(options.control_path);
665 options.control_path = NULL; 690 options.control_path = NULL;
691 }
666 692
667 if (options.control_path != NULL) { 693 if (options.control_path != NULL) {
668 char thishost[NI_MAXHOST]; 694 char thishost[NI_MAXHOST];
@@ -672,18 +698,22 @@ main(int ac, char **av)
672 snprintf(buf, sizeof(buf), "%d", options.port); 698 snprintf(buf, sizeof(buf), "%d", options.port);
673 cp = tilde_expand_filename(options.control_path, 699 cp = tilde_expand_filename(options.control_path,
674 original_real_uid); 700 original_real_uid);
701 xfree(options.control_path);
675 options.control_path = percent_expand(cp, "p", buf, "h", host, 702 options.control_path = percent_expand(cp, "p", buf, "h", host,
676 "r", options.user, "l", thishost, (char *)NULL); 703 "r", options.user, "l", thishost, (char *)NULL);
677 xfree(cp); 704 xfree(cp);
678 } 705 }
679 if (mux_command != 0 && options.control_path == NULL) 706 if (muxclient_command != 0 && options.control_path == NULL)
680 fatal("No ControlPath specified for \"-O\" command"); 707 fatal("No ControlPath specified for \"-O\" command");
681 if (options.control_path != NULL) 708 if (options.control_path != NULL)
682 control_client(options.control_path); 709 muxclient(options.control_path);
710
711 timeout_ms = options.connection_timeout * 1000;
683 712
684 /* Open a connection to the remote host. */ 713 /* Open a connection to the remote host. */
685 if (ssh_connect(host, &hostaddr, options.port, 714 if (ssh_connect(host, &hostaddr, options.port,
686 options.address_family, options.connection_attempts, 715 options.address_family, options.connection_attempts, &timeout_ms,
716 options.tcp_keep_alive,
687#ifdef HAVE_CYGWIN 717#ifdef HAVE_CYGWIN
688 options.use_privileged_port, 718 options.use_privileged_port,
689#else 719#else
@@ -692,6 +722,9 @@ main(int ac, char **av)
692 options.proxy_command) != 0) 722 options.proxy_command) != 0)
693 exit(255); 723 exit(255);
694 724
725 if (timeout_ms > 0)
726 debug3("timeout: %d ms remain after connect", timeout_ms);
727
695 /* 728 /*
696 * If we successfully made the connection, load the host private key 729 * If we successfully made the connection, load the host private key
697 * in case we will need it later for combined rsa-rhosts 730 * in case we will need it later for combined rsa-rhosts
@@ -745,7 +778,8 @@ main(int ac, char **av)
745 * Now that we are back to our own permissions, create ~/.ssh 778 * Now that we are back to our own permissions, create ~/.ssh
746 * directory if it doesn't already exist. 779 * directory if it doesn't already exist.
747 */ 780 */
748 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); 781 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir,
782 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
749 if (stat(buf, &st) < 0) 783 if (stat(buf, &st) < 0)
750 if (mkdir(buf, 0700) < 0) 784 if (mkdir(buf, 0700) < 0)
751 error("Could not create directory '%.200s'.", buf); 785 error("Could not create directory '%.200s'.", buf);
@@ -766,8 +800,9 @@ main(int ac, char **av)
766 800
767 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ 801 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
768 802
769 /* Log into the remote system. This never returns if the login fails. */ 803 /* Log into the remote system. Never returns if the login fails. */
770 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw); 804 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
805 pw, timeout_ms);
771 806
772 /* We no longer need the private host keys. Clear them now. */ 807 /* We no longer need the private host keys. Clear them now. */
773 if (sensitive_data.nkeys != 0) { 808 if (sensitive_data.nkeys != 0) {
@@ -795,7 +830,7 @@ main(int ac, char **av)
795 exit_status = compat20 ? ssh_session2() : ssh_session(); 830 exit_status = compat20 ? ssh_session2() : ssh_session();
796 packet_close(); 831 packet_close();
797 832
798 if (options.control_path != NULL && control_fd != -1) 833 if (options.control_path != NULL && muxserver_sock != -1)
799 unlink(options.control_path); 834 unlink(options.control_path);
800 835
801 /* 836 /*
@@ -808,6 +843,34 @@ main(int ac, char **av)
808 return exit_status; 843 return exit_status;
809} 844}
810 845
846/* Callback for remote forward global requests */
847static void
848ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
849{
850 Forward *rfwd = (Forward *)ctxt;
851
852 debug("remote forward %s for: listen %d, connect %s:%d",
853 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
854 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
855 if (type == SSH2_MSG_REQUEST_FAILURE) {
856 if (options.exit_on_forward_failure)
857 fatal("Error: remote port forwarding failed for "
858 "listen port %d", rfwd->listen_port);
859 else
860 logit("Warning: remote port forwarding failed for "
861 "listen port %d", rfwd->listen_port);
862 }
863 if (++remote_forward_confirms_received == options.num_remote_forwards) {
864 debug("All remote forwarding requests processed");
865 if (fork_after_authentication_flag) {
866 fork_after_authentication_flag = 0;
867 if (daemon(1, 1) < 0)
868 fatal("daemon() failed: %.200s",
869 strerror(errno));
870 }
871 }
872}
873
811static void 874static void
812ssh_init_forwarding(void) 875ssh_init_forwarding(void)
813{ 876{
@@ -856,6 +919,8 @@ ssh_init_forwarding(void)
856 logit("Warning: Could not request remote " 919 logit("Warning: Could not request remote "
857 "forwarding."); 920 "forwarding.");
858 } 921 }
922 client_register_global_confirm(ssh_confirm_remote_forward,
923 &options.remote_forwards[i]);
859 } 924 }
860 925
861 /* Initiate tunnel forwarding. */ 926 /* Initiate tunnel forwarding. */
@@ -892,10 +957,13 @@ ssh_session(void)
892 957
893 /* Enable compression if requested. */ 958 /* Enable compression if requested. */
894 if (options.compression) { 959 if (options.compression) {
895 debug("Requesting compression at level %d.", options.compression_level); 960 debug("Requesting compression at level %d.",
961 options.compression_level);
896 962
897 if (options.compression_level < 1 || options.compression_level > 9) 963 if (options.compression_level < 1 ||
898 fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); 964 options.compression_level > 9)
965 fatal("Compression level must be from 1 (fast) to "
966 "9 (slow, best).");
899 967
900 /* Send the request. */ 968 /* Send the request. */
901 packet_start(SSH_CMSG_REQUEST_COMPRESSION); 969 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
@@ -908,7 +976,8 @@ ssh_session(void)
908 else if (type == SSH_SMSG_FAILURE) 976 else if (type == SSH_SMSG_FAILURE)
909 logit("Warning: Remote host refused compression."); 977 logit("Warning: Remote host refused compression.");
910 else 978 else
911 packet_disconnect("Protocol error waiting for compression response."); 979 packet_disconnect("Protocol error waiting for "
980 "compression response.");
912 } 981 }
913 /* Allocate a pseudo tty if appropriate. */ 982 /* Allocate a pseudo tty if appropriate. */
914 if (tty_flag) { 983 if (tty_flag) {
@@ -945,9 +1014,11 @@ ssh_session(void)
945 interactive = 1; 1014 interactive = 1;
946 have_tty = 1; 1015 have_tty = 1;
947 } else if (type == SSH_SMSG_FAILURE) 1016 } else if (type == SSH_SMSG_FAILURE)
948 logit("Warning: Remote host failed or refused to allocate a pseudo tty."); 1017 logit("Warning: Remote host failed or refused to "
1018 "allocate a pseudo tty.");
949 else 1019 else
950 packet_disconnect("Protocol error waiting for pty request response."); 1020 packet_disconnect("Protocol error waiting for pty "
1021 "request response.");
951 } 1022 }
952 /* Request X11 forwarding if enabled and DISPLAY is set. */ 1023 /* Request X11 forwarding if enabled and DISPLAY is set. */
953 display = getenv("DISPLAY"); 1024 display = getenv("DISPLAY");
@@ -957,7 +1028,8 @@ ssh_session(void)
957 client_x11_get_proto(display, options.xauth_location, 1028 client_x11_get_proto(display, options.xauth_location,
958 options.forward_x11_trusted, &proto, &data); 1029 options.forward_x11_trusted, &proto, &data);
959 /* Request forwarding with authentication spoofing. */ 1030 /* Request forwarding with authentication spoofing. */
960 debug("Requesting X11 forwarding with authentication spoofing."); 1031 debug("Requesting X11 forwarding with authentication "
1032 "spoofing.");
961 x11_request_forwarding_with_spoofing(0, display, proto, data); 1033 x11_request_forwarding_with_spoofing(0, display, proto, data);
962 1034
963 /* Read response from the server. */ 1035 /* Read response from the server. */
@@ -967,7 +1039,8 @@ ssh_session(void)
967 } else if (type == SSH_SMSG_FAILURE) { 1039 } else if (type == SSH_SMSG_FAILURE) {
968 logit("Warning: Remote host denied X11 forwarding."); 1040 logit("Warning: Remote host denied X11 forwarding.");
969 } else { 1041 } else {
970 packet_disconnect("Protocol error waiting for X11 forwarding"); 1042 packet_disconnect("Protocol error waiting for X11 "
1043 "forwarding");
971 } 1044 }
972 } 1045 }
973 /* Tell the packet module whether this is an interactive session. */ 1046 /* Tell the packet module whether this is an interactive session. */
@@ -990,10 +1063,22 @@ ssh_session(void)
990 /* Initiate port forwardings. */ 1063 /* Initiate port forwardings. */
991 ssh_init_forwarding(); 1064 ssh_init_forwarding();
992 1065
993 /* If requested, let ssh continue in the background. */ 1066 /* Execute a local command */
994 if (fork_after_authentication_flag) 1067 if (options.local_command != NULL &&
1068 options.permit_local_command)
1069 ssh_local_cmd(options.local_command);
1070
1071 /*
1072 * If requested and we are not interested in replies to remote
1073 * forwarding requests, then let ssh continue in the background.
1074 */
1075 if (fork_after_authentication_flag &&
1076 (!options.exit_on_forward_failure ||
1077 options.num_remote_forwards == 0)) {
1078 fork_after_authentication_flag = 0;
995 if (daemon(1, 1) < 0) 1079 if (daemon(1, 1) < 0)
996 fatal("daemon() failed: %.200s", strerror(errno)); 1080 fatal("daemon() failed: %.200s", strerror(errno));
1081 }
997 1082
998 /* 1083 /*
999 * If a command was specified on the command line, execute the 1084 * If a command was specified on the command line, execute the
@@ -1003,7 +1088,8 @@ ssh_session(void)
1003 int len = buffer_len(&command); 1088 int len = buffer_len(&command);
1004 if (len > 900) 1089 if (len > 900)
1005 len = 900; 1090 len = 900;
1006 debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); 1091 debug("Sending command: %.*s", len,
1092 (u_char *)buffer_ptr(&command));
1007 packet_start(SSH_CMSG_EXEC_CMD); 1093 packet_start(SSH_CMSG_EXEC_CMD);
1008 packet_put_string(buffer_ptr(&command), buffer_len(&command)); 1094 packet_put_string(buffer_ptr(&command), buffer_len(&command));
1009 packet_send(); 1095 packet_send();
@@ -1020,88 +1106,6 @@ ssh_session(void)
1020 options.escape_char : SSH_ESCAPECHAR_NONE, 0); 1106 options.escape_char : SSH_ESCAPECHAR_NONE, 0);
1021} 1107}
1022 1108
1023static void
1024ssh_subsystem_reply(int type, u_int32_t seq, void *ctxt)
1025{
1026 int id, len;
1027
1028 id = packet_get_int();
1029 len = buffer_len(&command);
1030 if (len > 900)
1031 len = 900;
1032 packet_check_eom();
1033 if (type == SSH2_MSG_CHANNEL_FAILURE)
1034 fatal("Request for subsystem '%.*s' failed on channel %d",
1035 len, (u_char *)buffer_ptr(&command), id);
1036}
1037
1038void
1039client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
1040{
1041 int i;
1042
1043 i = client_global_request_id++;
1044 if (i >= options.num_remote_forwards)
1045 return;
1046 debug("remote forward %s for: listen %d, connect %s:%d",
1047 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1048 options.remote_forwards[i].listen_port,
1049 options.remote_forwards[i].connect_host,
1050 options.remote_forwards[i].connect_port);
1051 if (type == SSH2_MSG_REQUEST_FAILURE) {
1052 if (options.exit_on_forward_failure)
1053 fatal("Error: remote port forwarding failed for "
1054 "listen port %d",
1055 options.remote_forwards[i].listen_port);
1056 else
1057 logit("Warning: remote port forwarding failed for "
1058 "listen port %d",
1059 options.remote_forwards[i].listen_port);
1060 }
1061}
1062
1063static void
1064ssh_control_listener(void)
1065{
1066 struct sockaddr_un addr;
1067 mode_t old_umask;
1068 int addr_len;
1069
1070 if (options.control_path == NULL ||
1071 options.control_master == SSHCTL_MASTER_NO)
1072 return;
1073
1074 debug("setting up multiplex master socket");
1075
1076 memset(&addr, '\0', sizeof(addr));
1077 addr.sun_family = AF_UNIX;
1078 addr_len = offsetof(struct sockaddr_un, sun_path) +
1079 strlen(options.control_path) + 1;
1080
1081 if (strlcpy(addr.sun_path, options.control_path,
1082 sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
1083 fatal("ControlPath too long");
1084
1085 if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1086 fatal("%s socket(): %s", __func__, strerror(errno));
1087
1088 old_umask = umask(0177);
1089 if (bind(control_fd, (struct sockaddr *)&addr, addr_len) == -1) {
1090 control_fd = -1;
1091 if (errno == EINVAL || errno == EADDRINUSE)
1092 fatal("ControlSocket %s already exists",
1093 options.control_path);
1094 else
1095 fatal("%s bind(): %s", __func__, strerror(errno));
1096 }
1097 umask(old_umask);
1098
1099 if (listen(control_fd, 64) == -1)
1100 fatal("%s listen(): %s", __func__, strerror(errno));
1101
1102 set_nonblock(control_fd);
1103}
1104
1105/* request pty/x11/agent/tcpfwd/shell for channel */ 1109/* request pty/x11/agent/tcpfwd/shell for channel */
1106static void 1110static void
1107ssh_session2_setup(int id, void *arg) 1111ssh_session2_setup(int id, void *arg)
@@ -1117,7 +1121,8 @@ ssh_session2_setup(int id, void *arg)
1117 client_x11_get_proto(display, options.xauth_location, 1121 client_x11_get_proto(display, options.xauth_location,
1118 options.forward_x11_trusted, &proto, &data); 1122 options.forward_x11_trusted, &proto, &data);
1119 /* Request forwarding with authentication spoofing. */ 1123 /* Request forwarding with authentication spoofing. */
1120 debug("Requesting X11 forwarding with authentication spoofing."); 1124 debug("Requesting X11 forwarding with authentication "
1125 "spoofing.");
1121 x11_request_forwarding_with_spoofing(id, display, proto, data); 1126 x11_request_forwarding_with_spoofing(id, display, proto, data);
1122 interactive = 1; 1127 interactive = 1;
1123 /* XXX wait for reply */ 1128 /* XXX wait for reply */
@@ -1131,7 +1136,7 @@ ssh_session2_setup(int id, void *arg)
1131 } 1136 }
1132 1137
1133 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1138 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
1134 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); 1139 NULL, fileno(stdin), &command, environ);
1135 1140
1136 packet_set_interactive(interactive); 1141 packet_set_interactive(interactive);
1137} 1142}
@@ -1177,7 +1182,8 @@ ssh_session2_open(void)
1177 1182
1178 channel_send_open(c->self); 1183 channel_send_open(c->self);
1179 if (!no_shell_flag) 1184 if (!no_shell_flag)
1180 channel_register_confirm(c->self, ssh_session2_setup, NULL); 1185 channel_register_open_confirm(c->self,
1186 ssh_session2_setup, NULL);
1181 1187
1182 return c->self; 1188 return c->self;
1183} 1189}
@@ -1193,18 +1199,29 @@ ssh_session2(void)
1193 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1199 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1194 id = ssh_session2_open(); 1200 id = ssh_session2_open();
1195 1201
1202 /* If we don't expect to open a new session, then disallow it */
1203 if (options.control_master == SSHCTL_MASTER_NO) {
1204 debug("Requesting no-more-sessions@openssh.com");
1205 packet_start(SSH2_MSG_GLOBAL_REQUEST);
1206 packet_put_cstring("no-more-sessions@openssh.com");
1207 packet_put_char(0);
1208 packet_send();
1209 }
1210
1196 /* Execute a local command */ 1211 /* Execute a local command */
1197 if (options.local_command != NULL && 1212 if (options.local_command != NULL &&
1198 options.permit_local_command) 1213 options.permit_local_command)
1199 ssh_local_cmd(options.local_command); 1214 ssh_local_cmd(options.local_command);
1200 1215
1201 /* Start listening for multiplex clients */ 1216 /* Start listening for multiplex clients */
1202 ssh_control_listener(); 1217 muxserver_listen();
1203 1218
1204 /* If requested, let ssh continue in the background. */ 1219 /* If requested, let ssh continue in the background. */
1205 if (fork_after_authentication_flag) 1220 if (fork_after_authentication_flag) {
1221 fork_after_authentication_flag = 0;
1206 if (daemon(1, 1) < 0) 1222 if (daemon(1, 1) < 0)
1207 fatal("daemon() failed: %.200s", strerror(errno)); 1223 fatal("daemon() failed: %.200s", strerror(errno));
1224 }
1208 1225
1209 return client_loop(tty_flag, tty_flag ? 1226 return client_loop(tty_flag, tty_flag ?
1210 options.escape_char : SSH_ESCAPECHAR_NONE, id); 1227 options.escape_char : SSH_ESCAPECHAR_NONE, id);
@@ -1214,6 +1231,7 @@ static void
1214load_public_identity_files(void) 1231load_public_identity_files(void)
1215{ 1232{
1216 char *filename, *cp, thishost[NI_MAXHOST]; 1233 char *filename, *cp, thishost[NI_MAXHOST];
1234 char *pwdir = NULL, *pwname = NULL;
1217 int i = 0; 1235 int i = 0;
1218 Key *public; 1236 Key *public;
1219 struct passwd *pw; 1237 struct passwd *pw;
@@ -1226,9 +1244,11 @@ load_public_identity_files(void)
1226 int count = 0; 1244 int count = 0;
1227 for (i = 0; keys[i] != NULL; i++) { 1245 for (i = 0; keys[i] != NULL; i++) {
1228 count++; 1246 count++;
1229 memmove(&options.identity_files[1], &options.identity_files[0], 1247 memmove(&options.identity_files[1],
1248 &options.identity_files[0],
1230 sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1)); 1249 sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
1231 memmove(&options.identity_keys[1], &options.identity_keys[0], 1250 memmove(&options.identity_keys[1],
1251 &options.identity_keys[0],
1232 sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); 1252 sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
1233 options.num_identity_files++; 1253 options.num_identity_files++;
1234 options.identity_keys[0] = keys[i]; 1254 options.identity_keys[0] = keys[i];
@@ -1242,14 +1262,16 @@ load_public_identity_files(void)
1242#endif /* SMARTCARD */ 1262#endif /* SMARTCARD */
1243 if ((pw = getpwuid(original_real_uid)) == NULL) 1263 if ((pw = getpwuid(original_real_uid)) == NULL)
1244 fatal("load_public_identity_files: getpwuid failed"); 1264 fatal("load_public_identity_files: getpwuid failed");
1265 pwname = xstrdup(pw->pw_name);
1266 pwdir = xstrdup(pw->pw_dir);
1245 if (gethostname(thishost, sizeof(thishost)) == -1) 1267 if (gethostname(thishost, sizeof(thishost)) == -1)
1246 fatal("load_public_identity_files: gethostname: %s", 1268 fatal("load_public_identity_files: gethostname: %s",
1247 strerror(errno)); 1269 strerror(errno));
1248 for (; i < options.num_identity_files; i++) { 1270 for (; i < options.num_identity_files; i++) {
1249 cp = tilde_expand_filename(options.identity_files[i], 1271 cp = tilde_expand_filename(options.identity_files[i],
1250 original_real_uid); 1272 original_real_uid);
1251 filename = percent_expand(cp, "d", pw->pw_dir, 1273 filename = percent_expand(cp, "d", pwdir,
1252 "u", pw->pw_name, "l", thishost, "h", host, 1274 "u", pwname, "l", thishost, "h", host,
1253 "r", options.user, (char *)NULL); 1275 "r", options.user, (char *)NULL);
1254 xfree(cp); 1276 xfree(cp);
1255 public = key_load_public(filename, NULL); 1277 public = key_load_public(filename, NULL);
@@ -1259,231 +1281,8 @@ load_public_identity_files(void)
1259 options.identity_files[i] = filename; 1281 options.identity_files[i] = filename;
1260 options.identity_keys[i] = public; 1282 options.identity_keys[i] = public;
1261 } 1283 }
1262} 1284 bzero(pwname, strlen(pwname));
1263 1285 xfree(pwname);
1264static void 1286 bzero(pwdir, strlen(pwdir));
1265control_client_sighandler(int signo) 1287 xfree(pwdir);
1266{
1267 control_client_terminate = signo;
1268}
1269
1270static void
1271control_client_sigrelay(int signo)
1272{
1273 if (control_server_pid > 1)
1274 kill(control_server_pid, signo);
1275}
1276
1277static int
1278env_permitted(char *env)
1279{
1280 int i, ret;
1281 char name[1024], *cp;
1282
1283 if ((cp = strchr(env, '=')) == NULL || cp == env)
1284 return (0);
1285 ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
1286 if (ret <= 0 || (size_t)ret >= sizeof(name))
1287 fatal("env_permitted: name '%.100s...' too long", env);
1288
1289 for (i = 0; i < options.num_send_env; i++)
1290 if (match_pattern(name, options.send_env[i]))
1291 return (1);
1292
1293 return (0);
1294}
1295
1296static void
1297control_client(const char *path)
1298{
1299 struct sockaddr_un addr;
1300 int i, r, fd, sock, exitval[2], num_env, addr_len;
1301 Buffer m;
1302 char *term;
1303 extern char **environ;
1304 u_int flags;
1305
1306 if (mux_command == 0)
1307 mux_command = SSHMUX_COMMAND_OPEN;
1308
1309 switch (options.control_master) {
1310 case SSHCTL_MASTER_AUTO:
1311 case SSHCTL_MASTER_AUTO_ASK:
1312 debug("auto-mux: Trying existing master");
1313 /* FALLTHROUGH */
1314 case SSHCTL_MASTER_NO:
1315 break;
1316 default:
1317 return;
1318 }
1319
1320 memset(&addr, '\0', sizeof(addr));
1321 addr.sun_family = AF_UNIX;
1322 addr_len = offsetof(struct sockaddr_un, sun_path) +
1323 strlen(path) + 1;
1324
1325 if (strlcpy(addr.sun_path, path,
1326 sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
1327 fatal("ControlPath too long");
1328
1329 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1330 fatal("%s socket(): %s", __func__, strerror(errno));
1331
1332 if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
1333 if (mux_command != SSHMUX_COMMAND_OPEN) {
1334 fatal("Control socket connect(%.100s): %s", path,
1335 strerror(errno));
1336 }
1337 if (errno == ENOENT)
1338 debug("Control socket \"%.100s\" does not exist", path);
1339 else {
1340 error("Control socket connect(%.100s): %s", path,
1341 strerror(errno));
1342 }
1343 close(sock);
1344 return;
1345 }
1346
1347 if (stdin_null_flag) {
1348 if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
1349 fatal("open(/dev/null): %s", strerror(errno));
1350 if (dup2(fd, STDIN_FILENO) == -1)
1351 fatal("dup2: %s", strerror(errno));
1352 if (fd > STDERR_FILENO)
1353 close(fd);
1354 }
1355
1356 term = getenv("TERM");
1357
1358 flags = 0;
1359 if (tty_flag)
1360 flags |= SSHMUX_FLAG_TTY;
1361 if (subsystem_flag)
1362 flags |= SSHMUX_FLAG_SUBSYS;
1363 if (options.forward_x11)
1364 flags |= SSHMUX_FLAG_X11_FWD;
1365 if (options.forward_agent)
1366 flags |= SSHMUX_FLAG_AGENT_FWD;
1367
1368 buffer_init(&m);
1369
1370 /* Send our command to server */
1371 buffer_put_int(&m, mux_command);
1372 buffer_put_int(&m, flags);
1373 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
1374 fatal("%s: msg_send", __func__);
1375 buffer_clear(&m);
1376
1377 /* Get authorisation status and PID of controlee */
1378 if (ssh_msg_recv(sock, &m) == -1)
1379 fatal("%s: msg_recv", __func__);
1380 if (buffer_get_char(&m) != SSHMUX_VER)
1381 fatal("%s: wrong version", __func__);
1382 if (buffer_get_int(&m) != 1)
1383 fatal("Connection to master denied");
1384 control_server_pid = buffer_get_int(&m);
1385
1386 buffer_clear(&m);
1387
1388 switch (mux_command) {
1389 case SSHMUX_COMMAND_ALIVE_CHECK:
1390 fprintf(stderr, "Master running (pid=%d)\r\n",
1391 control_server_pid);
1392 exit(0);
1393 case SSHMUX_COMMAND_TERMINATE:
1394 fprintf(stderr, "Exit request sent.\r\n");
1395 exit(0);
1396 case SSHMUX_COMMAND_OPEN:
1397 /* continue below */
1398 break;
1399 default:
1400 fatal("silly mux_command %d", mux_command);
1401 }
1402
1403 /* SSHMUX_COMMAND_OPEN */
1404 buffer_put_cstring(&m, term ? term : "");
1405 buffer_append(&command, "\0", 1);
1406 buffer_put_cstring(&m, buffer_ptr(&command));
1407
1408 if (options.num_send_env == 0 || environ == NULL) {
1409 buffer_put_int(&m, 0);
1410 } else {
1411 /* Pass environment */
1412 num_env = 0;
1413 for (i = 0; environ[i] != NULL; i++)
1414 if (env_permitted(environ[i]))
1415 num_env++; /* Count */
1416
1417 buffer_put_int(&m, num_env);
1418
1419 for (i = 0; environ[i] != NULL && num_env >= 0; i++)
1420 if (env_permitted(environ[i])) {
1421 num_env--;
1422 buffer_put_cstring(&m, environ[i]);
1423 }
1424 }
1425
1426 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
1427 fatal("%s: msg_send", __func__);
1428
1429 mm_send_fd(sock, STDIN_FILENO);
1430 mm_send_fd(sock, STDOUT_FILENO);
1431 mm_send_fd(sock, STDERR_FILENO);
1432
1433 /* Wait for reply, so master has a chance to gather ttymodes */
1434 buffer_clear(&m);
1435 if (ssh_msg_recv(sock, &m) == -1)
1436 fatal("%s: msg_recv", __func__);
1437 if (buffer_get_char(&m) != SSHMUX_VER)
1438 fatal("%s: wrong version", __func__);
1439 buffer_free(&m);
1440
1441 signal(SIGHUP, control_client_sighandler);
1442 signal(SIGINT, control_client_sighandler);
1443 signal(SIGTERM, control_client_sighandler);
1444 signal(SIGWINCH, control_client_sigrelay);
1445
1446 if (tty_flag)
1447 enter_raw_mode();
1448
1449 /*
1450 * Stick around until the controlee closes the client_fd.
1451 * Before it does, it is expected to write this process' exit
1452 * value (one int). This process must read the value and wait for
1453 * the closure of the client_fd; if this one closes early, the
1454 * multiplex master will terminate early too (possibly losing data).
1455 */
1456 exitval[0] = 0;
1457 for (i = 0; !control_client_terminate && i < (int)sizeof(exitval);) {
1458 r = read(sock, (char *)exitval + i, sizeof(exitval) - i);
1459 if (r == 0) {
1460 debug2("Received EOF from master");
1461 break;
1462 }
1463 if (r == -1) {
1464 if (errno == EINTR)
1465 continue;
1466 fatal("%s: read %s", __func__, strerror(errno));
1467 }
1468 i += r;
1469 }
1470
1471 close(sock);
1472 leave_raw_mode();
1473 if (i > (int)sizeof(int))
1474 fatal("%s: master returned too much data (%d > %lu)",
1475 __func__, i, sizeof(int));
1476 if (control_client_terminate) {
1477 debug2("Exiting on signal %d", control_client_terminate);
1478 exitval[0] = 255;
1479 } else if (i < (int)sizeof(int)) {
1480 debug2("Control master terminated unexpectedly");
1481 exitval[0] = 255;
1482 } else
1483 debug2("Received exit status from master %d", exitval[0]);
1484
1485 if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
1486 fprintf(stderr, "Shared connection to %s closed.\r\n", host);
1487
1488 exit(exitval[0]);
1489} 1288}
diff --git a/ssh_config.0 b/ssh_config.0
index 381c1ba0a..e2e645854 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -40,10 +40,12 @@ DESCRIPTION
40 40
41 Host Restricts the following declarations (up to the next Host key- 41 Host Restricts the following declarations (up to the next Host key-
42 word) to be only for those hosts that match one of the patterns 42 word) to be only for those hosts that match one of the patterns
43 given after the keyword. A single `*' as a pattern can be used 43 given after the keyword. If more than one pattern is provided,
44 to provide global defaults for all hosts. The host is the 44 they should be separated by whitepsace. A single `*' as a pat-
45 hostname argument given on the command line (i.e. the name is not 45 tern can be used to provide global defaults for all hosts. The
46 converted to a canonicalized host name before matching). 46 host is the hostname argument given on the command line (i.e. the
47 name is not converted to a canonicalized host name before match-
48 ing).
47 49
48 See PATTERNS for more information on patterns. 50 See PATTERNS for more information on patterns.
49 51
@@ -324,6 +326,11 @@ DESCRIPTION
324 It is possible to have multiple identity files specified in con- 326 It is possible to have multiple identity files specified in con-
325 figuration files; all these identities will be tried in sequence. 327 figuration files; all these identities will be tried in sequence.
326 328
329 KbdInteractiveAuthentication
330 Specifies whether to use keyboard-interactive authentication.
331 The argument to this keyword must be ``yes'' or ``no''. The de-
332 fault is ``yes''.
333
327 KbdInteractiveDevices 334 KbdInteractiveDevices
328 Specifies the list of methods to use in keyboard-interactive au- 335 Specifies the list of methods to use in keyboard-interactive au-
329 thentication. Multiple method names must be comma-separated. 336 thentication. Multiple method names must be comma-separated.
@@ -335,8 +342,13 @@ DESCRIPTION
335 LocalCommand 342 LocalCommand
336 Specifies a command to execute on the local machine after suc- 343 Specifies a command to execute on the local machine after suc-
337 cessfully connecting to the server. The command string extends 344 cessfully connecting to the server. The command string extends
338 to the end of the line, and is executed with /bin/sh. This di- 345 to the end of the line, and is executed with the user's shell.
339 rective is ignored unless PermitLocalCommand has been enabled. 346 The following escape character substitutions will be performed:
347 `%d' (local user's home directory), `%h' (remote host name), `%l'
348 (local host name), `%n' (host name as provided on the command
349 line), `%p' (remote port), `%r' (remote user name) or `%u' (local
350 user name). This directive is ignored unless PermitLocalCommand
351 has been enabled.
340 352
341 LocalForward 353 LocalForward
342 Specifies that a TCP port on the local machine be forwarded over 354 Specifies that a TCP port on the local machine be forwarded over
@@ -413,16 +425,16 @@ DESCRIPTION
413 ProxyCommand 425 ProxyCommand
414 Specifies the command to use to connect to the server. The com- 426 Specifies the command to use to connect to the server. The com-
415 mand string extends to the end of the line, and is executed with 427 mand string extends to the end of the line, and is executed with
416 /bin/sh. In the command string, `%h' will be substituted by the 428 the user's shell. In the command string, `%h' will be substitut-
417 host name to connect and `%p' by the port. The command can be 429 ed by the host name to connect and `%p' by the port. The command
418 basically anything, and should read from its standard input and 430 can be basically anything, and should read from its standard in-
419 write to its standard output. It should eventually connect an 431 put and write to its standard output. It should eventually con-
420 sshd(8) server running on some machine, or execute sshd -i some- 432 nect an sshd(8) server running on some machine, or execute sshd
421 where. Host key management will be done using the HostName of 433 -i somewhere. Host key management will be done using the Host-
422 the host being connected (defaulting to the name typed by the us- 434 Name of the host being connected (defaulting to the name typed by
423 er). Setting the command to ``none'' disables this option en- 435 the user). Setting the command to ``none'' disables this option
424 tirely. Note that CheckHostIP is not available for connects with 436 entirely. Note that CheckHostIP is not available for connects
425 a proxy command. 437 with a proxy command.
426 438
427 This directive is useful in conjunction with nc(1) and its proxy 439 This directive is useful in conjunction with nc(1) and its proxy
428 support. For example, the following directive would connect via 440 support. For example, the following directive would connect via
@@ -595,6 +607,12 @@ DESCRIPTION
595 607
596 See also VERIFYING HOST KEYS in ssh(1). 608 See also VERIFYING HOST KEYS in ssh(1).
597 609
610 VisualHostKey
611 If this flag is set to ``yes'', an ASCII art representation of
612 the remote host key fingerprint is printed additionally to the
613 hex fingerprint string. If this flag is set to ``no'', only the
614 hex fingerprint string will be printed. The default is ``no''.
615
598 XAuthLocation 616 XAuthLocation
599 Specifies the full pathname of the xauth(1) program. The default 617 Specifies the full pathname of the xauth(1) program. The default
600 is /usr/X11R6/bin/xauth. 618 is /usr/X11R6/bin/xauth.
@@ -644,4 +662,4 @@ AUTHORS
644 ated OpenSSH. Markus Friedl contributed the support for SSH protocol 662 ated OpenSSH. Markus Friedl contributed the support for SSH protocol
645 versions 1.5 and 2.0. 663 versions 1.5 and 2.0.
646 664
647OpenBSD 4.2 August 15, 2007 10 665OpenBSD 4.4 June 26, 2008 11
diff --git a/ssh_config.5 b/ssh_config.5
index 95af3976a..85e7ba06d 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh_config.5,v 1.102 2007/08/15 12:13:41 stevesk Exp $ 37.\" $OpenBSD: ssh_config.5,v 1.111 2008/06/26 11:46:31 grunk Exp $
38.Dd $Mdocdate: August 15 2007 $ 38.Dd $Mdocdate: June 26 2008 $
39.Dt SSH_CONFIG 5 39.Dt SSH_CONFIG 5
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -103,6 +103,7 @@ Restricts the following declarations (up to the next
103.Cm Host 103.Cm Host
104keyword) to be only for those hosts that match one of the patterns 104keyword) to be only for those hosts that match one of the patterns
105given after the keyword. 105given after the keyword.
106If more than one pattern is provided, they should be separated by whitepsace.
106A single 107A single
107.Ql * 108.Ql *
108as a pattern can be used to provide global 109as a pattern can be used to provide global
@@ -576,6 +577,14 @@ escape characters:
576It is possible to have 577It is possible to have
577multiple identity files specified in configuration files; all these 578multiple identity files specified in configuration files; all these
578identities will be tried in sequence. 579identities will be tried in sequence.
580.It Cm KbdInteractiveAuthentication
581Specifies whether to use keyboard-interactive authentication.
582The argument to this keyword must be
583.Dq yes
584or
585.Dq no .
586The default is
587.Dq yes .
579.It Cm KbdInteractiveDevices 588.It Cm KbdInteractiveDevices
580Specifies the list of methods to use in keyboard-interactive authentication. 589Specifies the list of methods to use in keyboard-interactive authentication.
581Multiple method names must be comma-separated. 590Multiple method names must be comma-separated.
@@ -591,7 +600,22 @@ and
591Specifies a command to execute on the local machine after successfully 600Specifies a command to execute on the local machine after successfully
592connecting to the server. 601connecting to the server.
593The command string extends to the end of the line, and is executed with 602The command string extends to the end of the line, and is executed with
594.Pa /bin/sh . 603the user's shell.
604The following escape character substitutions will be performed:
605.Ql %d
606(local user's home directory),
607.Ql %h
608(remote host name),
609.Ql %l
610(local host name),
611.Ql %n
612(host name as provided on the command line),
613.Ql %p
614(remote port),
615.Ql %r
616(remote user name) or
617.Ql %u
618(local user name).
595This directive is ignored unless 619This directive is ignored unless
596.Cm PermitLocalCommand 620.Cm PermitLocalCommand
597has been enabled. 621has been enabled.
@@ -715,7 +739,7 @@ if version 2 is not available.
715Specifies the command to use to connect to the server. 739Specifies the command to use to connect to the server.
716The command 740The command
717string extends to the end of the line, and is executed with 741string extends to the end of the line, and is executed with
718.Pa /bin/sh . 742the user's shell.
719In the command string, 743In the command string,
720.Ql %h 744.Ql %h
721will be substituted by the host name to 745will be substituted by the host name to
@@ -1036,6 +1060,16 @@ See also
1036.Sx VERIFYING HOST KEYS 1060.Sx VERIFYING HOST KEYS
1037in 1061in
1038.Xr ssh 1 . 1062.Xr ssh 1 .
1063.It Cm VisualHostKey
1064If this flag is set to
1065.Dq yes ,
1066an ASCII art representation of the remote host key fingerprint is
1067printed additionally to the hex fingerprint string.
1068If this flag is set to
1069.Dq no ,
1070only the hex fingerprint string will be printed.
1071The default is
1072.Dq no .
1039.It Cm XAuthLocation 1073.It Cm XAuthLocation
1040Specifies the full pathname of the 1074Specifies the full pathname of the
1041.Xr xauth 1 1075.Xr xauth 1
diff --git a/sshconnect.c b/sshconnect.c
index a222233d0..ec8ba33e0 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.200 2006/10/10 10:12:45 markus Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.211 2008/07/01 07:24:22 dtucker 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
@@ -86,7 +86,10 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
86 char *command_string, *tmp; 86 char *command_string, *tmp;
87 int pin[2], pout[2]; 87 int pin[2], pout[2];
88 pid_t pid; 88 pid_t pid;
89 char strport[NI_MAXSERV]; 89 char *shell, strport[NI_MAXSERV];
90
91 if ((shell = getenv("SHELL")) == NULL)
92 shell = _PATH_BSHELL;
90 93
91 /* Convert the port number into a string. */ 94 /* Convert the port number into a string. */
92 snprintf(strport, sizeof strport, "%hu", port); 95 snprintf(strport, sizeof strport, "%hu", port);
@@ -132,7 +135,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
132 135
133 /* Stderr is left as it is so that error messages get 136 /* Stderr is left as it is so that error messages get
134 printed on the user's terminal. */ 137 printed on the user's terminal. */
135 argv[0] = _PATH_BSHELL; 138 argv[0] = shell;
136 argv[1] = "-c"; 139 argv[1] = "-c";
137 argv[2] = command_string; 140 argv[2] = command_string;
138 argv[3] = NULL; 141 argv[3] = NULL;
@@ -158,6 +161,8 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
158 161
159 /* Set the connection file descriptors. */ 162 /* Set the connection file descriptors. */
160 packet_set_connection(pout[0], pin[1]); 163 packet_set_connection(pout[0], pin[1]);
164 packet_set_timeout(options.server_alive_interval,
165 options.server_alive_count_max);
161 166
162 /* Indicate OK return */ 167 /* Indicate OK return */
163 return 0; 168 return 0;
@@ -201,10 +206,10 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
201 hints.ai_socktype = ai->ai_socktype; 206 hints.ai_socktype = ai->ai_socktype;
202 hints.ai_protocol = ai->ai_protocol; 207 hints.ai_protocol = ai->ai_protocol;
203 hints.ai_flags = AI_PASSIVE; 208 hints.ai_flags = AI_PASSIVE;
204 gaierr = getaddrinfo(options.bind_address, "0", &hints, &res); 209 gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res);
205 if (gaierr) { 210 if (gaierr) {
206 error("getaddrinfo: %s: %s", options.bind_address, 211 error("getaddrinfo: %s: %s", options.bind_address,
207 gai_strerror(gaierr)); 212 ssh_gai_strerror(gaierr));
208 close(sock); 213 close(sock);
209 return -1; 214 return -1;
210 } 215 }
@@ -220,30 +225,36 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
220 225
221static int 226static int
222timeout_connect(int sockfd, const struct sockaddr *serv_addr, 227timeout_connect(int sockfd, const struct sockaddr *serv_addr,
223 socklen_t addrlen, int timeout) 228 socklen_t addrlen, int *timeoutp)
224{ 229{
225 fd_set *fdset; 230 fd_set *fdset;
226 struct timeval tv; 231 struct timeval tv, t_start;
227 socklen_t optlen; 232 socklen_t optlen;
228 int optval, rc, result = -1; 233 int optval, rc, result = -1;
229 234
230 if (timeout <= 0) 235 gettimeofday(&t_start, NULL);
231 return (connect(sockfd, serv_addr, addrlen)); 236
237 if (*timeoutp <= 0) {
238 result = connect(sockfd, serv_addr, addrlen);
239 goto done;
240 }
232 241
233 set_nonblock(sockfd); 242 set_nonblock(sockfd);
234 rc = connect(sockfd, serv_addr, addrlen); 243 rc = connect(sockfd, serv_addr, addrlen);
235 if (rc == 0) { 244 if (rc == 0) {
236 unset_nonblock(sockfd); 245 unset_nonblock(sockfd);
237 return (0); 246 result = 0;
247 goto done;
248 }
249 if (errno != EINPROGRESS) {
250 result = -1;
251 goto done;
238 } 252 }
239 if (errno != EINPROGRESS)
240 return (-1);
241 253
242 fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS), 254 fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
243 sizeof(fd_mask)); 255 sizeof(fd_mask));
244 FD_SET(sockfd, fdset); 256 FD_SET(sockfd, fdset);
245 tv.tv_sec = timeout; 257 ms_to_timeval(&tv, *timeoutp);
246 tv.tv_usec = 0;
247 258
248 for (;;) { 259 for (;;) {
249 rc = select(sockfd + 1, NULL, fdset, NULL, &tv); 260 rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
@@ -282,6 +293,16 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
282 } 293 }
283 294
284 xfree(fdset); 295 xfree(fdset);
296
297 done:
298 if (result == 0 && *timeoutp > 0) {
299 ms_subtract_diff(&t_start, timeoutp);
300 if (*timeoutp <= 0) {
301 errno = ETIMEDOUT;
302 result = -1;
303 }
304 }
305
285 return (result); 306 return (result);
286} 307}
287 308
@@ -298,8 +319,8 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
298 */ 319 */
299int 320int
300ssh_connect(const char *host, struct sockaddr_storage * hostaddr, 321ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
301 u_short port, int family, int connection_attempts, 322 u_short port, int family, int connection_attempts, int *timeout_ms,
302 int needpriv, const char *proxy_command) 323 int want_keepalive, int needpriv, const char *proxy_command)
303{ 324{
304 int gaierr; 325 int gaierr;
305 int on = 1; 326 int on = 1;
@@ -320,8 +341,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
320 hints.ai_socktype = SOCK_STREAM; 341 hints.ai_socktype = SOCK_STREAM;
321 snprintf(strport, sizeof strport, "%u", port); 342 snprintf(strport, sizeof strport, "%u", port);
322 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) 343 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
323 fatal("%s: %.100s: %s", __progname, host, 344 fatal("%s: Could not resolve hostname %.100s: %s", __progname,
324 gai_strerror(gaierr)); 345 host, ssh_gai_strerror(gaierr));
325 346
326 for (attempt = 0; attempt < connection_attempts; attempt++) { 347 for (attempt = 0; attempt < connection_attempts; attempt++) {
327 if (attempt > 0) { 348 if (attempt > 0) {
@@ -352,7 +373,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
352 continue; 373 continue;
353 374
354 if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, 375 if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
355 options.connection_timeout) >= 0) { 376 timeout_ms) >= 0) {
356 /* Successful connection. */ 377 /* Successful connection. */
357 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); 378 memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
358 break; 379 break;
@@ -379,13 +400,15 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
379 debug("Connection established."); 400 debug("Connection established.");
380 401
381 /* Set SO_KEEPALIVE if requested. */ 402 /* Set SO_KEEPALIVE if requested. */
382 if (options.tcp_keep_alive && 403 if (want_keepalive &&
383 setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, 404 setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
384 sizeof(on)) < 0) 405 sizeof(on)) < 0)
385 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 406 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
386 407
387 /* Set the connection. */ 408 /* Set the connection. */
388 packet_set_connection(sock, sock); 409 packet_set_connection(sock, sock);
410 packet_set_timeout(options.server_alive_interval,
411 options.server_alive_count_max);
389 412
390 return 0; 413 return 0;
391} 414}
@@ -395,7 +418,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
395 * identification string. 418 * identification string.
396 */ 419 */
397static void 420static void
398ssh_exchange_identification(void) 421ssh_exchange_identification(int timeout_ms)
399{ 422{
400 char buf[256], remote_version[256]; /* must be same size! */ 423 char buf[256], remote_version[256]; /* must be same size! */
401 int remote_major, remote_minor, mismatch; 424 int remote_major, remote_minor, mismatch;
@@ -403,16 +426,44 @@ ssh_exchange_identification(void)
403 int connection_out = packet_get_connection_out(); 426 int connection_out = packet_get_connection_out();
404 int minor1 = PROTOCOL_MINOR_1; 427 int minor1 = PROTOCOL_MINOR_1;
405 u_int i, n; 428 u_int i, n;
429 size_t len;
430 int fdsetsz, remaining, rc;
431 struct timeval t_start, t_remaining;
432 fd_set *fdset;
433
434 fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
435 fdset = xcalloc(1, fdsetsz);
406 436
407 /* Read other side's version identification. */ 437 /* Read other side's version identification. */
438 remaining = timeout_ms;
408 for (n = 0;;) { 439 for (n = 0;;) {
409 for (i = 0; i < sizeof(buf) - 1; i++) { 440 for (i = 0; i < sizeof(buf) - 1; i++) {
410 size_t len = atomicio(read, connection_in, &buf[i], 1); 441 if (timeout_ms > 0) {
442 gettimeofday(&t_start, NULL);
443 ms_to_timeval(&t_remaining, remaining);
444 FD_SET(connection_in, fdset);
445 rc = select(connection_in + 1, fdset, NULL,
446 fdset, &t_remaining);
447 ms_subtract_diff(&t_start, &remaining);
448 if (rc == 0 || remaining <= 0)
449 fatal("Connection timed out during "
450 "banner exchange");
451 if (rc == -1) {
452 if (errno == EINTR)
453 continue;
454 fatal("ssh_exchange_identification: "
455 "select: %s", strerror(errno));
456 }
457 }
458
459 len = atomicio(read, connection_in, &buf[i], 1);
411 460
412 if (len != 1 && errno == EPIPE) 461 if (len != 1 && errno == EPIPE)
413 fatal("ssh_exchange_identification: Connection closed by remote host"); 462 fatal("ssh_exchange_identification: "
463 "Connection closed by remote host");
414 else if (len != 1) 464 else if (len != 1)
415 fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); 465 fatal("ssh_exchange_identification: "
466 "read: %.100s", strerror(errno));
416 if (buf[i] == '\r') { 467 if (buf[i] == '\r') {
417 buf[i] = '\n'; 468 buf[i] = '\n';
418 buf[i + 1] = 0; 469 buf[i + 1] = 0;
@@ -423,7 +474,8 @@ ssh_exchange_identification(void)
423 break; 474 break;
424 } 475 }
425 if (++n > 65536) 476 if (++n > 65536)
426 fatal("ssh_exchange_identification: No banner received"); 477 fatal("ssh_exchange_identification: "
478 "No banner received");
427 } 479 }
428 buf[sizeof(buf) - 1] = 0; 480 buf[sizeof(buf) - 1] = 0;
429 if (strncmp(buf, "SSH-", 4) == 0) 481 if (strncmp(buf, "SSH-", 4) == 0)
@@ -431,6 +483,7 @@ ssh_exchange_identification(void)
431 debug("ssh_exchange_identification: %s", buf); 483 debug("ssh_exchange_identification: %s", buf);
432 } 484 }
433 server_version_string = xstrdup(buf); 485 server_version_string = xstrdup(buf);
486 xfree(fdset);
434 487
435 /* 488 /*
436 * Check that the versions match. In future this might accept 489 * Check that the versions match. In future this might accept
@@ -484,10 +537,10 @@ ssh_exchange_identification(void)
484 (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, 537 (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
485 remote_major); 538 remote_major);
486 /* Send our own protocol version identification. */ 539 /* Send our own protocol version identification. */
487 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", 540 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
488 compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, 541 compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
489 compat20 ? PROTOCOL_MINOR_2 : minor1, 542 compat20 ? PROTOCOL_MINOR_2 : minor1,
490 SSH_VERSION); 543 SSH_VERSION, compat20 ? "\r\n" : "\n");
491 if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) 544 if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
492 fatal("write: %.100s", strerror(errno)); 545 fatal("write: %.100s", strerror(errno));
493 client_version_string = xstrdup(buf); 546 client_version_string = xstrdup(buf);
@@ -536,14 +589,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
536 Key *file_key; 589 Key *file_key;
537 const char *type = key_type(host_key); 590 const char *type = key_type(host_key);
538 char *ip = NULL, *host = NULL; 591 char *ip = NULL, *host = NULL;
539 char hostline[1000], *hostp, *fp; 592 char hostline[1000], *hostp, *fp, *ra;
540 HostStatus host_status; 593 HostStatus host_status;
541 HostStatus ip_status; 594 HostStatus ip_status;
542 int r, local = 0, host_ip_differ = 0; 595 int r, local = 0, host_ip_differ = 0;
543 int salen; 596 int salen;
544 char ntop[NI_MAXHOST]; 597 char ntop[NI_MAXHOST];
545 char msg[1024]; 598 char msg[1024];
546 int len, host_line, ip_line; 599 int len, host_line, ip_line, cancelled_forwarding = 0;
547 const char *host_file = NULL, *ip_file = NULL; 600 const char *host_file = NULL, *ip_file = NULL;
548 601
549 /* 602 /*
@@ -590,6 +643,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
590 } else { 643 } else {
591 ip = xstrdup("<no hostip for proxy command>"); 644 ip = xstrdup("<no hostip for proxy command>");
592 } 645 }
646
593 /* 647 /*
594 * Turn off check_host_ip if the connection is to localhost, via proxy 648 * Turn off check_host_ip if the connection is to localhost, via proxy
595 * command or if we don't have a hostname to compare with 649 * command or if we don't have a hostname to compare with
@@ -674,6 +728,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
674 logit("Warning: Permanently added the %s host " 728 logit("Warning: Permanently added the %s host "
675 "key for IP address '%.128s' to the list " 729 "key for IP address '%.128s' to the list "
676 "of known hosts.", type, ip); 730 "of known hosts.", type, ip);
731 } else if (options.visual_host_key) {
732 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
733 ra = key_fingerprint(host_key, SSH_FP_MD5,
734 SSH_FP_RANDOMART);
735 logit("Host key fingerprint is %s\n%s\n", fp, ra);
736 xfree(ra);
737 xfree(fp);
677 } 738 }
678 break; 739 break;
679 case HOST_NEW: 740 case HOST_NEW:
@@ -709,6 +770,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
709 snprintf(msg1, sizeof(msg1), "."); 770 snprintf(msg1, sizeof(msg1), ".");
710 /* The default */ 771 /* The default */
711 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); 772 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
773 ra = key_fingerprint(host_key, SSH_FP_MD5,
774 SSH_FP_RANDOMART);
712 msg2[0] = '\0'; 775 msg2[0] = '\0';
713 if (options.verify_host_key_dns) { 776 if (options.verify_host_key_dns) {
714 if (matching_host_key_dns) 777 if (matching_host_key_dns)
@@ -723,10 +786,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
723 snprintf(msg, sizeof(msg), 786 snprintf(msg, sizeof(msg),
724 "The authenticity of host '%.200s (%s)' can't be " 787 "The authenticity of host '%.200s (%s)' can't be "
725 "established%s\n" 788 "established%s\n"
726 "%s key fingerprint is %s.\n%s" 789 "%s key fingerprint is %s.%s%s\n%s"
727 "Are you sure you want to continue connecting " 790 "Are you sure you want to continue connecting "
728 "(yes/no)? ", 791 "(yes/no)? ",
729 host, ip, msg1, type, fp, msg2); 792 host, ip, msg1, type, fp,
793 options.visual_host_key ? "\n" : "",
794 options.visual_host_key ? ra : "",
795 msg2);
796 xfree(ra);
730 xfree(fp); 797 xfree(fp);
731 if (!confirm(msg)) 798 if (!confirm(msg))
732 goto fail; 799 goto fail;
@@ -779,7 +846,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
779 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); 846 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @");
780 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 847 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
781 error("The %s host key for %s has changed,", type, host); 848 error("The %s host key for %s has changed,", type, host);
782 error("and the key for the according IP address %s", ip); 849 error("and the key for the corresponding IP address %s", ip);
783 error("%s. This could either mean that", key_msg); 850 error("%s. This could either mean that", key_msg);
784 error("DNS SPOOFING is happening or the IP address for the host"); 851 error("DNS SPOOFING is happening or the IP address for the host");
785 error("and its host key have changed at the same time."); 852 error("and its host key have changed at the same time.");
@@ -811,27 +878,32 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
811 error("Password authentication is disabled to avoid " 878 error("Password authentication is disabled to avoid "
812 "man-in-the-middle attacks."); 879 "man-in-the-middle attacks.");
813 options.password_authentication = 0; 880 options.password_authentication = 0;
881 cancelled_forwarding = 1;
814 } 882 }
815 if (options.kbd_interactive_authentication) { 883 if (options.kbd_interactive_authentication) {
816 error("Keyboard-interactive authentication is disabled" 884 error("Keyboard-interactive authentication is disabled"
817 " to avoid man-in-the-middle attacks."); 885 " to avoid man-in-the-middle attacks.");
818 options.kbd_interactive_authentication = 0; 886 options.kbd_interactive_authentication = 0;
819 options.challenge_response_authentication = 0; 887 options.challenge_response_authentication = 0;
888 cancelled_forwarding = 1;
820 } 889 }
821 if (options.challenge_response_authentication) { 890 if (options.challenge_response_authentication) {
822 error("Challenge/response authentication is disabled" 891 error("Challenge/response authentication is disabled"
823 " to avoid man-in-the-middle attacks."); 892 " to avoid man-in-the-middle attacks.");
824 options.challenge_response_authentication = 0; 893 options.challenge_response_authentication = 0;
894 cancelled_forwarding = 1;
825 } 895 }
826 if (options.forward_agent) { 896 if (options.forward_agent) {
827 error("Agent forwarding is disabled to avoid " 897 error("Agent forwarding is disabled to avoid "
828 "man-in-the-middle attacks."); 898 "man-in-the-middle attacks.");
829 options.forward_agent = 0; 899 options.forward_agent = 0;
900 cancelled_forwarding = 1;
830 } 901 }
831 if (options.forward_x11) { 902 if (options.forward_x11) {
832 error("X11 forwarding is disabled to avoid " 903 error("X11 forwarding is disabled to avoid "
833 "man-in-the-middle attacks."); 904 "man-in-the-middle attacks.");
834 options.forward_x11 = 0; 905 options.forward_x11 = 0;
906 cancelled_forwarding = 1;
835 } 907 }
836 if (options.num_local_forwards > 0 || 908 if (options.num_local_forwards > 0 ||
837 options.num_remote_forwards > 0) { 909 options.num_remote_forwards > 0) {
@@ -839,12 +911,18 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
839 "man-in-the-middle attacks."); 911 "man-in-the-middle attacks.");
840 options.num_local_forwards = 912 options.num_local_forwards =
841 options.num_remote_forwards = 0; 913 options.num_remote_forwards = 0;
914 cancelled_forwarding = 1;
842 } 915 }
843 if (options.tun_open != SSH_TUNMODE_NO) { 916 if (options.tun_open != SSH_TUNMODE_NO) {
844 error("Tunnel forwarding is disabled to avoid " 917 error("Tunnel forwarding is disabled to avoid "
845 "man-in-the-middle attacks."); 918 "man-in-the-middle attacks.");
846 options.tun_open = SSH_TUNMODE_NO; 919 options.tun_open = SSH_TUNMODE_NO;
920 cancelled_forwarding = 1;
847 } 921 }
922 if (options.exit_on_forward_failure && cancelled_forwarding)
923 fatal("Error: forwarding disabled due to host key "
924 "check failure");
925
848 /* 926 /*
849 * XXX Should permit the user to change to use the new id. 927 * XXX Should permit the user to change to use the new id.
850 * This could be done by converting the host key to an 928 * This could be done by converting the host key to an
@@ -943,7 +1021,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
943 */ 1021 */
944void 1022void
945ssh_login(Sensitive *sensitive, const char *orighost, 1023ssh_login(Sensitive *sensitive, const char *orighost,
946 struct sockaddr *hostaddr, struct passwd *pw) 1024 struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms)
947{ 1025{
948 char *host, *cp; 1026 char *host, *cp;
949 char *server_user, *local_user; 1027 char *server_user, *local_user;
@@ -958,7 +1036,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
958 *cp = (char)tolower(*cp); 1036 *cp = (char)tolower(*cp);
959 1037
960 /* Exchange protocol version identification strings with the server. */ 1038 /* Exchange protocol version identification strings with the server. */
961 ssh_exchange_identification(); 1039 ssh_exchange_identification(timeout_ms);
962 1040
963 /* Put the connection into non-blocking mode. */ 1041 /* Put the connection into non-blocking mode. */
964 packet_set_nonblocking(); 1042 packet_set_nonblocking();
@@ -997,18 +1075,20 @@ static int
997show_key_from_file(const char *file, const char *host, int keytype) 1075show_key_from_file(const char *file, const char *host, int keytype)
998{ 1076{
999 Key *found; 1077 Key *found;
1000 char *fp; 1078 char *fp, *ra;
1001 int line, ret; 1079 int line, ret;
1002 1080
1003 found = key_new(keytype); 1081 found = key_new(keytype);
1004 if ((ret = lookup_key_in_hostfile_by_type(file, host, 1082 if ((ret = lookup_key_in_hostfile_by_type(file, host,
1005 keytype, found, &line))) { 1083 keytype, found, &line))) {
1006 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); 1084 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
1085 ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART);
1007 logit("WARNING: %s key found for host %s\n" 1086 logit("WARNING: %s key found for host %s\n"
1008 "in %s:%d\n" 1087 "in %s:%d\n"
1009 "%s key fingerprint %s.", 1088 "%s key fingerprint %s.\n%s\n",
1010 key_type(found), host, file, line, 1089 key_type(found), host, file, line,
1011 key_type(found), fp); 1090 key_type(found), fp, ra);
1091 xfree(ra);
1012 xfree(fp); 1092 xfree(fp);
1013 } 1093 }
1014 key_free(found); 1094 key_free(found);
diff --git a/sshconnect.h b/sshconnect.h
index 4e66bbffc..75bde1a4d 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.h,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: sshconnect.h,v 1.24 2007/09/04 11:15:56 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -33,10 +33,10 @@ struct Sensitive {
33 33
34int 34int
35ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, 35ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int,
36 int, const char *); 36 int *, int, int, const char *);
37 37
38void 38void
39ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *); 39ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int);
40 40
41int verify_host_key(char *, struct sockaddr *, Key *); 41int verify_host_key(char *, struct sockaddr *, Key *);
42 42
diff --git a/sshconnect2.c b/sshconnect2.c
index 208df078c..389bec9e4 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.164 2007/05/17 23:53:41 jolan Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.166 2008/07/17 08:48:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -38,6 +38,9 @@
38#include <stdio.h> 38#include <stdio.h>
39#include <string.h> 39#include <string.h>
40#include <unistd.h> 40#include <unistd.h>
41#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H)
42#include <vis.h>
43#endif
41 44
42#include "openbsd-compat/sys-queue.h" 45#include "openbsd-compat/sys-queue.h"
43 46
@@ -130,7 +133,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
130 options.hostkeyalgorithms; 133 options.hostkeyalgorithms;
131 134
132 if (options.rekey_limit) 135 if (options.rekey_limit)
133 packet_set_rekey_limit(options.rekey_limit); 136 packet_set_rekey_limit((u_int32_t)options.rekey_limit);
134 137
135 /* start key exchange */ 138 /* start key exchange */
136 kex = kex_setup(myproposal); 139 kex = kex_setup(myproposal);
@@ -374,14 +377,21 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
374void 377void
375input_userauth_banner(int type, u_int32_t seq, void *ctxt) 378input_userauth_banner(int type, u_int32_t seq, void *ctxt)
376{ 379{
377 char *msg, *lang; 380 char *msg, *raw, *lang;
381 u_int len;
378 382
379 debug3("input_userauth_banner"); 383 debug3("input_userauth_banner");
380 msg = packet_get_string(NULL); 384 raw = packet_get_string(&len);
381 lang = packet_get_string(NULL); 385 lang = packet_get_string(NULL);
382 if (options.log_level >= SYSLOG_LEVEL_INFO) 386 if (options.log_level >= SYSLOG_LEVEL_INFO) {
387 if (len > 65536)
388 len = 65536;
389 msg = xmalloc(len * 4); /* max expansion from strnvis() */
390 strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL);
383 fprintf(stderr, "%s", msg); 391 fprintf(stderr, "%s", msg);
384 xfree(msg); 392 xfree(msg);
393 }
394 xfree(raw);
385 xfree(lang); 395 xfree(lang);
386} 396}
387 397
diff --git a/sshd.0 b/sshd.0
index d2ffaacfa..04d64776e 100644
--- a/sshd.0
+++ b/sshd.0
@@ -4,8 +4,9 @@ NAME
4 sshd - OpenSSH SSH daemon 4 sshd - OpenSSH SSH daemon
5 5
6SYNOPSIS 6SYNOPSIS
7 sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time] 7 sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]
8 [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len] 8 [-g login_grace_time] [-h host_key_file] [-k key_gen_time]
9 [-o option] [-p port] [-u len]
9 10
10DESCRIPTION 11DESCRIPTION
11 sshd (OpenSSH Daemon) is the daemon program for ssh(1). Together these 12 sshd (OpenSSH Daemon) is the daemon program for ssh(1). Together these
@@ -31,7 +32,17 @@ DESCRIPTION
31 32
32 -b bits 33 -b bits
33 Specifies the number of bits in the ephemeral protocol version 1 34 Specifies the number of bits in the ephemeral protocol version 1
34 server key (default 768). 35 server key (default 1024).
36
37 -C connection_spec
38 Specify the connection parameters to use for the -T extended test
39 mode. If provided, any Match directives in the configuration
40 file that would apply to the specified user, host, and address
41 will be set before the configuration is written to standard out-
42 put. The connection parameters are supplied as keyword=value
43 pairs. The keywords are ``user'', ``host'', and ``addr''. All
44 are required and may be supplied in any order, either with multi-
45 ple -C options or as a comma-separated list.
35 46
36 -D When this option is specified, sshd will not detach and does not 47 -D When this option is specified, sshd will not detach and does not
37 become a daemon. This allows easy monitoring of sshd. 48 become a daemon. This allows easy monitoring of sshd.
@@ -98,6 +109,11 @@ DESCRIPTION
98 ginning, authentication, and termination of each connection is 109 ginning, authentication, and termination of each connection is
99 logged. 110 logged.
100 111
112 -T Extended test mode. Check the validity of the configuration
113 file, output the effective configuration to stdout and then exit.
114 Optionally, Match rules may be applied by specifying the connec-
115 tion parameters using one or more -C options.
116
101 -t Test mode. Only check the validity of the configuration file and 117 -t Test mode. Only check the validity of the configuration file and
102 sanity of the keys. This is useful for updating sshd reliably as 118 sanity of the keys. This is useful for updating sshd reliably as
103 configuration options may change. 119 configuration options may change.
@@ -289,18 +305,22 @@ AUTHORIZED_KEYS FILE FORMAT
289 This option is automatically disabled if UseLogin is enabled. 305 This option is automatically disabled if UseLogin is enabled.
290 306
291 from="pattern-list" 307 from="pattern-list"
292 Specifies that in addition to public key authentication, the 308 Specifies that in addition to public key authentication, either
293 canonical name of the remote host must be present in the comma- 309 the canonical name of the remote host or its IP address must be
294 separated list of patterns. The purpose of this option is to op- 310 present in the comma-separated list of patterns. See PATTERNS in
295 tionally increase security: public key authentication by itself 311 ssh_config(5) for more information on patterns.
296 does not trust the network or name servers or anything (but the 312
297 key); however, if somebody somehow steals the key, the key per- 313 In addition to the wildcard matching that may be applied to host-
298 mits an intruder to log in from anywhere in the world. This ad- 314 names or addresses, a from stanza may match IP addressess using
299 ditional option makes using a stolen key more difficult (name 315 CIDR address/masklen notation.
300 servers and/or routers would have to be compromised in addition 316
301 to just the key). 317 The purpose of this option is to optionally increase security:
302 318 public key authentication by itself does not trust the network or
303 See PATTERNS in ssh_config(5) for more information on patterns. 319 name servers or anything (but the key); however, if somebody
320 somehow steals the key, the key permits an intruder to log in
321 from anywhere in the world. This additional option makes using a
322 stolen key more difficult (name servers and/or routers would have
323 to be compromised in addition to just the key).
304 324
305 no-agent-forwarding 325 no-agent-forwarding
306 Forbids authentication agent forwarding when this key is used for 326 Forbids authentication agent forwarding when this key is used for
@@ -313,6 +333,9 @@ AUTHORIZED_KEYS FILE FORMAT
313 333
314 no-pty Prevents tty allocation (a request to allocate a pty will fail). 334 no-pty Prevents tty allocation (a request to allocate a pty will fail).
315 335
336 no-user-rc
337 Disables execution of ~/.ssh/rc.
338
316 no-X11-forwarding 339 no-X11-forwarding
317 Forbids X11 forwarding when this key is used for authentication. 340 Forbids X11 forwarding when this key is used for authentication.
318 Any X11 forward requests by the client will return an error. 341 Any X11 forward requests by the client will return an error.
@@ -417,6 +440,13 @@ FILES
417 host-based authentication without permitting login with 440 host-based authentication without permitting login with
418 rlogin/rsh. 441 rlogin/rsh.
419 442
443 ~/.ssh/
444 This directory is the default location for all user-specific con-
445 figuration and authentication information. There is no general
446 requirement to keep the entire contents of this directory secret,
447 but the recommended permissions are read/write/execute for the
448 user, and not accessible by others.
449
420 ~/.ssh/authorized_keys 450 ~/.ssh/authorized_keys
421 Lists the public keys (RSA/DSA) that can be used for logging in 451 Lists the public keys (RSA/DSA) that can be used for logging in
422 as this user. The format of this file is described above. The 452 as this user. The format of this file is described above. The
@@ -542,4 +572,4 @@ CAVEATS
542 System security is not improved unless rshd, rlogind, and rexecd are dis- 572 System security is not improved unless rshd, rlogind, and rexecd are dis-
543 abled (thus completely disabling rlogin and rsh into the machine). 573 abled (thus completely disabling rlogin and rsh into the machine).
544 574
545OpenBSD 4.2 August 16, 2007 9 575OpenBSD 4.4 July 2, 2008 9
diff --git a/sshd.8 b/sshd.8
index 12c2cefec..c4c4181fc 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd.8,v 1.237 2007/06/07 19:37:34 pvalchev Exp $ 37.\" $OpenBSD: sshd.8,v 1.246 2008/07/02 02:24:18 djm Exp $
38.Dd $Mdocdate: August 16 2007 $ 38.Dd $Mdocdate: July 2 2008 $
39.Dt SSHD 8 39.Dt SSHD 8
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -44,8 +44,9 @@
44.Sh SYNOPSIS 44.Sh SYNOPSIS
45.Nm sshd 45.Nm sshd
46.Bk -words 46.Bk -words
47.Op Fl 46Ddeiqt 47.Op Fl 46DdeiqTt
48.Op Fl b Ar bits 48.Op Fl b Ar bits
49.Op Fl C Ar connection_spec
49.Op Fl f Ar config_file 50.Op Fl f Ar config_file
50.Op Fl g Ar login_grace_time 51.Op Fl g Ar login_grace_time
51.Op Fl h Ar host_key_file 52.Op Fl h Ar host_key_file
@@ -99,7 +100,25 @@ Forces
99to use IPv6 addresses only. 100to use IPv6 addresses only.
100.It Fl b Ar bits 101.It Fl b Ar bits
101Specifies the number of bits in the ephemeral protocol version 1 102Specifies the number of bits in the ephemeral protocol version 1
102server key (default 768). 103server key (default 1024).
104.It Fl C Ar connection_spec
105Specify the connection parameters to use for the
106.Fl T
107extended test mode.
108If provided, any
109.Cm Match
110directives in the configuration file
111that would apply to the specified user, host, and address will be set before
112the configuration is written to standard output.
113The connection parameters are supplied as keyword=value pairs.
114The keywords are
115.Dq user ,
116.Dq host ,
117and
118.Dq addr .
119All are required and may be supplied in any order, either with multiple
120.Fl C
121options or as a comma-separated list.
103.It Fl D 122.It Fl D
104When this option is specified, 123When this option is specified,
105.Nm 124.Nm
@@ -191,6 +210,15 @@ Quiet mode.
191Nothing is sent to the system log. 210Nothing is sent to the system log.
192Normally the beginning, 211Normally the beginning,
193authentication, and termination of each connection is logged. 212authentication, and termination of each connection is logged.
213.It Fl T
214Extended test mode.
215Check the validity of the configuration file, output the effective configuration
216to stdout and then exit.
217Optionally,
218.Cm Match
219rules may be applied by specifying the connection parameters using one or more
220.Fl C
221options.
194.It Fl t 222.It Fl t
195Test mode. 223Test mode.
196Only check the validity of the configuration file and sanity of the keys. 224Only check the validity of the configuration file and sanity of the keys.
@@ -503,23 +531,27 @@ This option is automatically disabled if
503.Cm UseLogin 531.Cm UseLogin
504is enabled. 532is enabled.
505.It Cm from="pattern-list" 533.It Cm from="pattern-list"
506Specifies that in addition to public key authentication, the canonical name 534Specifies that in addition to public key authentication, either the canonical
507of the remote host must be present in the comma-separated list of 535name of the remote host or its IP address must be present in the
508patterns. 536comma-separated list of patterns.
509The purpose
510of this option is to optionally increase security: public key authentication
511by itself does not trust the network or name servers or anything (but
512the key); however, if somebody somehow steals the key, the key
513permits an intruder to log in from anywhere in the world.
514This additional option makes using a stolen key more difficult (name
515servers and/or routers would have to be compromised in addition to
516just the key).
517.Pp
518See 537See
519.Sx PATTERNS 538.Sx PATTERNS
520in 539in
521.Xr ssh_config 5 540.Xr ssh_config 5
522for more information on patterns. 541for more information on patterns.
542.Pp
543In addition to the wildcard matching that may be applied to hostnames or
544addresses, a
545.Cm from
546stanza may match IP addressess using CIDR address/masklen notation.
547.Pp
548The purpose of this option is to optionally increase security: public key
549authentication by itself does not trust the network or name servers or
550anything (but the key); however, if somebody somehow steals the key, the key
551permits an intruder to log in from anywhere in the world.
552This additional option makes using a stolen key more difficult (name
553servers and/or routers would have to be compromised in addition to
554just the key).
523.It Cm no-agent-forwarding 555.It Cm no-agent-forwarding
524Forbids authentication agent forwarding when this key is used for 556Forbids authentication agent forwarding when this key is used for
525authentication. 557authentication.
@@ -531,6 +563,9 @@ This might be used, e.g. in connection with the
531option. 563option.
532.It Cm no-pty 564.It Cm no-pty
533Prevents tty allocation (a request to allocate a pty will fail). 565Prevents tty allocation (a request to allocate a pty will fail).
566.It Cm no-user-rc
567Disables execution of
568.Pa ~/.ssh/rc .
534.It Cm no-X11-forwarding 569.It Cm no-X11-forwarding
535Forbids X11 forwarding when this key is used for authentication. 570Forbids X11 forwarding when this key is used for authentication.
536Any X11 forward requests by the client will return an error. 571Any X11 forward requests by the client will return an error.
@@ -682,6 +717,13 @@ This file is used in exactly the same way as
682but allows host-based authentication without permitting login with 717but allows host-based authentication without permitting login with
683rlogin/rsh. 718rlogin/rsh.
684.Pp 719.Pp
720.It ~/.ssh/
721This directory is the default location for all user-specific configuration
722and authentication information.
723There is no general requirement to keep the entire contents of this directory
724secret, but the recommended permissions are read/write/execute for the user,
725and not accessible by others.
726.Pp
685.It ~/.ssh/authorized_keys 727.It ~/.ssh/authorized_keys
686Lists the public keys (RSA/DSA) that can be used for logging in as this user. 728Lists the public keys (RSA/DSA) that can be used for logging in as this user.
687The format of this file is described above. 729The format of this file is described above.
diff --git a/sshd.c b/sshd.c
index 04778ea99..6e5bb5476 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.351 2007/05/22 10:18:52 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.364 2008/07/10 18:08:11 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
@@ -54,6 +54,7 @@
54# include <sys/time.h> 54# include <sys/time.h>
55#endif 55#endif
56#include "openbsd-compat/sys-tree.h" 56#include "openbsd-compat/sys-tree.h"
57#include "openbsd-compat/sys-queue.h"
57#include <sys/wait.h> 58#include <sys/wait.h>
58 59
59#include <errno.h> 60#include <errno.h>
@@ -75,6 +76,8 @@
75#include <openssl/bn.h> 76#include <openssl/bn.h>
76#include <openssl/md5.h> 77#include <openssl/md5.h>
77#include <openssl/rand.h> 78#include <openssl/rand.h>
79#include "openbsd-compat/openssl-compat.h"
80
78#ifdef HAVE_SECUREWARE 81#ifdef HAVE_SECUREWARE
79#include <sys/security.h> 82#include <sys/security.h>
80#include <prot.h> 83#include <prot.h>
@@ -120,8 +123,8 @@
120#ifdef LIBWRAP 123#ifdef LIBWRAP
121#include <tcpd.h> 124#include <tcpd.h>
122#include <syslog.h> 125#include <syslog.h>
123int allow_severity = LOG_INFO; 126int allow_severity;
124int deny_severity = LOG_WARNING; 127int deny_severity;
125#endif /* LIBWRAP */ 128#endif /* LIBWRAP */
126 129
127#ifndef O_NOCTTY 130#ifndef O_NOCTTY
@@ -366,9 +369,6 @@ grace_alarm_handler(int sig)
366static void 369static void
367generate_ephemeral_server_key(void) 370generate_ephemeral_server_key(void)
368{ 371{
369 u_int32_t rnd = 0;
370 int i;
371
372 verbose("Generating %s%d bit RSA key.", 372 verbose("Generating %s%d bit RSA key.",
373 sensitive_data.server_key ? "new " : "", options.server_key_bits); 373 sensitive_data.server_key ? "new " : "", options.server_key_bits);
374 if (sensitive_data.server_key != NULL) 374 if (sensitive_data.server_key != NULL)
@@ -377,12 +377,7 @@ generate_ephemeral_server_key(void)
377 options.server_key_bits); 377 options.server_key_bits);
378 verbose("RSA key generation complete."); 378 verbose("RSA key generation complete.");
379 379
380 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 380 arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
381 if (i % 4 == 0)
382 rnd = arc4random();
383 sensitive_data.ssh1_cookie[i] = rnd & 0xff;
384 rnd >>= 8;
385 }
386 arc4random_stir(); 381 arc4random_stir();
387} 382}
388 383
@@ -404,7 +399,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
404 int mismatch; 399 int mismatch;
405 int remote_major, remote_minor; 400 int remote_major, remote_minor;
406 int major, minor; 401 int major, minor;
407 char *s; 402 char *s, *newline = "\n";
408 char buf[256]; /* Must not be larger than remote_version. */ 403 char buf[256]; /* Must not be larger than remote_version. */
409 char remote_version[256]; /* Must be at least as big as buf. */ 404 char remote_version[256]; /* Must be at least as big as buf. */
410 405
@@ -415,11 +410,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
415 } else if (options.protocol & SSH_PROTO_2) { 410 } else if (options.protocol & SSH_PROTO_2) {
416 major = PROTOCOL_MAJOR_2; 411 major = PROTOCOL_MAJOR_2;
417 minor = PROTOCOL_MINOR_2; 412 minor = PROTOCOL_MINOR_2;
413 newline = "\r\n";
418 } else { 414 } else {
419 major = PROTOCOL_MAJOR_1; 415 major = PROTOCOL_MAJOR_1;
420 minor = PROTOCOL_MINOR_1; 416 minor = PROTOCOL_MINOR_1;
421 } 417 }
422 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); 418 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
419 SSH_VERSION, newline);
423 server_version_string = xstrdup(buf); 420 server_version_string = xstrdup(buf);
424 421
425 /* Send our protocol version identification. */ 422 /* Send our protocol version identification. */
@@ -581,15 +578,14 @@ demote_sensitive_data(void)
581static void 578static void
582privsep_preauth_child(void) 579privsep_preauth_child(void)
583{ 580{
584 u_int32_t rnd[256]; 581 u_int32_t rnd[256];
585 gid_t gidset[1]; 582 gid_t gidset[1];
586 int i;
587 583
588 /* Enable challenge-response authentication for privilege separation */ 584 /* Enable challenge-response authentication for privilege separation */
589 privsep_challenge_enable(); 585 privsep_challenge_enable();
590 586
591 for (i = 0; i < 256; i++) 587 arc4random_stir();
592 rnd[i] = arc4random(); 588 arc4random_buf(rnd, sizeof(rnd));
593 RAND_seed(rnd, sizeof(rnd)); 589 RAND_seed(rnd, sizeof(rnd));
594 590
595 /* Demote the private keys to public keys. */ 591 /* Demote the private keys to public keys. */
@@ -662,6 +658,8 @@ privsep_preauth(Authctxt *authctxt)
662static void 658static void
663privsep_postauth(Authctxt *authctxt) 659privsep_postauth(Authctxt *authctxt)
664{ 660{
661 u_int32_t rnd[256];
662
665#ifdef DISABLE_FD_PASSING 663#ifdef DISABLE_FD_PASSING
666 if (1) { 664 if (1) {
667#else 665#else
@@ -679,7 +677,7 @@ privsep_postauth(Authctxt *authctxt)
679 if (pmonitor->m_pid == -1) 677 if (pmonitor->m_pid == -1)
680 fatal("fork of unprivileged child failed"); 678 fatal("fork of unprivileged child failed");
681 else if (pmonitor->m_pid != 0) { 679 else if (pmonitor->m_pid != 0) {
682 debug2("User child is on pid %ld", (long)pmonitor->m_pid); 680 verbose("User child is on pid %ld", (long)pmonitor->m_pid);
683 close(pmonitor->m_recvfd); 681 close(pmonitor->m_recvfd);
684 buffer_clear(&loginmsg); 682 buffer_clear(&loginmsg);
685 monitor_child_postauth(pmonitor); 683 monitor_child_postauth(pmonitor);
@@ -693,6 +691,10 @@ privsep_postauth(Authctxt *authctxt)
693 /* Demote the private keys to public keys. */ 691 /* Demote the private keys to public keys. */
694 demote_sensitive_data(); 692 demote_sensitive_data();
695 693
694 arc4random_stir();
695 arc4random_buf(rnd, sizeof(rnd));
696 RAND_seed(rnd, sizeof(rnd));
697
696 /* Drop privileges */ 698 /* Drop privileges */
697 do_setusercontext(authctxt->pw); 699 do_setusercontext(authctxt->pw);
698 700
@@ -792,7 +794,7 @@ drop_connection(int startups)
792 p *= startups - options.max_startups_begin; 794 p *= startups - options.max_startups_begin;
793 p /= options.max_startups - options.max_startups_begin; 795 p /= options.max_startups - options.max_startups_begin;
794 p += options.max_startups_rate; 796 p += options.max_startups_rate;
795 r = arc4random() % 100; 797 r = arc4random_uniform(100);
796 798
797 debug("drop_connection: p %d, r %d", p, r); 799 debug("drop_connection: p %d, r %d", p, r);
798 return (r < p) ? 1 : 0; 800 return (r < p) ? 1 : 0;
@@ -804,8 +806,9 @@ usage(void)
804 fprintf(stderr, "%s, %s\n", 806 fprintf(stderr, "%s, %s\n",
805 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); 807 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
806 fprintf(stderr, 808 fprintf(stderr,
807"usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" 809"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n"
808" [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" 810" [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n"
811" [-o option] [-p port] [-u len]\n"
809 ); 812 );
810 exit(1); 813 exit(1);
811} 814}
@@ -953,8 +956,7 @@ server_listen(void)
953 ntop, sizeof(ntop), strport, sizeof(strport), 956 ntop, sizeof(ntop), strport, sizeof(strport),
954 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 957 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
955 error("getnameinfo failed: %.100s", 958 error("getnameinfo failed: %.100s",
956 (ret != EAI_SYSTEM) ? gai_strerror(ret) : 959 ssh_gai_strerror(ret));
957 strerror(errno));
958 continue; 960 continue;
959 } 961 }
960 /* Create socket for listening. */ 962 /* Create socket for listening. */
@@ -977,6 +979,16 @@ server_listen(void)
977 &on, sizeof(on)) == -1) 979 &on, sizeof(on)) == -1)
978 error("setsockopt SO_REUSEADDR: %s", strerror(errno)); 980 error("setsockopt SO_REUSEADDR: %s", strerror(errno));
979 981
982#ifdef IPV6_V6ONLY
983 /* Only communicate in IPv6 over AF_INET6 sockets. */
984 if (ai->ai_family == AF_INET6) {
985 if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
986 &on, sizeof(on)) == -1)
987 error("setsockopt IPV6_V6ONLY: %s",
988 strerror(errno));
989 }
990#endif
991
980 debug("Bind to port %s on %s.", strport, ntop); 992 debug("Bind to port %s on %s.", strport, ntop);
981 993
982 /* Bind the socket to the desired port. */ 994 /* Bind the socket to the desired port. */
@@ -1084,7 +1096,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1084 *newsock = accept(listen_socks[i], 1096 *newsock = accept(listen_socks[i],
1085 (struct sockaddr *)&from, &fromlen); 1097 (struct sockaddr *)&from, &fromlen);
1086 if (*newsock < 0) { 1098 if (*newsock < 0) {
1087 if (errno != EINTR && errno != EWOULDBLOCK) 1099 if (errno != EINTR && errno != EAGAIN &&
1100 errno != EWOULDBLOCK)
1088 error("accept: %.100s", strerror(errno)); 1101 error("accept: %.100s", strerror(errno));
1089 continue; 1102 continue;
1090 } 1103 }
@@ -1231,9 +1244,12 @@ main(int ac, char **av)
1231 int opt, i, on = 1; 1244 int opt, i, on = 1;
1232 int sock_in = -1, sock_out = -1, newsock = -1; 1245 int sock_in = -1, sock_out = -1, newsock = -1;
1233 const char *remote_ip; 1246 const char *remote_ip;
1247 char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
1234 int remote_port; 1248 int remote_port;
1235 char *line; 1249 char *line, *p, *cp;
1236 int config_s[2] = { -1 , -1 }; 1250 int config_s[2] = { -1 , -1 };
1251 u_int64_t ibytes, obytes;
1252 mode_t new_umask;
1237 Key *key; 1253 Key *key;
1238 Authctxt *authctxt; 1254 Authctxt *authctxt;
1239 1255
@@ -1267,7 +1283,7 @@ main(int ac, char **av)
1267 initialize_server_options(&options); 1283 initialize_server_options(&options);
1268 1284
1269 /* Parse command-line arguments. */ 1285 /* Parse command-line arguments. */
1270 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { 1286 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) {
1271 switch (opt) { 1287 switch (opt) {
1272 case '4': 1288 case '4':
1273 options.address_family = AF_INET; 1289 options.address_family = AF_INET;
@@ -1345,6 +1361,25 @@ main(int ac, char **av)
1345 case 't': 1361 case 't':
1346 test_flag = 1; 1362 test_flag = 1;
1347 break; 1363 break;
1364 case 'T':
1365 test_flag = 2;
1366 break;
1367 case 'C':
1368 cp = optarg;
1369 while ((p = strsep(&cp, ",")) && *p != '\0') {
1370 if (strncmp(p, "addr=", 5) == 0)
1371 test_addr = xstrdup(p + 5);
1372 else if (strncmp(p, "host=", 5) == 0)
1373 test_host = xstrdup(p + 5);
1374 else if (strncmp(p, "user=", 5) == 0)
1375 test_user = xstrdup(p + 5);
1376 else {
1377 fprintf(stderr, "Invalid test "
1378 "mode specification %s\n", p);
1379 exit(1);
1380 }
1381 }
1382 break;
1348 case 'u': 1383 case 'u':
1349 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); 1384 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL);
1350 if (utmp_len > MAXHOSTNAMELEN) { 1385 if (utmp_len > MAXHOSTNAMELEN) {
@@ -1367,7 +1402,7 @@ main(int ac, char **av)
1367 } 1402 }
1368 if (rexeced_flag || inetd_flag) 1403 if (rexeced_flag || inetd_flag)
1369 rexec_flag = 0; 1404 rexec_flag = 0;
1370 if (rexec_flag && (av[0] == NULL || *av[0] != '/')) 1405 if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
1371 fatal("sshd re-exec requires execution with an absolute path"); 1406 fatal("sshd re-exec requires execution with an absolute path");
1372 if (rexeced_flag) 1407 if (rexeced_flag)
1373 closefrom(REEXEC_MIN_FREE_FD); 1408 closefrom(REEXEC_MIN_FREE_FD);
@@ -1406,6 +1441,21 @@ main(int ac, char **av)
1406 sensitive_data.have_ssh1_key = 0; 1441 sensitive_data.have_ssh1_key = 0;
1407 sensitive_data.have_ssh2_key = 0; 1442 sensitive_data.have_ssh2_key = 0;
1408 1443
1444 /*
1445 * If we're doing an extended config test, make sure we have all of
1446 * the parameters we need. If we're not doing an extended test,
1447 * do not silently ignore connection test params.
1448 */
1449 if (test_flag >= 2 &&
1450 (test_user != NULL || test_host != NULL || test_addr != NULL)
1451 && (test_user == NULL || test_host == NULL || test_addr == NULL))
1452 fatal("user, host and addr are all required when testing "
1453 "Match configs");
1454 if (test_flag < 2 && (test_user != NULL || test_host != NULL ||
1455 test_addr != NULL))
1456 fatal("Config test connection parameter (-C) provided without "
1457 "test mode (-T)");
1458
1409 /* Fetch our configuration */ 1459 /* Fetch our configuration */
1410 buffer_init(&cfg); 1460 buffer_init(&cfg);
1411 if (rexeced_flag) 1461 if (rexeced_flag)
@@ -1534,6 +1584,13 @@ main(int ac, char **av)
1534 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); 1584 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
1535 } 1585 }
1536 1586
1587 if (test_flag > 1) {
1588 if (test_user != NULL && test_addr != NULL && test_host != NULL)
1589 parse_server_match_config(&options, test_user,
1590 test_host, test_addr);
1591 dump_config(&options);
1592 }
1593
1537 /* Configuration looks good, so exit if in test mode. */ 1594 /* Configuration looks good, so exit if in test mode. */
1538 if (test_flag) 1595 if (test_flag)
1539 exit(0); 1596 exit(0);
@@ -1558,6 +1615,10 @@ main(int ac, char **av)
1558 rexec_argv[rexec_argc + 1] = NULL; 1615 rexec_argv[rexec_argc + 1] = NULL;
1559 } 1616 }
1560 1617
1618 /* Ensure that umask disallows at least group and world write */
1619 new_umask = umask(0077) | 0022;
1620 (void) umask(new_umask);
1621
1561 /* Initialize the log (it is reinitialized below in case we forked). */ 1622 /* Initialize the log (it is reinitialized below in case we forked). */
1562 if (debug_flag && (!inetd_flag || rexeced_flag)) 1623 if (debug_flag && (!inetd_flag || rexeced_flag))
1563 log_stderr = 1; 1624 log_stderr = 1;
@@ -1600,10 +1661,6 @@ main(int ac, char **av)
1600 /* Get a connection, either from inetd or a listening TCP socket */ 1661 /* Get a connection, either from inetd or a listening TCP socket */
1601 if (inetd_flag) { 1662 if (inetd_flag) {
1602 server_accept_inetd(&sock_in, &sock_out); 1663 server_accept_inetd(&sock_in, &sock_out);
1603
1604 if ((options.protocol & SSH_PROTO_1) &&
1605 sensitive_data.server_key == NULL)
1606 generate_ephemeral_server_key();
1607 } else { 1664 } else {
1608 server_listen(); 1665 server_listen();
1609 1666
@@ -1740,6 +1797,8 @@ main(int ac, char **av)
1740 audit_connection_from(remote_ip, remote_port); 1797 audit_connection_from(remote_ip, remote_port);
1741#endif 1798#endif
1742#ifdef LIBWRAP 1799#ifdef LIBWRAP
1800 allow_severity = options.log_facility|LOG_INFO;
1801 deny_severity = options.log_facility|LOG_WARNING;
1743 /* Check whether logins are denied from this host. */ 1802 /* Check whether logins are denied from this host. */
1744 if (packet_connection_is_on_socket()) { 1803 if (packet_connection_is_on_socket()) {
1745 struct request_info req; 1804 struct request_info req;
@@ -1773,6 +1832,10 @@ main(int ac, char **av)
1773 1832
1774 sshd_exchange_identification(sock_in, sock_out); 1833 sshd_exchange_identification(sock_in, sock_out);
1775 1834
1835 /* In inetd mode, generate ephemeral key only for proto 1 connections */
1836 if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
1837 generate_ephemeral_server_key();
1838
1776 packet_set_nonblocking(); 1839 packet_set_nonblocking();
1777 1840
1778 /* allocate authentication context */ 1841 /* allocate authentication context */
@@ -1825,6 +1888,20 @@ main(int ac, char **av)
1825 audit_event(SSH_AUTH_SUCCESS); 1888 audit_event(SSH_AUTH_SUCCESS);
1826#endif 1889#endif
1827 1890
1891#ifdef GSSAPI
1892 if (options.gss_authentication) {
1893 temporarily_use_uid(authctxt->pw);
1894 ssh_gssapi_storecreds();
1895 restore_uid();
1896 }
1897#endif
1898#ifdef USE_PAM
1899 if (options.use_pam) {
1900 do_pam_setcred(1);
1901 do_pam_session();
1902 }
1903#endif
1904
1828 /* 1905 /*
1829 * In privilege separation, we fork another child and prepare 1906 * In privilege separation, we fork another child and prepare
1830 * file descriptor passing. 1907 * file descriptor passing.
@@ -1836,11 +1913,18 @@ main(int ac, char **av)
1836 destroy_sensitive_data(); 1913 destroy_sensitive_data();
1837 } 1914 }
1838 1915
1916 packet_set_timeout(options.client_alive_interval,
1917 options.client_alive_count_max);
1918
1839 /* Start session. */ 1919 /* Start session. */
1840 do_authenticated(authctxt); 1920 do_authenticated(authctxt);
1841 1921
1842 /* The connection has been terminated. */ 1922 /* The connection has been terminated. */
1843 verbose("Closing connection to %.100s", remote_ip); 1923 packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
1924 packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
1925 verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes);
1926
1927 verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
1844 1928
1845#ifdef USE_PAM 1929#ifdef USE_PAM
1846 if (options.use_pam) 1930 if (options.use_pam)
@@ -1920,7 +2004,6 @@ do_ssh1_kex(void)
1920 u_char session_key[SSH_SESSION_KEY_LENGTH]; 2004 u_char session_key[SSH_SESSION_KEY_LENGTH];
1921 u_char cookie[8]; 2005 u_char cookie[8];
1922 u_int cipher_type, auth_mask, protocol_flags; 2006 u_int cipher_type, auth_mask, protocol_flags;
1923 u_int32_t rnd = 0;
1924 2007
1925 /* 2008 /*
1926 * Generate check bytes that the client must send back in the user 2009 * Generate check bytes that the client must send back in the user
@@ -1931,12 +2014,7 @@ do_ssh1_kex(void)
1931 * cookie. This only affects rhosts authentication, and this is one 2014 * cookie. This only affects rhosts authentication, and this is one
1932 * of the reasons why it is inherently insecure. 2015 * of the reasons why it is inherently insecure.
1933 */ 2016 */
1934 for (i = 0; i < 8; i++) { 2017 arc4random_buf(cookie, sizeof(cookie));
1935 if (i % 4 == 0)
1936 rnd = arc4random();
1937 cookie[i] = rnd & 0xff;
1938 rnd >>= 8;
1939 }
1940 2018
1941 /* 2019 /*
1942 * Send our public key. We include in the packet 64 bits of random 2020 * Send our public key. We include in the packet 64 bits of random
diff --git a/sshd_config b/sshd_config
index 3393cec50..1b53a0efb 100644
--- a/sshd_config
+++ b/sshd_config
@@ -1,4 +1,4 @@
1# $OpenBSD: sshd_config,v 1.75 2007/03/19 01:01:29 djm Exp $ 1# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $
2 2
3# This is the sshd server system-wide configuration file. See 3# This is the sshd server system-wide configuration file. See
4# sshd_config(5) for more information. 4# sshd_config(5) for more information.
@@ -28,7 +28,7 @@ Protocol 2
28 28
29# Lifetime and size of ephemeral version 1 server key 29# Lifetime and size of ephemeral version 1 server key
30#KeyRegenerationInterval 1h 30#KeyRegenerationInterval 1h
31#ServerKeyBits 768 31#ServerKeyBits 1024
32 32
33# Logging 33# Logging
34# obsoletes QuietMode and FascistLogging 34# obsoletes QuietMode and FascistLogging
@@ -41,6 +41,7 @@ Protocol 2
41#PermitRootLogin yes 41#PermitRootLogin yes
42#StrictModes yes 42#StrictModes yes
43#MaxAuthTries 6 43#MaxAuthTries 6
44#MaxSessions 10
44 45
45#RSAAuthentication yes 46#RSAAuthentication yes
46#PubkeyAuthentication yes 47#PubkeyAuthentication yes
@@ -84,6 +85,7 @@ Protocol 2
84# and ChallengeResponseAuthentication to 'no'. 85# and ChallengeResponseAuthentication to 'no'.
85#UsePAM no 86#UsePAM no
86 87
88#AllowAgentForwarding yes
87#AllowTcpForwarding yes 89#AllowTcpForwarding yes
88#GatewayPorts no 90#GatewayPorts no
89#X11Forwarding no 91#X11Forwarding no
@@ -102,9 +104,10 @@ Protocol 2
102#PidFile /var/run/sshd.pid 104#PidFile /var/run/sshd.pid
103#MaxStartups 10 105#MaxStartups 10
104#PermitTunnel no 106#PermitTunnel no
107#ChrootDirectory none
105 108
106# no default banner path 109# no default banner path
107#Banner /some/path 110#Banner none
108 111
109# override default of no subsystems 112# override default of no subsystems
110Subsystem sftp /usr/libexec/sftp-server 113Subsystem sftp /usr/libexec/sftp-server
diff --git a/sshd_config.0 b/sshd_config.0
index 0b340ad20..15a6c9004 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -34,6 +34,12 @@ DESCRIPTION
34 arguments are ``any'', ``inet'' (use IPv4 only), or ``inet6'' 34 arguments are ``any'', ``inet'' (use IPv4 only), or ``inet6''
35 (use IPv6 only). The default is ``any''. 35 (use IPv6 only). The default is ``any''.
36 36
37 AllowAgentForwarding
38 Specifies whether ssh-agent(1) forwarding is permitted. The de-
39 fault is ``yes''. Note that disabling agent forwarding does not
40 improve security unless users are also denied shell access, as
41 they can always install their own forwarders.
42
37 AllowGroups 43 AllowGroups
38 This keyword can be followed by a list of group name patterns, 44 This keyword can be followed by a list of group name patterns,
39 separated by spaces. If specified, login is allowed only for 45 separated by spaces. If specified, login is allowed only for
@@ -76,10 +82,9 @@ DESCRIPTION
76 path or one relative to the user's home directory. The default 82 path or one relative to the user's home directory. The default
77 is ``.ssh/authorized_keys''. 83 is ``.ssh/authorized_keys''.
78 84
79 Banner In some jurisdictions, sending a warning message before authenti- 85 Banner The contents of the specified file are sent to the remote user
80 cation may be relevant for getting legal protection. The con- 86 before authentication is allowed. If the argument is ``none''
81 tents of the specified file are sent to the remote user before 87 then no banner is displayed. This option is only available for
82 authentication is allowed. This option is only available for
83 protocol version 2. By default, no banner is displayed. 88 protocol version 2. By default, no banner is displayed.
84 89
85 ChallengeResponseAuthentication 90 ChallengeResponseAuthentication
@@ -87,6 +92,28 @@ DESCRIPTION
87 All authentication styles from login.conf(5) are supported. The 92 All authentication styles from login.conf(5) are supported. The
88 default is ``yes''. 93 default is ``yes''.
89 94
95 ChrootDirectory
96 Specifies a path to chroot(2) to after authentication. This
97 path, and all its components, must be root-owned directories that
98 are not writable by any other user or group.
99
100 The path may contain the following tokens that are expanded at
101 runtime once the connecting user has been authenticated: %% is
102 replaced by a literal '%', %h is replaced by the home directory
103 of the user being authenticated, and %u is replaced by the user-
104 name of that user.
105
106 The ChrootDirectory must contain the necessary files and directo-
107 ries to support the users' session. For an interactive session
108 this requires at least a shell, typically sh(1), and basic /dev
109 nodes such as null(4), zero(4), stdin(4), stdout(4), stderr(4),
110 arandom(4) and tty(4) devices. For file transfer sessions using
111 ``sftp'', no additional configuration of the environment is nec-
112 essary if the in-process sftp server is used (see Subsystem for
113 details).
114
115 The default is not to chroot(2).
116
90 Ciphers 117 Ciphers
91 Specifies the ciphers allowed for protocol version 2. Multiple 118 Specifies the ciphers allowed for protocol version 2. Multiple
92 ciphers must be comma-separated. The supported ciphers are 119 ciphers must be comma-separated. The supported ciphers are
@@ -156,12 +183,15 @@ DESCRIPTION
156 183
157 ForceCommand 184 ForceCommand
158 Forces the execution of the command specified by ForceCommand, 185 Forces the execution of the command specified by ForceCommand,
159 ignoring any command supplied by the client. The command is in- 186 ignoring any command supplied by the client and ~/.ssh/rc if pre-
160 voked by using the user's login shell with the -c option. This 187 sent. The command is invoked by using the user's login shell
161 applies to shell, command, or subsystem execution. It is most 188 with the -c option. This applies to shell, command, or subsystem
162 useful inside a Match block. The command originally supplied by 189 execution. It is most useful inside a Match block. The command
163 the client is available in the SSH_ORIGINAL_COMMAND environment 190 originally supplied by the client is available in the
164 variable. 191 SSH_ORIGINAL_COMMAND environment variable. Specifying a command
192 of ``internal-sftp'' will force the use of an in-process sftp
193 server that requires no support files when used with
194 ChrootDirectory.
165 195
166 GatewayPorts 196 GatewayPorts
167 Specifies whether remote hosts are allowed to connect to ports 197 Specifies whether remote hosts are allowed to connect to ports
@@ -290,22 +320,40 @@ DESCRIPTION
290 Match Introduces a conditional block. If all of the criteria on the 320 Match Introduces a conditional block. If all of the criteria on the
291 Match line are satisfied, the keywords on the following lines 321 Match line are satisfied, the keywords on the following lines
292 override those set in the global section of the config file, un- 322 override those set in the global section of the config file, un-
293 til either another Match line or the end of the file. The argu- 323 til either another Match line or the end of the file.
294 ments to Match are one or more criteria-pattern pairs. The 324
295 available criteria are User, Group, Host, and Address. Only a 325 The arguments to Match are one or more criteria-pattern pairs.
296 subset of keywords may be used on the lines following a Match 326 The available criteria are User, Group, Host, and Address. The
297 keyword. Available keywords are AllowTcpForwarding, Banner, 327 match patterns may consist of single entries or comma-separated
298 ForceCommand, GatewayPorts, GSSApiAuthentication, 328 lists and may use the wildcard and negation operators described
329 in the PATTERNS section of ssh_config(5).
330
331 The patterns in an Address criteria may additionally contain ad-
332 dresses to match in CIDR address/masklen format, e.g.
333 ``192.0.2.0/24'' or ``3ffe:ffff::/32''. Note that the mask
334 length provided must be consistent with the address - it is an
335 error to specify a mask length that is too long for the address
336 or one with bits set in this host portion of the address. For
337 example, ``192.0.2.0/33'' and ``192.0.2.0/8'' respectively.
338
339 Only a subset of keywords may be used on the lines following a
340 Match keyword. Available keywords are AllowTcpForwarding,
341 Banner, ChrootDirectory, ForceCommand, GatewayPorts,
342 GSSAPIAuthentication, HostbasedAuthentication,
299 KbdInteractiveAuthentication, KerberosAuthentication, 343 KbdInteractiveAuthentication, KerberosAuthentication,
300 PasswordAuthentication, PermitOpen, RhostsRSAAuthentication, 344 MaxAuthTries, MaxSessions, PasswordAuthentication, PermitOpen,
301 RSAAuthentication, X11DisplayOffset, X11Forwarding, and 345 PermitRootLogin, RhostsRSAAuthentication, RSAAuthentication,
302 X11UseLocalHost. 346 X11DisplayOffset, X11Forwarding, and X11UseLocalHost.
303 347
304 MaxAuthTries 348 MaxAuthTries
305 Specifies the maximum number of authentication attempts permitted 349 Specifies the maximum number of authentication attempts permitted
306 per connection. Once the number of failures reaches half this 350 per connection. Once the number of failures reaches half this
307 value, additional failures are logged. The default is 6. 351 value, additional failures are logged. The default is 6.
308 352
353 MaxSessions
354 Specifies the maximum number of open sessions permitted per net-
355 work connection. The default is 10.
356
309 MaxStartups 357 MaxStartups
310 Specifies the maximum number of concurrent unauthenticated con- 358 Specifies the maximum number of concurrent unauthenticated con-
311 nections to the SSH daemon. Additional connections will be 359 nections to the SSH daemon. Additional connections will be
@@ -416,7 +464,7 @@ DESCRIPTION
416 464
417 ServerKeyBits 465 ServerKeyBits
418 Defines the number of bits in the ephemeral protocol version 1 466 Defines the number of bits in the ephemeral protocol version 1
419 server key. The minimum value is 512, and the default is 768. 467 server key. The minimum value is 512, and the default is 1024.
420 468
421 StrictModes 469 StrictModes
422 Specifies whether sshd(8) should check file modes and ownership 470 Specifies whether sshd(8) should check file modes and ownership
@@ -428,8 +476,15 @@ DESCRIPTION
428 Subsystem 476 Subsystem
429 Configures an external subsystem (e.g. file transfer daemon). 477 Configures an external subsystem (e.g. file transfer daemon).
430 Arguments should be a subsystem name and a command (with optional 478 Arguments should be a subsystem name and a command (with optional
431 arguments) to execute upon subsystem request. The command 479 arguments) to execute upon subsystem request.
432 sftp-server(8) implements the ``sftp'' file transfer subsystem. 480
481 The command sftp-server(8) implements the ``sftp'' file transfer
482 subsystem.
483
484 Alternately the name ``internal-sftp'' implements an in-process
485 ``sftp'' server. This may simplify configurations using
486 ChrootDirectory to force a different filesystem root on clients.
487
433 By default no subsystems are defined. Note that this option ap- 488 By default no subsystems are defined. Note that this option ap-
434 plies to protocol version 2 only. 489 plies to protocol version 2 only.
435 490
@@ -572,4 +627,4 @@ AUTHORS
572 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support 627 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
573 for privilege separation. 628 for privilege separation.
574 629
575OpenBSD 4.2 June 11, 2007 9 630OpenBSD 4.4 July 2, 2008 10
diff --git a/sshd_config.5 b/sshd_config.5
index 7882f8bcf..7255b1c22 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd_config.5,v 1.77 2007/06/08 07:48:09 jmc Exp $ 37.\" $OpenBSD: sshd_config.5,v 1.96 2008/07/02 02:24:18 djm Exp $
38.Dd $Mdocdate: June 11 2007 $ 38.Dd $Mdocdate: July 2 2008 $
39.Dt SSHD_CONFIG 5 39.Dt SSHD_CONFIG 5
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -95,6 +95,15 @@ Valid arguments are
95(use IPv6 only). 95(use IPv6 only).
96The default is 96The default is
97.Dq any . 97.Dq any .
98.It Cm AllowAgentForwarding
99Specifies whether
100.Xr ssh-agent 1
101forwarding is permitted.
102The default is
103.Dq yes .
104Note that disabling agent forwarding does not improve security
105unless users are also denied shell access, as they can always install
106their own forwarders.
98.It Cm AllowGroups 107.It Cm AllowGroups
99This keyword can be followed by a list of group name patterns, separated 108This keyword can be followed by a list of group name patterns, separated
100by spaces. 109by spaces.
@@ -159,10 +168,11 @@ directory.
159The default is 168The default is
160.Dq .ssh/authorized_keys . 169.Dq .ssh/authorized_keys .
161.It Cm Banner 170.It Cm Banner
162In some jurisdictions, sending a warning message before authentication
163may be relevant for getting legal protection.
164The contents of the specified file are sent to the remote user before 171The contents of the specified file are sent to the remote user before
165authentication is allowed. 172authentication is allowed.
173If the argument is
174.Dq none
175then no banner is displayed.
166This option is only available for protocol version 2. 176This option is only available for protocol version 2.
167By default, no banner is displayed. 177By default, no banner is displayed.
168.It Cm ChallengeResponseAuthentication 178.It Cm ChallengeResponseAuthentication
@@ -172,6 +182,45 @@ All authentication styles from
172are supported. 182are supported.
173The default is 183The default is
174.Dq yes . 184.Dq yes .
185.It Cm ChrootDirectory
186Specifies a path to
187.Xr chroot 2
188to after authentication.
189This path, and all its components, must be root-owned directories that are
190not writable by any other user or group.
191.Pp
192The path may contain the following tokens that are expanded at runtime once
193the connecting user has been authenticated: %% is replaced by a literal '%',
194%h is replaced by the home directory of the user being authenticated, and
195%u is replaced by the username of that user.
196.Pp
197The
198.Cm ChrootDirectory
199must contain the necessary files and directories to support the
200users' session.
201For an interactive session this requires at least a shell, typically
202.Xr sh 1 ,
203and basic
204.Pa /dev
205nodes such as
206.Xr null 4 ,
207.Xr zero 4 ,
208.Xr stdin 4 ,
209.Xr stdout 4 ,
210.Xr stderr 4 ,
211.Xr arandom 4
212and
213.Xr tty 4
214devices.
215For file transfer sessions using
216.Dq sftp ,
217no additional configuration of the environment is necessary if the
218in-process sftp server is used (see
219.Cm Subsystem
220for details).
221.Pp
222The default is not to
223.Xr chroot 2 .
175.It Cm Ciphers 224.It Cm Ciphers
176Specifies the ciphers allowed for protocol version 2. 225Specifies the ciphers allowed for protocol version 2.
177Multiple ciphers must be comma-separated. 226Multiple ciphers must be comma-separated.
@@ -284,7 +333,9 @@ for more information on patterns.
284.It Cm ForceCommand 333.It Cm ForceCommand
285Forces the execution of the command specified by 334Forces the execution of the command specified by
286.Cm ForceCommand , 335.Cm ForceCommand ,
287ignoring any command supplied by the client. 336ignoring any command supplied by the client and
337.Pa ~/.ssh/rc
338if present.
288The command is invoked by using the user's login shell with the -c option. 339The command is invoked by using the user's login shell with the -c option.
289This applies to shell, command, or subsystem execution. 340This applies to shell, command, or subsystem execution.
290It is most useful inside a 341It is most useful inside a
@@ -293,6 +344,11 @@ block.
293The command originally supplied by the client is available in the 344The command originally supplied by the client is available in the
294.Ev SSH_ORIGINAL_COMMAND 345.Ev SSH_ORIGINAL_COMMAND
295environment variable. 346environment variable.
347Specifying a command of
348.Dq internal-sftp
349will force the use of an in-process sftp server that requires no support
350files when used with
351.Cm ChrootDirectory .
296.It Cm GatewayPorts 352.It Cm GatewayPorts
297Specifies whether remote hosts are allowed to connect to ports 353Specifies whether remote hosts are allowed to connect to ports
298forwarded for the client. 354forwarded for the client.
@@ -501,6 +557,7 @@ line are satisfied, the keywords on the following lines override those
501set in the global section of the config file, until either another 557set in the global section of the config file, until either another
502.Cm Match 558.Cm Match
503line or the end of the file. 559line or the end of the file.
560.Pp
504The arguments to 561The arguments to
505.Cm Match 562.Cm Match
506are one or more criteria-pattern pairs. 563are one or more criteria-pattern pairs.
@@ -510,19 +567,46 @@ The available criteria are
510.Cm Host , 567.Cm Host ,
511and 568and
512.Cm Address . 569.Cm Address .
570The match patterns may consist of single entries or comma-separated
571lists and may use the wildcard and negation operators described in the
572.Sx PATTERNS
573section of
574.Xr ssh_config 5 .
575.Pp
576The patterns in an
577.Cm Address
578criteria may additionally contain addresses to match in CIDR
579address/masklen format, e.g.\&
580.Dq 192.0.2.0/24
581or
582.Dq 3ffe:ffff::/32 .
583Note that the mask length provided must be consistent with the address -
584it is an error to specify a mask length that is too long for the address
585or one with bits set in this host portion of the address.
586For example,
587.Dq 192.0.2.0/33
588and
589.Dq 192.0.2.0/8
590respectively.
591.Pp
513Only a subset of keywords may be used on the lines following a 592Only a subset of keywords may be used on the lines following a
514.Cm Match 593.Cm Match
515keyword. 594keyword.
516Available keywords are 595Available keywords are
517.Cm AllowTcpForwarding , 596.Cm AllowTcpForwarding ,
518.Cm Banner , 597.Cm Banner ,
598.Cm ChrootDirectory ,
519.Cm ForceCommand , 599.Cm ForceCommand ,
520.Cm GatewayPorts , 600.Cm GatewayPorts ,
521.Cm GSSApiAuthentication , 601.Cm GSSAPIAuthentication ,
602.Cm HostbasedAuthentication ,
522.Cm KbdInteractiveAuthentication , 603.Cm KbdInteractiveAuthentication ,
523.Cm KerberosAuthentication , 604.Cm KerberosAuthentication ,
605.Cm MaxAuthTries ,
606.Cm MaxSessions ,
524.Cm PasswordAuthentication , 607.Cm PasswordAuthentication ,
525.Cm PermitOpen , 608.Cm PermitOpen ,
609.Cm PermitRootLogin ,
526.Cm RhostsRSAAuthentication , 610.Cm RhostsRSAAuthentication ,
527.Cm RSAAuthentication , 611.Cm RSAAuthentication ,
528.Cm X11DisplayOffset , 612.Cm X11DisplayOffset ,
@@ -535,6 +619,9 @@ connection.
535Once the number of failures reaches half this value, 619Once the number of failures reaches half this value,
536additional failures are logged. 620additional failures are logged.
537The default is 6. 621The default is 6.
622.It Cm MaxSessions
623Specifies the maximum number of open sessions permitted per network connection.
624The default is 10.
538.It Cm MaxStartups 625.It Cm MaxStartups
539Specifies the maximum number of concurrent unauthenticated connections to the 626Specifies the maximum number of concurrent unauthenticated connections to the
540SSH daemon. 627SSH daemon.
@@ -724,7 +811,7 @@ The default is
724This option applies to protocol version 1 only. 811This option applies to protocol version 1 only.
725.It Cm ServerKeyBits 812.It Cm ServerKeyBits
726Defines the number of bits in the ephemeral protocol version 1 server key. 813Defines the number of bits in the ephemeral protocol version 1 server key.
727The minimum value is 512, and the default is 768. 814The minimum value is 512, and the default is 1024.
728.It Cm StrictModes 815.It Cm StrictModes
729Specifies whether 816Specifies whether
730.Xr sshd 8 817.Xr sshd 8
@@ -738,11 +825,22 @@ The default is
738Configures an external subsystem (e.g. file transfer daemon). 825Configures an external subsystem (e.g. file transfer daemon).
739Arguments should be a subsystem name and a command (with optional arguments) 826Arguments should be a subsystem name and a command (with optional arguments)
740to execute upon subsystem request. 827to execute upon subsystem request.
828.Pp
741The command 829The command
742.Xr sftp-server 8 830.Xr sftp-server 8
743implements the 831implements the
744.Dq sftp 832.Dq sftp
745file transfer subsystem. 833file transfer subsystem.
834.Pp
835Alternately the name
836.Dq internal-sftp
837implements an in-process
838.Dq sftp
839server.
840This may simplify configurations using
841.Cm ChrootDirectory
842to force a different filesystem root on clients.
843.Pp
746By default no subsystems are defined. 844By default no subsystems are defined.
747Note that this option applies to protocol version 2 only. 845Note that this option applies to protocol version 2 only.
748.It Cm SyslogFacility 846.It Cm SyslogFacility
diff --git a/sshlogin.c b/sshlogin.c
index 0059ff8d0..cc35d6024 100644
--- a/sshlogin.c
+++ b/sshlogin.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshlogin.c,v 1.25 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: sshlogin.c,v 1.26 2007/09/11 15:47:17 gilles 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
@@ -98,8 +98,7 @@ store_lastlog_message(const char *user, uid_t uid)
98 98
99 if (last_login_time != 0) { 99 if (last_login_time != 0) {
100 time_string = ctime(&last_login_time); 100 time_string = ctime(&last_login_time);
101 if (strchr(time_string, '\n')) 101 time_string[strcspn(time_string, "\n")] = '\0';
102 *strchr(time_string, '\n') = '\0';
103 if (strcmp(hostname, "") == 0) 102 if (strcmp(hostname, "") == 0)
104 snprintf(buf, sizeof(buf), "Last login: %s\r\n", 103 snprintf(buf, sizeof(buf), "Last login: %s\r\n",
105 time_string); 104 time_string);
diff --git a/sshpty.c b/sshpty.c
index 79c62ee9c..5a0d1a7ad 100644
--- a/sshpty.c
+++ b/sshpty.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshpty.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: sshpty.c,v 1.28 2007/09/11 23:49:09 stevesk 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/sshpty.h b/sshpty.h
index 7fac622d9..ac9003584 100644
--- a/sshpty.h
+++ b/sshpty.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshpty.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: sshpty.h,v 1.11 2008/05/19 15:45:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,7 +16,7 @@
16 16
17#include <termios.h> 17#include <termios.h>
18 18
19struct termios get_saved_tio(void); 19struct termios *get_saved_tio(void);
20void leave_raw_mode(void); 20void leave_raw_mode(void);
21void enter_raw_mode(void); 21void enter_raw_mode(void);
22 22
diff --git a/sshtty.c b/sshtty.c
index 04567669b..21ade4e51 100644
--- a/sshtty.c
+++ b/sshtty.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshtty.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: sshtty.c,v 1.13 2008/05/19 15:45:07 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
@@ -47,10 +47,10 @@
47static struct termios _saved_tio; 47static struct termios _saved_tio;
48static int _in_raw_mode = 0; 48static int _in_raw_mode = 0;
49 49
50struct termios 50struct termios *
51get_saved_tio(void) 51get_saved_tio(void)
52{ 52{
53 return _saved_tio; 53 return _in_raw_mode ? &_saved_tio : NULL;
54} 54}
55 55
56void 56void
diff --git a/ttymodes.c b/ttymodes.c
index d8e2c553a..e116b1999 100644
--- a/ttymodes.c
+++ b/ttymodes.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ttymodes.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: ttymodes.c,v 1.28 2008/07/07 00:31:41 stevesk 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
@@ -298,6 +298,10 @@ tty_make_modes(int fd, struct termios *tiop)
298 } 298 }
299 299
300 if (tiop == NULL) { 300 if (tiop == NULL) {
301 if (fd == -1) {
302 debug("tty_make_modes: no fd or tio");
303 goto end;
304 }
301 if (tcgetattr(fd, &tio) == -1) { 305 if (tcgetattr(fd, &tio) == -1) {
302 logit("tcgetattr: %.100s", strerror(errno)); 306 logit("tcgetattr: %.100s", strerror(errno));
303 goto end; 307 goto end;
@@ -317,12 +321,10 @@ tty_make_modes(int fd, struct termios *tiop)
317 321
318 /* Store values of mode flags. */ 322 /* Store values of mode flags. */
319#define TTYCHAR(NAME, OP) \ 323#define TTYCHAR(NAME, OP) \
320 debug3("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \
321 buffer_put_char(&buf, OP); \ 324 buffer_put_char(&buf, OP); \
322 put_arg(&buf, special_char_encode(tio.c_cc[NAME])); 325 put_arg(&buf, special_char_encode(tio.c_cc[NAME]));
323 326
324#define TTYMODE(NAME, FIELD, OP) \ 327#define TTYMODE(NAME, FIELD, OP) \
325 debug3("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \
326 buffer_put_char(&buf, OP); \ 328 buffer_put_char(&buf, OP); \
327 put_arg(&buf, ((tio.FIELD & NAME) != 0)); 329 put_arg(&buf, ((tio.FIELD & NAME) != 0));
328 330
@@ -353,7 +355,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
353 int n_bytes = 0; 355 int n_bytes = 0;
354 int failure = 0; 356 int failure = 0;
355 u_int (*get_arg)(void); 357 u_int (*get_arg)(void);
356 int arg, arg_size; 358 int arg_size;
357 359
358 if (compat20) { 360 if (compat20) {
359 *n_bytes_ptr = packet_get_int(); 361 *n_bytes_ptr = packet_get_int();
@@ -410,16 +412,14 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
410 case OP: \ 412 case OP: \
411 n_bytes += arg_size; \ 413 n_bytes += arg_size; \
412 tio.c_cc[NAME] = special_char_decode(get_arg()); \ 414 tio.c_cc[NAME] = special_char_decode(get_arg()); \
413 debug3("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \
414 break; 415 break;
415#define TTYMODE(NAME, FIELD, OP) \ 416#define TTYMODE(NAME, FIELD, OP) \
416 case OP: \ 417 case OP: \
417 n_bytes += arg_size; \ 418 n_bytes += arg_size; \
418 if ((arg = get_arg())) \ 419 if (get_arg()) \
419 tio.FIELD |= NAME; \ 420 tio.FIELD |= NAME; \
420 else \ 421 else \
421 tio.FIELD &= ~NAME; \ 422 tio.FIELD &= ~NAME; \
422 debug3("tty_parse_modes: %d %d", OP, arg); \
423 break; 423 break;
424 424
425#include "ttymodes.h" 425#include "ttymodes.h"
diff --git a/umac.c b/umac.c
index c2fdcf448..92902bc09 100644
--- a/umac.c
+++ b/umac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: umac.c,v 1.1 2007/06/07 19:37:34 pvalchev Exp $ */ 1/* $OpenBSD: umac.c,v 1.3 2008/05/12 20:52:20 pvalchev Exp $ */
2/* ----------------------------------------------------------------------- 2/* -----------------------------------------------------------------------
3 * 3 *
4 * umac.c -- C Implementation UMAC Message Authentication 4 * umac.c -- C Implementation UMAC Message Authentication
@@ -66,6 +66,7 @@
66#include "includes.h" 66#include "includes.h"
67#include <sys/types.h> 67#include <sys/types.h>
68 68
69#include "xmalloc.h"
69#include "umac.h" 70#include "umac.h"
70#include <string.h> 71#include <string.h>
71#include <stdlib.h> 72#include <stdlib.h>
@@ -135,12 +136,14 @@ static UINT32 LOAD_UINT32_REVERSED(void *ptr)
135 return (UINT32)temp; 136 return (UINT32)temp;
136} 137}
137 138
139# if (__LITTLE_ENDIAN__)
138static void STORE_UINT32_REVERSED(void *ptr, UINT32 x) 140static void STORE_UINT32_REVERSED(void *ptr, UINT32 x)
139{ 141{
140 UINT32 i = (UINT32)x; 142 UINT32 i = (UINT32)x;
141 *(UINT32 *)ptr = (i >> 24) | ((i & 0x00FF0000) >> 8 ) 143 *(UINT32 *)ptr = (i >> 24) | ((i & 0x00FF0000) >> 8 )
142 | ((i & 0x0000FF00) << 8 ) | (i << 24); 144 | ((i & 0x0000FF00) << 8 ) | (i << 24);
143} 145}
146# endif /* __LITTLE_ENDIAN */
144#endif /* HAVE_SWAP32 */ 147#endif /* HAVE_SWAP32 */
145 148
146/* The following definitions use the above reversal-primitives to do the right 149/* The following definitions use the above reversal-primitives to do the right
@@ -178,14 +181,14 @@ typedef AES_KEY aes_int_key[1];
178/* The user-supplied UMAC key is stretched using AES in a counter 181/* The user-supplied UMAC key is stretched using AES in a counter
179 * mode to supply all random bits needed by UMAC. The kdf function takes 182 * mode to supply all random bits needed by UMAC. The kdf function takes
180 * an AES internal key representation 'key' and writes a stream of 183 * an AES internal key representation 'key' and writes a stream of
181 * 'nbytes' bytes to the memory pointed at by 'buffer_ptr'. Each distinct 184 * 'nbytes' bytes to the memory pointed at by 'bufp'. Each distinct
182 * 'ndx' causes a distinct byte stream. 185 * 'ndx' causes a distinct byte stream.
183 */ 186 */
184static void kdf(void *buffer_ptr, aes_int_key key, UINT8 ndx, int nbytes) 187static void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes)
185{ 188{
186 UINT8 in_buf[AES_BLOCK_LEN] = {0}; 189 UINT8 in_buf[AES_BLOCK_LEN] = {0};
187 UINT8 out_buf[AES_BLOCK_LEN]; 190 UINT8 out_buf[AES_BLOCK_LEN];
188 UINT8 *dst_buf = (UINT8 *)buffer_ptr; 191 UINT8 *dst_buf = (UINT8 *)bufp;
189 int i; 192 int i;
190 193
191 /* Setup the initial value */ 194 /* Setup the initial value */
@@ -543,6 +546,7 @@ static void nh_transform(nh_ctx *hc, UINT8 *buf, UINT32 nbytes)
543 546
544/* ---------------------------------------------------------------------- */ 547/* ---------------------------------------------------------------------- */
545 548
549#if (__LITTLE_ENDIAN__)
546static void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes) 550static void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes)
547/* We endian convert the keys on little-endian computers to */ 551/* We endian convert the keys on little-endian computers to */
548/* compensate for the lack of big-endian memory reads during hashing. */ 552/* compensate for the lack of big-endian memory reads during hashing. */
@@ -565,7 +569,6 @@ static void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes)
565 } while (--iters); 569 } while (--iters);
566 } 570 }
567} 571}
568#if (__LITTLE_ENDIAN__)
569#define endian_convert_if_le(x,y,z) endian_convert((x),(y),(z)) 572#define endian_convert_if_le(x,y,z) endian_convert((x),(y),(z))
570#else 573#else
571#define endian_convert_if_le(x,y,z) do{}while(0) /* Do nothing */ 574#define endian_convert_if_le(x,y,z) do{}while(0) /* Do nothing */
@@ -1042,7 +1045,8 @@ static int uhash_update(uhash_ctx_t ctx, u_char *input, long len)
1042 */ 1045 */
1043{ 1046{
1044 UWORD bytes_hashed, bytes_remaining; 1047 UWORD bytes_hashed, bytes_remaining;
1045 UINT8 nh_result[STREAMS*sizeof(UINT64)]; 1048 UINT64 result_buf[STREAMS];
1049 UINT8 *nh_result = (UINT8 *)&result_buf;
1046 1050
1047 if (ctx->msg_len + len <= L1_KEY_LEN) { 1051 if (ctx->msg_len + len <= L1_KEY_LEN) {
1048 nh_update(&ctx->hash, (UINT8 *)input, len); 1052 nh_update(&ctx->hash, (UINT8 *)input, len);
@@ -1094,7 +1098,8 @@ static int uhash_update(uhash_ctx_t ctx, u_char *input, long len)
1094static int uhash_final(uhash_ctx_t ctx, u_char *res) 1098static int uhash_final(uhash_ctx_t ctx, u_char *res)
1095/* Incorporate any pending data, pad, and generate tag */ 1099/* Incorporate any pending data, pad, and generate tag */
1096{ 1100{
1097 UINT8 nh_result[STREAMS*sizeof(UINT64)]; 1101 UINT64 result_buf[STREAMS];
1102 UINT8 *nh_result = (UINT8 *)&result_buf;
1098 1103
1099 if (ctx->msg_len > L1_KEY_LEN) { 1104 if (ctx->msg_len > L1_KEY_LEN) {
1100 if (ctx->msg_len % L1_KEY_LEN) { 1105 if (ctx->msg_len % L1_KEY_LEN) {
@@ -1196,7 +1201,7 @@ int umac_delete(struct umac_ctx *ctx)
1196 if (ctx) { 1201 if (ctx) {
1197 if (ALLOC_BOUNDARY) 1202 if (ALLOC_BOUNDARY)
1198 ctx = (struct umac_ctx *)ctx->free_ptr; 1203 ctx = (struct umac_ctx *)ctx->free_ptr;
1199 free(ctx); 1204 xfree(ctx);
1200 } 1205 }
1201 return (1); 1206 return (1);
1202} 1207}
@@ -1212,7 +1217,7 @@ struct umac_ctx *umac_new(u_char key[])
1212 size_t bytes_to_add; 1217 size_t bytes_to_add;
1213 aes_int_key prf_key; 1218 aes_int_key prf_key;
1214 1219
1215 octx = ctx = malloc(sizeof(*ctx) + ALLOC_BOUNDARY); 1220 octx = ctx = xmalloc(sizeof(*ctx) + ALLOC_BOUNDARY);
1216 if (ctx) { 1221 if (ctx) {
1217 if (ALLOC_BOUNDARY) { 1222 if (ALLOC_BOUNDARY) {
1218 bytes_to_add = ALLOC_BOUNDARY - 1223 bytes_to_add = ALLOC_BOUNDARY -
diff --git a/version.h b/version.h
index 6fcd7e075..41a081f12 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
1/* $OpenBSD: version.h,v 1.50 2007/08/15 08:16:49 markus Exp $ */ 1/* $OpenBSD: version.h,v 1.54 2008/07/21 08:19:07 djm Exp $ */
2 2
3#define SSH_VERSION "OpenSSH_4.7" 3#define SSH_VERSION "OpenSSH_5.1"
4 4
5#define SSH_PORTABLE "p1" 5#define SSH_PORTABLE "p1"
6#define SSH_RELEASE SSH_VERSION SSH_PORTABLE 6#define SSH_RELEASE SSH_VERSION SSH_PORTABLE