summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog67
-rw-r--r--Makefile.in2
-rw-r--r--auth2.c48
-rw-r--r--bsd-base64.c315
-rw-r--r--bsd-base64.h19
-rw-r--r--channels.c33
-rw-r--r--channels.h6
-rw-r--r--clientloop.c6
-rw-r--r--configure.in4
-rw-r--r--dsa.c4
-rw-r--r--includes.h1
-rw-r--r--key.c25
-rw-r--r--key.h1
-rw-r--r--nchan.c23
-rw-r--r--packet.c13
-rw-r--r--radix.c7
-rw-r--r--readconf.c18
-rw-r--r--readconf.h3
-rw-r--r--scp.c20
-rw-r--r--servconf.c33
-rw-r--r--servconf.h6
-rw-r--r--serverloop.c2
-rw-r--r--session.c43
-rw-r--r--ssh-add.16
-rw-r--r--ssh-agent.14
-rw-r--r--ssh-keygen.163
-rw-r--r--ssh-keygen.c8
-rw-r--r--ssh.1160
-rw-r--r--ssh.h7
-rw-r--r--sshconnect.c34
-rw-r--r--sshconnect1.c6
-rw-r--r--sshconnect2.c8
-rw-r--r--sshd.8104
-rw-r--r--sshd.c9
-rw-r--r--uuencode.c110
-rw-r--r--uuencode.h4
36 files changed, 961 insertions, 261 deletions
diff --git a/ChangeLog b/ChangeLog
index d7143d5d4..c6e3548a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
120000507
2 - Remove references to SSLeay.
3 - Big OpenBSD CVS update
4 - markus@cvs.openbsd.org
5 [clientloop.c]
6 - typo
7 [session.c]
8 - update proctitle on pty alloc/dealloc, e.g. w/ windows client
9 [session.c]
10 - update proctitle for proto 1, too
11 [channels.h nchan.c serverloop.c session.c sshd.c]
12 - use c-style comments
13 - deraadt@cvs.openbsd.org
14 [scp.c]
15 - more atomicio
16 - markus@cvs.openbsd.org
17 [channels.c]
18 - set O_NONBLOCK
19 [ssh.1]
20 - update AUTHOR
21 [readconf.c ssh-keygen.c ssh.h]
22 - default DSA key file ~/.ssh/id_dsa
23 [clientloop.c]
24 - typo, rm verbose debug
25 - deraadt@cvs.openbsd.org
26 [ssh-keygen.1]
27 - document DSA use of ssh-keygen
28 [sshd.8]
29 - a start at describing what i understand of the DSA side
30 [ssh-keygen.1]
31 - document -X and -x
32 [ssh-keygen.c]
33 - simplify usage
34 - markus@cvs.openbsd.org
35 [sshd.8]
36 - there is no rhosts_dsa
37 [ssh-keygen.1]
38 - document -y, update -X,-x
39 [nchan.c]
40 - fix close for non-open ssh1 channels
41 [servconf.c servconf.h ssh.h sshd.8 sshd.c ]
42 - s/DsaKey/HostDSAKey/, document option
43 [sshconnect2.c]
44 - respect number_of_password_prompts
45 [channels.c channels.h servconf.c servconf.h session.c sshd.8]
46 - GatewayPorts for sshd, ok deraadt@
47 [ssh-add.1 ssh-agent.1 ssh.1]
48 - more doc on: DSA, id_dsa, known_hosts2, authorized_keys2
49 [ssh.1]
50 - more info on proto 2
51 [sshd.8]
52 - sync AUTHOR w/ ssh.1
53 [key.c key.h sshconnect.c]
54 - print key type when talking about host keys
55 [packet.c]
56 - clear padding in ssh2
57 [dsa.c key.c radix.c ssh.h sshconnect1.c uuencode.c uuencode.h]
58 - replace broken uuencode w/ libc b64_ntop
59 [auth2.c]
60 - log failure before sending the reply
61 [key.c radix.c uuencode.c]
62 - remote trailing comments before calling __b64_pton
63 [auth2.c readconf.c readconf.h servconf.c servconf.h ssh.1]
64 [sshconnect2.c sshd.8]
65 - add DSAAuthetication option to ssh/sshd, document SSH2 in sshd.8
66 - Bring in b64_ntop and b64_pton from OpenBSD libc (bsd-base64.[ch])
67
120000502 6820000502
2 - OpenBSD CVS update 69 - OpenBSD CVS update
3 [channels.c] 70 [channels.c]
diff --git a/Makefile.in b/Makefile.in
index 646201c04..de2fbd269 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -33,7 +33,7 @@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
33 33
34TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) 34TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS)
35 35
36LIBOBJS= atomicio.o authfd.o authfile.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o 36LIBOBJS= atomicio.o authfd.o authfile.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o bsd-mktemp.o bsd-rresvport.o bsd-setenv.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dispatch.o dsa.o fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o
37 37
38SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o 38SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o
39 39
diff --git a/auth2.c b/auth2.c
index e77358a3b..3d997f45b 100644
--- a/auth2.c
+++ b/auth2.c
@@ -27,7 +27,7 @@
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29#include "includes.h" 29#include "includes.h"
30RCSID("$OpenBSD: auth2.c,v 1.5 2000/05/01 23:13:39 djm Exp $"); 30RCSID("$OpenBSD: auth2.c,v 1.7 2000/05/06 17:45:36 markus Exp $");
31 31
32#include <openssl/dsa.h> 32#include <openssl/dsa.h>
33#include <openssl/rsa.h> 33#include <openssl/rsa.h>
@@ -188,9 +188,29 @@ input_userauth_request(int type, int plen)
188 authenticated = 0; 188 authenticated = 0;
189#endif /* USE_PAM */ 189#endif /* USE_PAM */
190 190
191 /* XXX todo: check if multiple auth methods are needed */ 191 /* Raise logging level */
192 if (authenticated == 1 ||
193 attempt == AUTH_FAIL_LOG ||
194 strcmp(method, "password") == 0)
195 authlog = log;
196
197 /* Log before sending the reply */
192 if (authenticated == 1) { 198 if (authenticated == 1) {
193 authmsg = "Accepted"; 199 authmsg = "Accepted";
200 } else if (authenticated == 0) {
201 authmsg = "Failed";
202 } else {
203 authmsg = "Postponed";
204 }
205 authlog("%s %s for %.200s from %.200s port %d ssh2",
206 authmsg,
207 method,
208 pw && pw->pw_uid == 0 ? "ROOT" : user,
209 get_remote_ipaddr(),
210 get_remote_port());
211
212 /* XXX todo: check if multiple auth methods are needed */
213 if (authenticated == 1) {
194 /* turn off userauth */ 214 /* turn off userauth */
195 dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); 215 dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
196 packet_start(SSH2_MSG_USERAUTH_SUCCESS); 216 packet_start(SSH2_MSG_USERAUTH_SUCCESS);
@@ -199,27 +219,12 @@ input_userauth_request(int type, int plen)
199 /* now we can break out */ 219 /* now we can break out */
200 userauth_success = 1; 220 userauth_success = 1;
201 } else if (authenticated == 0) { 221 } else if (authenticated == 0) {
202 authmsg = "Failed";
203 packet_start(SSH2_MSG_USERAUTH_FAILURE); 222 packet_start(SSH2_MSG_USERAUTH_FAILURE);
204 packet_put_cstring("publickey,password"); /* XXX dynamic */ 223 packet_put_cstring("publickey,password"); /* XXX dynamic */
205 packet_put_char(0); /* XXX partial success, unused */ 224 packet_put_char(0); /* XXX partial success, unused */
206 packet_send(); 225 packet_send();
207 packet_write_wait(); 226 packet_write_wait();
208 } else {
209 authmsg = "Postponed";
210 } 227 }
211 /* Raise logging level */
212 if (authenticated == 1||
213 attempt == AUTH_FAIL_LOG ||
214 strcmp(method, "password") == 0)
215 authlog = log;
216
217 authlog("%s %s for %.200s from %.200s port %d ssh2",
218 authmsg,
219 method,
220 pw && pw->pw_uid == 0 ? "ROOT" : user,
221 get_remote_ipaddr(),
222 get_remote_port());
223 228
224 xfree(service); 229 xfree(service);
225 xfree(user); 230 xfree(user);
@@ -269,7 +274,7 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
269 int have_sig; 274 int have_sig;
270 int authenticated = 0; 275 int authenticated = 0;
271 276
272 if (options.rsa_authentication == 0) { 277 if (options.dsa_authentication == 0) {
273 debug("pubkey auth disabled"); 278 debug("pubkey auth disabled");
274 return 0; 279 return 0;
275 } 280 }
@@ -306,6 +311,13 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
306 debug("test key..."); 311 debug("test key...");
307 /* test whether pkalg/pkblob are acceptable */ 312 /* test whether pkalg/pkblob are acceptable */
308 /* XXX fake reply and always send PK_OK ? */ 313 /* XXX fake reply and always send PK_OK ? */
314 /*
315 * XXX this allows testing whether a user is allowed
316 * to login: if you happen to have a valid pubkey this
317 * message is sent. the message is NEVER sent at all
318 * if a user is not allowed to login. is this an
319 * issue? -markus
320 */
309 if (user_dsa_key_allowed(pw, key)) { 321 if (user_dsa_key_allowed(pw, key)) {
310 packet_start(SSH2_MSG_USERAUTH_PK_OK); 322 packet_start(SSH2_MSG_USERAUTH_PK_OK);
311 packet_put_string(pkalg, alen); 323 packet_put_string(pkalg, alen);
diff --git a/bsd-base64.c b/bsd-base64.c
new file mode 100644
index 000000000..57a957364
--- /dev/null
+++ b/bsd-base64.c
@@ -0,0 +1,315 @@
1/* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20/*
21 * Portions Copyright (c) 1995 by International Business Machines, Inc.
22 *
23 * International Business Machines, Inc. (hereinafter called IBM) grants
24 * permission under its copyrights to use, copy, modify, and distribute this
25 * Software with or without fee, provided that the above copyright notice and
26 * all paragraphs of this notice appear in all copies, and that the name of IBM
27 * not be used in connection with the marketing of any product incorporating
28 * the Software or modifications thereof, without specific, written prior
29 * permission.
30 *
31 * To the extent it has a right to do so, IBM grants an immunity from suit
32 * under its patents, if any, for the use, sale or manufacture of products to
33 * the extent that such products are used for performing Domain Name System
34 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
35 * granted for any product per se or for any other function of any product.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
40 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
41 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include "config.h"
46
47#ifndef HAVE_B64_NTOP
48
49#include <sys/types.h>
50#include <sys/param.h>
51#include <sys/socket.h>
52#include <netinet/in.h>
53#include <arpa/inet.h>
54
55#include <ctype.h>
56#include <resolv.h>
57#include <stdio.h>
58
59#include <stdlib.h>
60#include <string.h>
61
62#define Assert(Cond) if (!(Cond)) abort()
63
64static const char Base64[] =
65 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
66static const char Pad64 = '=';
67
68/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
69 The following encoding technique is taken from RFC 1521 by Borenstein
70 and Freed. It is reproduced here in a slightly edited form for
71 convenience.
72
73 A 65-character subset of US-ASCII is used, enabling 6 bits to be
74 represented per printable character. (The extra 65th character, "=",
75 is used to signify a special processing function.)
76
77 The encoding process represents 24-bit groups of input bits as output
78 strings of 4 encoded characters. Proceeding from left to right, a
79 24-bit input group is formed by concatenating 3 8-bit input groups.
80 These 24 bits are then treated as 4 concatenated 6-bit groups, each
81 of which is translated into a single digit in the base64 alphabet.
82
83 Each 6-bit group is used as an index into an array of 64 printable
84 characters. The character referenced by the index is placed in the
85 output string.
86
87 Table 1: The Base64 Alphabet
88
89 Value Encoding Value Encoding Value Encoding Value Encoding
90 0 A 17 R 34 i 51 z
91 1 B 18 S 35 j 52 0
92 2 C 19 T 36 k 53 1
93 3 D 20 U 37 l 54 2
94 4 E 21 V 38 m 55 3
95 5 F 22 W 39 n 56 4
96 6 G 23 X 40 o 57 5
97 7 H 24 Y 41 p 58 6
98 8 I 25 Z 42 q 59 7
99 9 J 26 a 43 r 60 8
100 10 K 27 b 44 s 61 9
101 11 L 28 c 45 t 62 +
102 12 M 29 d 46 u 63 /
103 13 N 30 e 47 v
104 14 O 31 f 48 w (pad) =
105 15 P 32 g 49 x
106 16 Q 33 h 50 y
107
108 Special processing is performed if fewer than 24 bits are available
109 at the end of the data being encoded. A full encoding quantum is
110 always completed at the end of a quantity. When fewer than 24 input
111 bits are available in an input group, zero bits are added (on the
112 right) to form an integral number of 6-bit groups. Padding at the
113 end of the data is performed using the '=' character.
114
115 Since all base64 input is an integral number of octets, only the
116 -------------------------------------------------
117 following cases can arise:
118
119 (1) the final quantum of encoding input is an integral
120 multiple of 24 bits; here, the final unit of encoded
121 output will be an integral multiple of 4 characters
122 with no "=" padding,
123 (2) the final quantum of encoding input is exactly 8 bits;
124 here, the final unit of encoded output will be two
125 characters followed by two "=" padding characters, or
126 (3) the final quantum of encoding input is exactly 16 bits;
127 here, the final unit of encoded output will be three
128 characters followed by one "=" padding character.
129 */
130
131int
132b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
133{
134 size_t datalength = 0;
135 u_char input[3];
136 u_char output[4];
137 int i;
138
139 while (2 < srclength) {
140 input[0] = *src++;
141 input[1] = *src++;
142 input[2] = *src++;
143 srclength -= 3;
144
145 output[0] = input[0] >> 2;
146 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
147 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
148 output[3] = input[2] & 0x3f;
149 Assert(output[0] < 64);
150 Assert(output[1] < 64);
151 Assert(output[2] < 64);
152 Assert(output[3] < 64);
153
154 if (datalength + 4 > targsize)
155 return (-1);
156 target[datalength++] = Base64[output[0]];
157 target[datalength++] = Base64[output[1]];
158 target[datalength++] = Base64[output[2]];
159 target[datalength++] = Base64[output[3]];
160 }
161
162 /* Now we worry about padding. */
163 if (0 != srclength) {
164 /* Get what's left. */
165 input[0] = input[1] = input[2] = '\0';
166 for (i = 0; i < srclength; i++)
167 input[i] = *src++;
168
169 output[0] = input[0] >> 2;
170 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
171 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
172 Assert(output[0] < 64);
173 Assert(output[1] < 64);
174 Assert(output[2] < 64);
175
176 if (datalength + 4 > targsize)
177 return (-1);
178 target[datalength++] = Base64[output[0]];
179 target[datalength++] = Base64[output[1]];
180 if (srclength == 1)
181 target[datalength++] = Pad64;
182 else
183 target[datalength++] = Base64[output[2]];
184 target[datalength++] = Pad64;
185 }
186 if (datalength >= targsize)
187 return (-1);
188 target[datalength] = '\0'; /* Returned value doesn't count \0. */
189 return (datalength);
190}
191
192/* skips all whitespace anywhere.
193 converts characters, four at a time, starting at (or after)
194 src from base - 64 numbers into three 8 bit bytes in the target area.
195 it returns the number of data bytes stored at the target, or -1 on error.
196 */
197
198int
199b64_pton(char const *src, u_char *target, size_t targsize)
200{
201 int tarindex, state, ch;
202 char *pos;
203
204 state = 0;
205 tarindex = 0;
206
207 while ((ch = *src++) != '\0') {
208 if (isspace(ch)) /* Skip whitespace anywhere. */
209 continue;
210
211 if (ch == Pad64)
212 break;
213
214 pos = strchr(Base64, ch);
215 if (pos == 0) /* A non-base64 character. */
216 return (-1);
217
218 switch (state) {
219 case 0:
220 if (target) {
221 if (tarindex >= targsize)
222 return (-1);
223 target[tarindex] = (pos - Base64) << 2;
224 }
225 state = 1;
226 break;
227 case 1:
228 if (target) {
229 if (tarindex + 1 >= targsize)
230 return (-1);
231 target[tarindex] |= (pos - Base64) >> 4;
232 target[tarindex+1] = ((pos - Base64) & 0x0f)
233 << 4 ;
234 }
235 tarindex++;
236 state = 2;
237 break;
238 case 2:
239 if (target) {
240 if (tarindex + 1 >= targsize)
241 return (-1);
242 target[tarindex] |= (pos - Base64) >> 2;
243 target[tarindex+1] = ((pos - Base64) & 0x03)
244 << 6;
245 }
246 tarindex++;
247 state = 3;
248 break;
249 case 3:
250 if (target) {
251 if (tarindex >= targsize)
252 return (-1);
253 target[tarindex] |= (pos - Base64);
254 }
255 tarindex++;
256 state = 0;
257 break;
258 }
259 }
260
261 /*
262 * We are done decoding Base-64 chars. Let's see if we ended
263 * on a byte boundary, and/or with erroneous trailing characters.
264 */
265
266 if (ch == Pad64) { /* We got a pad char. */
267 ch = *src++; /* Skip it, get next. */
268 switch (state) {
269 case 0: /* Invalid = in first position */
270 case 1: /* Invalid = in second position */
271 return (-1);
272
273 case 2: /* Valid, means one byte of info */
274 /* Skip any number of spaces. */
275 for (; ch != '\0'; ch = *src++)
276 if (!isspace(ch))
277 break;
278 /* Make sure there is another trailing = sign. */
279 if (ch != Pad64)
280 return (-1);
281 ch = *src++; /* Skip the = */
282 /* Fall through to "single trailing =" case. */
283 /* FALLTHROUGH */
284
285 case 3: /* Valid, means two bytes of info */
286 /*
287 * We know this char is an =. Is there anything but
288 * whitespace after it?
289 */
290 for (; ch != '\0'; ch = *src++)
291 if (!isspace(ch))
292 return (-1);
293
294 /*
295 * Now make sure for cases 2 and 3 that the "extra"
296 * bits that slopped past the last full byte were
297 * zeros. If we don't check them, they become a
298 * subliminal channel.
299 */
300 if (target && target[tarindex] != 0)
301 return (-1);
302 }
303 } else {
304 /*
305 * We ended by seeing the end of the string. Make sure we
306 * have no partial bytes lying around.
307 */
308 if (state != 0)
309 return (-1);
310 }
311
312 return (tarindex);
313}
314
315#endif /* HAVE_B64_NTOP */
diff --git a/bsd-base64.h b/bsd-base64.h
new file mode 100644
index 000000000..c5dace7cb
--- /dev/null
+++ b/bsd-base64.h
@@ -0,0 +1,19 @@
1#ifndef _BSD_BASE64_H
2#define _BSD_BASE64_H
3
4#include "config.h"
5
6#ifndef HAVE___B64_NTOP
7# ifdef HAVE_B64_NTOP
8# define __b64_ntop b64_ntop
9# define __b64_pton b64_pton
10# else /* !HAVE_B64_NTOP */
11
12int b64_ntop(u_char const *src, size_t srclength, char *target,
13 size_t targsize);
14int b64_pton(char const *src, u_char *target, size_t targsize);
15
16# endif /* HAVE_B64_NTOP */
17#endif /* HAVE___B64_NTOP */
18
19#endif /* _BSD_BINRESVPORT_H */
diff --git a/channels.c b/channels.c
index bd8c337ee..f833e1bb9 100644
--- a/channels.c
+++ b/channels.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19#include "includes.h" 19#include "includes.h"
20RCSID("$Id: channels.c,v 1.28 2000/05/01 23:23:45 damien Exp $"); 20RCSID("$Id: channels.c,v 1.29 2000/05/07 02:03:15 damien Exp $");
21 21
22#include "ssh.h" 22#include "ssh.h"
23#include "packet.h" 23#include "packet.h"
@@ -147,8 +147,25 @@ channel_lookup(int id)
147 return c; 147 return c;
148} 148}
149 149
150void
151set_nonblock(int fd)
152{
153 int val;
154 val = fcntl(fd, F_GETFL, 0);
155 if (val < 0) {
156 error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
157 return;
158 }
159 if (val & O_NONBLOCK)
160 return;
161 debug("fd %d setting O_NONBLOCK", fd);
162 val |= O_NONBLOCK;
163 if (fcntl(fd, F_SETFL, val) == -1)
164 error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno));
165}
166
150/* 167/*
151 * register filedescriptors for a channel, used when allocating a channel or 168 * Register filedescriptors for a channel, used when allocating a channel or
152 * when the channel consumer/producer is ready, e.g. shell exec'd 169 * when the channel consumer/producer is ready, e.g. shell exec'd
153 */ 170 */
154 171
@@ -163,11 +180,18 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage)
163 if (efd > channel_max_fd_value) 180 if (efd > channel_max_fd_value)
164 channel_max_fd_value = efd; 181 channel_max_fd_value = efd;
165 /* XXX set close-on-exec -markus */ 182 /* XXX set close-on-exec -markus */
183
166 c->rfd = rfd; 184 c->rfd = rfd;
167 c->wfd = wfd; 185 c->wfd = wfd;
168 c->sock = (rfd == wfd) ? rfd : -1; 186 c->sock = (rfd == wfd) ? rfd : -1;
169 c->efd = efd; 187 c->efd = efd;
170 c->extended_usage = extusage; 188 c->extended_usage = extusage;
189 if (rfd != -1)
190 set_nonblock(rfd);
191 if (wfd != -1)
192 set_nonblock(wfd);
193 if (efd != -1)
194 set_nonblock(efd);
171} 195}
172 196
173/* 197/*
@@ -1532,7 +1556,7 @@ channel_request_remote_forwarding(u_short listen_port, const char *host_to_conne
1532 */ 1556 */
1533 1557
1534void 1558void
1535channel_input_port_forward_request(int is_root) 1559channel_input_port_forward_request(int is_root, int gateway_ports)
1536{ 1560{
1537 u_short port, host_port; 1561 u_short port, host_port;
1538 char *hostname; 1562 char *hostname;
@@ -1551,9 +1575,8 @@ channel_input_port_forward_request(int is_root)
1551 port); 1575 port);
1552 /* 1576 /*
1553 * Initiate forwarding, 1577 * Initiate forwarding,
1554 * bind port to localhost only (gateway ports == 0).
1555 */ 1578 */
1556 channel_request_local_forwarding(port, hostname, host_port, 0); 1579 channel_request_local_forwarding(port, hostname, host_port, gateway_ports);
1557 1580
1558 /* Free the argument string. */ 1581 /* Free the argument string. */
1559 xfree(hostname); 1582 xfree(hostname);
diff --git a/channels.h b/channels.h
index 263934265..9763edf8e 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* RCSID("$Id: channels.h,v 1.8 2000/04/30 00:00:54 damien Exp $"); */ 1/* RCSID("$Id: channels.h,v 1.9 2000/05/07 02:03:15 damien Exp $"); */
2 2
3#ifndef CHANNELS_H 3#ifndef CHANNELS_H
4#define CHANNELS_H 4#define CHANNELS_H
@@ -56,7 +56,7 @@ typedef struct Channel {
56 56
57 char *ctype; /* type */ 57 char *ctype; /* type */
58 58
59 // callback 59 /* callback */
60 channel_callback_fn *cb_fn; 60 channel_callback_fn *cb_fn;
61 void *cb_arg; 61 void *cb_arg;
62 int cb_event; 62 int cb_event;
@@ -175,7 +175,7 @@ void channel_permit_all_opens(void);
175 * listening for the port, and sends back a success reply (or disconnect 175 * listening for the port, and sends back a success reply (or disconnect
176 * message if there was an error). This never returns if there was an error. 176 * message if there was an error). This never returns if there was an error.
177 */ 177 */
178void channel_input_port_forward_request(int is_root); 178void channel_input_port_forward_request(int is_root, int gateway_ports);
179 179
180/* 180/*
181 * Creates a port for X11 connections, and starts listening for it. Returns 181 * Creates a port for X11 connections, and starts listening for it. Returns
diff --git a/clientloop.c b/clientloop.c
index 0ee9fc32a..382cfe1f3 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: clientloop.c,v 1.13 2000/04/30 00:00:54 damien Exp $"); 19RCSID("$Id: clientloop.c,v 1.14 2000/05/07 02:03:16 damien Exp $");
20 20
21#include "xmalloc.h" 21#include "xmalloc.h"
22#include "ssh.h" 22#include "ssh.h"
@@ -971,7 +971,7 @@ client_input_channel_open(int type, int plen)
971 rwindow = packet_get_int(); 971 rwindow = packet_get_int();
972 rmaxpack = packet_get_int(); 972 rmaxpack = packet_get_int();
973 973
974 log("server_input_open: ctype %s rchan %d win %d max %d", 974 debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
975 ctype, rchan, rwindow, rmaxpack); 975 ctype, rchan, rwindow, rmaxpack);
976 976
977 if (strcmp(ctype, "x11") == 0) { 977 if (strcmp(ctype, "x11") == 0) {
@@ -1077,7 +1077,7 @@ client_input_channel_req(int id, void *arg)
1077 rtype = packet_get_string(&len); 1077 rtype = packet_get_string(&len);
1078 reply = packet_get_char(); 1078 reply = packet_get_char();
1079 1079
1080 debug("session_input_channel_req: rtype %s reply %d", rtype, reply); 1080 debug("client_input_channel_req: rtype %s reply %d", rtype, reply);
1081 1081
1082 c = channel_lookup(id); 1082 c = channel_lookup(id);
1083 if (c == NULL) 1083 if (c == NULL)
diff --git a/configure.in b/configure.in
index be2a63df1..1b099c6b8 100644
--- a/configure.in
+++ b/configure.in
@@ -132,7 +132,7 @@ fi
132AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h) 132AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h)
133 133
134# Checks for library functions. 134# Checks for library functions.
135AC_CHECK_FUNCS(arc4random bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage innetgr md5_crypt mkdtemp openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmpx vsnprintf vhangup _getpty) 135AC_CHECK_FUNCS(arc4random b64_ntop bindresvport_af clock freeaddrinfo gai_strerror getaddrinfo getnameinfo getrusage innetgr md5_crypt mkdtemp openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmpx vsnprintf vhangup _getpty __b64_ntop)
136 136
137AC_CHECK_FUNC(login, 137AC_CHECK_FUNC(login,
138 [AC_DEFINE(HAVE_LOGIN)], 138 [AC_DEFINE(HAVE_LOGIN)],
@@ -196,7 +196,7 @@ saved_CFLAGS="$CFLAGS"
196if test "x$prefix" != "xNONE" ; then 196if test "x$prefix" != "xNONE" ; then
197 tryssldir="$tryssldir $prefix" 197 tryssldir="$tryssldir $prefix"
198fi 198fi
199AC_MSG_CHECKING([for OpenSSL/SSLeay directory]) 199AC_MSG_CHECKING([for OpenSSL directory])
200for ssldir in "" $tryssldir /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do 200for ssldir in "" $tryssldir /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do
201 if test ! -z "$ssldir" ; then 201 if test ! -z "$ssldir" ; then
202 LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir" 202 LDFLAGS="$saved_LDFLAGS -L$ssldir/lib -L$ssldir"
diff --git a/dsa.c b/dsa.c
index a4f6d3e78..580590809 100644
--- a/dsa.c
+++ b/dsa.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$Id: dsa.c,v 1.5 2000/04/26 20:56:29 markus Exp $"); 31RCSID("$Id: dsa.c,v 1.6 2000/05/04 22:37:59 markus Exp $");
32 32
33#include "ssh.h" 33#include "ssh.h"
34#include "xmalloc.h" 34#include "xmalloc.h"
@@ -63,7 +63,7 @@ dsa_key_from_blob(
63 Key *key; 63 Key *key;
64 64
65#ifdef DEBUG_DSS 65#ifdef DEBUG_DSS
66 dump_base64(blob, blen); 66 dump_base64(stderr, blob, blen);
67#endif 67#endif
68 /* fetch & parse DSA/DSS pubkey */ 68 /* fetch & parse DSA/DSS pubkey */
69 key = key_new(KEY_DSA); 69 key = key_new(KEY_DSA);
diff --git a/includes.h b/includes.h
index a83e03167..56878a040 100644
--- a/includes.h
+++ b/includes.h
@@ -99,6 +99,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
99#include "bsd-snprintf.h" 99#include "bsd-snprintf.h"
100#include "bsd-daemon.h" 100#include "bsd-daemon.h"
101#include "bsd-login.h" 101#include "bsd-login.h"
102#include "bsd-base64.h"
102 103
103/* rfc2553 socket API replacements */ 104/* rfc2553 socket API replacements */
104#include "fake-getaddrinfo.h" 105#include "fake-getaddrinfo.h"
diff --git a/key.c b/key.c
index 583c52901..ae355a3fc 100644
--- a/key.c
+++ b/key.c
@@ -255,6 +255,10 @@ key_read(Key *ret, char **cpp)
255 len = 2*strlen(cp); 255 len = 2*strlen(cp);
256 blob = xmalloc(len); 256 blob = xmalloc(len);
257 n = uudecode(cp, blob, len); 257 n = uudecode(cp, blob, len);
258 if (n < 0) {
259 error("uudecode %s failed", cp);
260 return 0;
261 }
258 k = dsa_key_from_blob(blob, n); 262 k = dsa_key_from_blob(blob, n);
259 if (k == NULL) 263 if (k == NULL)
260 return 0; 264 return 0;
@@ -297,11 +301,26 @@ key_write(Key *key, FILE *f)
297 unsigned char *blob, *uu; 301 unsigned char *blob, *uu;
298 dsa_make_key_blob(key, &blob, &len); 302 dsa_make_key_blob(key, &blob, &len);
299 uu = xmalloc(2*len); 303 uu = xmalloc(2*len);
300 n = uuencode(blob, len, uu); 304 n = uuencode(blob, len, uu, 2*len);
301 fprintf(f, "%s %s", SSH_DSS, uu); 305 if (n > 0) {
306 fprintf(f, "%s %s", SSH_DSS, uu);
307 success = 1;
308 }
302 xfree(blob); 309 xfree(blob);
303 xfree(uu); 310 xfree(uu);
304 success = 1;
305 } 311 }
306 return success; 312 return success;
307} 313}
314char *
315key_type(Key *k)
316{
317 switch (k->type) {
318 case KEY_RSA:
319 return "RSA";
320 break;
321 case KEY_DSA:
322 return "DSA";
323 break;
324 }
325 return "unknown";
326}
diff --git a/key.h b/key.h
index d1bcf3b1b..ed3f770b8 100644
--- a/key.h
+++ b/key.h
@@ -17,6 +17,7 @@ Key *key_new(int type);
17void key_free(Key *k); 17void key_free(Key *k);
18int key_equal(Key *a, Key *b); 18int key_equal(Key *a, Key *b);
19char *key_fingerprint(Key *k); 19char *key_fingerprint(Key *k);
20char *key_type(Key *k);
20int key_write(Key *key, FILE *f); 21int key_write(Key *key, FILE *f);
21unsigned int 22unsigned int
22key_read(Key *key, char **cpp); 23key_read(Key *key, char **cpp);
diff --git a/nchan.c b/nchan.c
index f2dace0e4..b00686a48 100644
--- a/nchan.c
+++ b/nchan.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$Id: nchan.c,v 1.8 2000/04/16 01:18:43 damien Exp $"); 31RCSID("$Id: nchan.c,v 1.9 2000/05/07 02:03:16 damien Exp $");
32 32
33#include "ssh.h" 33#include "ssh.h"
34 34
@@ -139,6 +139,25 @@ static void
139chan_rcvd_ieof1(Channel *c) 139chan_rcvd_ieof1(Channel *c)
140{ 140{
141 debug("channel %d: rcvd ieof", c->self); 141 debug("channel %d: rcvd ieof", c->self);
142 if (c->type != SSH_CHANNEL_OPEN) {
143 debug("channel %d: non-open", c->self);
144 if (c->istate == CHAN_INPUT_OPEN) {
145 debug("channel %d: non-open: input open -> wait_oclose", c->self);
146 chan_shutdown_read(c);
147 chan_send_ieof1(c);
148 c->istate = CHAN_INPUT_WAIT_OCLOSE;
149 } else {
150 error("channel %d: istate %d != open", c->self, c->istate);
151 }
152 if (c->ostate == CHAN_OUTPUT_OPEN) {
153 debug("channel %d: non-open: output open -> closed", c->self);
154 chan_send_oclose1(c);
155 c->ostate = CHAN_OUTPUT_CLOSED;
156 } else {
157 error("channel %d: ostate %d != open", c->self, c->ostate);
158 }
159 return;
160 }
142 switch (c->ostate) { 161 switch (c->ostate) {
143 case CHAN_OUTPUT_OPEN: 162 case CHAN_OUTPUT_OPEN:
144 debug("channel %d: output open -> drain", c->self); 163 debug("channel %d: output open -> drain", c->self);
@@ -314,7 +333,7 @@ chan_write_failed2(Channel *c)
314 switch (c->ostate) { 333 switch (c->ostate) {
315 case CHAN_OUTPUT_OPEN: 334 case CHAN_OUTPUT_OPEN:
316 debug("channel %d: output open -> closed", c->self); 335 debug("channel %d: output open -> closed", c->self);
317 chan_shutdown_write(c); // ?? 336 chan_shutdown_write(c); /* ?? */
318 c->ostate = CHAN_OUTPUT_CLOSED; 337 c->ostate = CHAN_OUTPUT_CLOSED;
319 break; 338 break;
320 case CHAN_OUTPUT_WAIT_DRAIN: 339 case CHAN_OUTPUT_WAIT_DRAIN:
diff --git a/packet.c b/packet.c
index e70d06091..dfe21fa1c 100644
--- a/packet.c
+++ b/packet.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19#include "includes.h" 19#include "includes.h"
20RCSID("$Id: packet.c,v 1.21 2000/05/01 11:10:33 damien Exp $"); 20RCSID("$Id: packet.c,v 1.22 2000/05/07 02:03:17 damien Exp $");
21 21
22#include "xmalloc.h" 22#include "xmalloc.h"
23#include "buffer.h" 23#include "buffer.h"
@@ -465,7 +465,7 @@ packet_send1()
465 /* Compute packet length without padding (add checksum, remove padding). */ 465 /* Compute packet length without padding (add checksum, remove padding). */
466 len = buffer_len(&outgoing_packet) + 4 - 8; 466 len = buffer_len(&outgoing_packet) + 4 - 8;
467 467
468 /* Insert padding. */ 468 /* Insert padding. Initialized to zero in packet_start1() */
469 padding = 8 - len % 8; 469 padding = 8 - len % 8;
470 if (cipher_type != SSH_CIPHER_NONE) { 470 if (cipher_type != SSH_CIPHER_NONE) {
471 cp = buffer_ptr(&outgoing_packet); 471 cp = buffer_ptr(&outgoing_packet);
@@ -569,12 +569,16 @@ packet_send2()
569 padlen += block_size; 569 padlen += block_size;
570 buffer_append_space(&outgoing_packet, &cp, padlen); 570 buffer_append_space(&outgoing_packet, &cp, padlen);
571 if (enc && enc->type != SSH_CIPHER_NONE) { 571 if (enc && enc->type != SSH_CIPHER_NONE) {
572 /* random padding */
572 for (i = 0; i < padlen; i++) { 573 for (i = 0; i < padlen; i++) {
573 if (i % 4 == 0) 574 if (i % 4 == 0)
574 rand = arc4random(); 575 rand = arc4random();
575 cp[i] = rand & 0xff; 576 cp[i] = rand & 0xff;
576 rand <<= 8; 577 rand <<= 8;
577 } 578 }
579 } else {
580 /* clear padding */
581 memset(cp, 0, padlen);
578 } 582 }
579 /* packet_length includes payload, padding and padding length field */ 583 /* packet_length includes payload, padding and padding length field */
580 packet_length = buffer_len(&outgoing_packet) - 4; 584 packet_length = buffer_len(&outgoing_packet) - 4;
@@ -657,10 +661,11 @@ packet_read(int *payload_len_ptr)
657 for (;;) { 661 for (;;) {
658 /* Try to read a packet from the buffer. */ 662 /* Try to read a packet from the buffer. */
659 type = packet_read_poll(payload_len_ptr); 663 type = packet_read_poll(payload_len_ptr);
660 if (type == SSH_SMSG_SUCCESS 664 if (!use_ssh2_packet_format && (
665 type == SSH_SMSG_SUCCESS
661 || type == SSH_SMSG_FAILURE 666 || type == SSH_SMSG_FAILURE
662 || type == SSH_CMSG_EOF 667 || type == SSH_CMSG_EOF
663 || type == SSH_CMSG_EXIT_CONFIRMATION) 668 || type == SSH_CMSG_EXIT_CONFIRMATION))
664 packet_integrity_check(*payload_len_ptr, 0, type); 669 packet_integrity_check(*payload_len_ptr, 0, type);
665 /* If we got a packet, return it. */ 670 /* If we got a packet, return it. */
666 if (type != SSH_MSG_NONE) 671 if (type != SSH_MSG_NONE)
diff --git a/radix.c b/radix.c
index 9d1c999a1..033773344 100644
--- a/radix.c
+++ b/radix.c
@@ -69,7 +69,7 @@ typedef unsigned short my_u_short;
69 69
70 70
71int 71int
72creds_to_radix(CREDENTIALS *creds, unsigned char *buf) 72creds_to_radix(CREDENTIALS *creds, unsigned char *buf, size_t buflen)
73{ 73{
74 char *p, *s; 74 char *p, *s;
75 int len; 75 int len;
@@ -119,7 +119,7 @@ creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
119 p += creds->ticket_st.length; 119 p += creds->ticket_st.length;
120 len = p - temp; 120 len = p - temp;
121 121
122 return (uuencode((unsigned char *)temp, len, (char *)buf)); 122 return (uuencode((unsigned char *)temp, len, (char *)buf, buflen));
123} 123}
124 124
125int 125int
@@ -131,7 +131,8 @@ radix_to_creds(const char *buf, CREDENTIALS *creds)
131 char version; 131 char version;
132 char temp[2048]; 132 char temp[2048];
133 133
134 if (!(len = uudecode(buf, (unsigned char *)temp, sizeof(temp)))) 134 len = uudecode(buf, (unsigned char *)temp, sizeof(temp));
135 if (len < 0)
135 return 0; 136 return 0;
136 137
137 p = temp; 138 p = temp;
diff --git a/readconf.c b/readconf.c
index 529f8039b..c69e10dda 100644
--- a/readconf.c
+++ b/readconf.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: readconf.c,v 1.12 2000/04/29 13:57:11 damien Exp $"); 17RCSID("$Id: readconf.c,v 1.13 2000/05/07 02:03:17 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "cipher.h" 20#include "cipher.h"
@@ -105,7 +105,7 @@ typedef enum {
105 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 105 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
106 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, 106 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
107 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2, 107 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2,
108 oGlobalKnownHostsFile2, oUserKnownHostsFile2 108 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication
109} OpCodes; 109} OpCodes;
110 110
111/* Textual representations of the tokens. */ 111/* Textual representations of the tokens. */
@@ -121,6 +121,7 @@ static struct {
121 { "rhostsauthentication", oRhostsAuthentication }, 121 { "rhostsauthentication", oRhostsAuthentication },
122 { "passwordauthentication", oPasswordAuthentication }, 122 { "passwordauthentication", oPasswordAuthentication },
123 { "rsaauthentication", oRSAAuthentication }, 123 { "rsaauthentication", oRSAAuthentication },
124 { "dsaauthentication", oDSAAuthentication },
124 { "skeyauthentication", oSkeyAuthentication }, 125 { "skeyauthentication", oSkeyAuthentication },
125#ifdef KRB4 126#ifdef KRB4
126 { "kerberosauthentication", oKerberosAuthentication }, 127 { "kerberosauthentication", oKerberosAuthentication },
@@ -290,6 +291,10 @@ parse_flag:
290 intptr = &options->password_authentication; 291 intptr = &options->password_authentication;
291 goto parse_flag; 292 goto parse_flag;
292 293
294 case oDSAAuthentication:
295 intptr = &options->dsa_authentication;
296 goto parse_flag;
297
293 case oRSAAuthentication: 298 case oRSAAuthentication:
294 intptr = &options->rsa_authentication; 299 intptr = &options->rsa_authentication;
295 goto parse_flag; 300 goto parse_flag;
@@ -637,6 +642,7 @@ initialize_options(Options * options)
637 options->use_privileged_port = -1; 642 options->use_privileged_port = -1;
638 options->rhosts_authentication = -1; 643 options->rhosts_authentication = -1;
639 options->rsa_authentication = -1; 644 options->rsa_authentication = -1;
645 options->dsa_authentication = -1;
640 options->skey_authentication = -1; 646 options->skey_authentication = -1;
641#ifdef KRB4 647#ifdef KRB4
642 options->kerberos_authentication = -1; 648 options->kerberos_authentication = -1;
@@ -696,6 +702,8 @@ fill_default_options(Options * options)
696 options->rhosts_authentication = 1; 702 options->rhosts_authentication = 1;
697 if (options->rsa_authentication == -1) 703 if (options->rsa_authentication == -1)
698 options->rsa_authentication = 1; 704 options->rsa_authentication = 1;
705 if (options->dsa_authentication == -1)
706 options->dsa_authentication = 1;
699 if (options->skey_authentication == -1) 707 if (options->skey_authentication == -1)
700 options->skey_authentication = 0; 708 options->skey_authentication = 0;
701#ifdef KRB4 709#ifdef KRB4
@@ -745,14 +753,12 @@ fill_default_options(Options * options)
745 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); 753 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
746 options->num_identity_files = 1; 754 options->num_identity_files = 1;
747 } 755 }
748#if 0
749 if (options->num_identity_files2 == 0) { 756 if (options->num_identity_files2 == 0) {
750 options->identity_files2[0] = 757 options->identity_files2[0] =
751 xmalloc(2 + strlen(SSH2_CLIENT_IDENTITY) + 1); 758 xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
752 sprintf(options->identity_files2[0], "~/%.100s", SSH2_CLIENT_IDENTITY); 759 sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA);
753 options->num_identity_files2 = 1; 760 options->num_identity_files2 = 1;
754 } 761 }
755#endif
756 if (options->escape_char == -1) 762 if (options->escape_char == -1)
757 options->escape_char = '~'; 763 options->escape_char = '~';
758 if (options->system_hostfile == NULL) 764 if (options->system_hostfile == NULL)
diff --git a/readconf.h b/readconf.h
index bbef923ab..ba53542d9 100644
--- a/readconf.h
+++ b/readconf.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: readconf.h,v 1.9 2000/04/29 13:57:11 damien Exp $"); */ 16/* RCSID("$Id: readconf.h,v 1.10 2000/05/07 02:03:17 damien Exp $"); */
17 17
18#ifndef READCONF_H 18#ifndef READCONF_H
19#define READCONF_H 19#define READCONF_H
@@ -36,6 +36,7 @@ typedef struct {
36 int rhosts_rsa_authentication; /* Try rhosts with RSA 36 int rhosts_rsa_authentication; /* Try rhosts with RSA
37 * authentication. */ 37 * authentication. */
38 int rsa_authentication; /* Try RSA authentication. */ 38 int rsa_authentication; /* Try RSA authentication. */
39 int dsa_authentication; /* Try DSA authentication. */
39 int skey_authentication; /* Try S/Key or TIS authentication. */ 40 int skey_authentication; /* Try S/Key or TIS authentication. */
40#ifdef KRB4 41#ifdef KRB4
41 int kerberos_authentication; /* Try Kerberos 42 int kerberos_authentication; /* Try Kerberos
diff --git a/scp.c b/scp.c
index 2ac106290..2831f9b99 100644
--- a/scp.c
+++ b/scp.c
@@ -45,7 +45,7 @@
45 */ 45 */
46 46
47#include "includes.h" 47#include "includes.h"
48RCSID("$Id: scp.c,v 1.21 2000/05/01 11:10:33 damien Exp $"); 48RCSID("$Id: scp.c,v 1.22 2000/05/07 02:03:17 damien Exp $");
49 49
50#include "ssh.h" 50#include "ssh.h"
51#include "xmalloc.h" 51#include "xmalloc.h"
@@ -573,7 +573,7 @@ next: (void) close(fd);
573 if (i + amt > stb.st_size) 573 if (i + amt > stb.st_size)
574 amt = stb.st_size - i; 574 amt = stb.st_size - i;
575 if (!haderr) { 575 if (!haderr) {
576 result = read(fd, bp->buf, amt); 576 result = atomicio(read, fd, bp->buf, amt);
577 if (result != amt) 577 if (result != amt)
578 haderr = result >= 0 ? EIO : errno; 578 haderr = result >= 0 ? EIO : errno;
579 } 579 }
@@ -692,12 +692,12 @@ sink(argc, argv)
692 targisdir = 1; 692 targisdir = 1;
693 for (first = 1;; first = 0) { 693 for (first = 1;; first = 0) {
694 cp = buf; 694 cp = buf;
695 if (read(remin, cp, 1) <= 0) 695 if (atomicio(read, remin, cp, 1) <= 0)
696 return; 696 return;
697 if (*cp++ == '\n') 697 if (*cp++ == '\n')
698 SCREWUP("unexpected <newline>"); 698 SCREWUP("unexpected <newline>");
699 do { 699 do {
700 if (read(remin, &ch, sizeof(ch)) != sizeof(ch)) 700 if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
701 SCREWUP("lost connection"); 701 SCREWUP("lost connection");
702 *cp++ = ch; 702 *cp++ = ch;
703 } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); 703 } while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
@@ -835,7 +835,7 @@ bad: run_err("%s: %s", np, strerror(errno));
835 amt = size - i; 835 amt = size - i;
836 count += amt; 836 count += amt;
837 do { 837 do {
838 j = read(remin, cp, amt); 838 j = atomicio(read, remin, cp, amt);
839 if (j <= 0) { 839 if (j <= 0) {
840 run_err("%s", j ? strerror(errno) : 840 run_err("%s", j ? strerror(errno) :
841 "dropped connection"); 841 "dropped connection");
@@ -848,7 +848,7 @@ bad: run_err("%s: %s", np, strerror(errno));
848 if (count == bp->cnt) { 848 if (count == bp->cnt) {
849 /* Keep reading so we stay sync'd up. */ 849 /* Keep reading so we stay sync'd up. */
850 if (wrerr == NO) { 850 if (wrerr == NO) {
851 j = write(ofd, bp->buf, count); 851 j = atomicio(write, ofd, bp->buf, count);
852 if (j != count) { 852 if (j != count) {
853 wrerr = YES; 853 wrerr = YES;
854 wrerrno = j >= 0 ? EIO : errno; 854 wrerrno = j >= 0 ? EIO : errno;
@@ -861,7 +861,7 @@ bad: run_err("%s: %s", np, strerror(errno));
861 if (showprogress) 861 if (showprogress)
862 progressmeter(1); 862 progressmeter(1);
863 if (count != 0 && wrerr == NO && 863 if (count != 0 && wrerr == NO &&
864 (j = write(ofd, bp->buf, count)) != count) { 864 (j = atomicio(write, ofd, bp->buf, count)) != count) {
865 wrerr = YES; 865 wrerr = YES;
866 wrerrno = j >= 0 ? EIO : errno; 866 wrerrno = j >= 0 ? EIO : errno;
867 } 867 }
@@ -913,7 +913,7 @@ response()
913{ 913{
914 char ch, *cp, resp, rbuf[2048]; 914 char ch, *cp, resp, rbuf[2048];
915 915
916 if (read(remin, &resp, sizeof(resp)) != sizeof(resp)) 916 if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp))
917 lostconn(0); 917 lostconn(0);
918 918
919 cp = rbuf; 919 cp = rbuf;
@@ -926,7 +926,7 @@ response()
926 case 1: /* error, followed by error msg */ 926 case 1: /* error, followed by error msg */
927 case 2: /* fatal error, "" */ 927 case 2: /* fatal error, "" */
928 do { 928 do {
929 if (read(remin, &ch, sizeof(ch)) != sizeof(ch)) 929 if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
930 lostconn(0); 930 lostconn(0);
931 *cp++ = ch; 931 *cp++ = ch;
932 } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); 932 } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n');
@@ -1008,7 +1008,7 @@ run_err(const char *fmt,...)
1008 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1008 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1009 * SUCH DAMAGE. 1009 * SUCH DAMAGE.
1010 * 1010 *
1011 * $Id: scp.c,v 1.21 2000/05/01 11:10:33 damien Exp $ 1011 * $Id: scp.c,v 1.22 2000/05/07 02:03:17 damien Exp $
1012 */ 1012 */
1013 1013
1014char * 1014char *
diff --git a/servconf.c b/servconf.c
index 16eaeba01..ada4f487c 100644
--- a/servconf.c
+++ b/servconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: servconf.c,v 1.14 2000/05/01 23:23:45 damien Exp $"); 15RCSID("$Id: servconf.c,v 1.15 2000/05/07 02:03:18 damien Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "servconf.h" 18#include "servconf.h"
@@ -32,7 +32,7 @@ initialize_server_options(ServerOptions *options)
32 options->ports_from_cmdline = 0; 32 options->ports_from_cmdline = 0;
33 options->listen_addrs = NULL; 33 options->listen_addrs = NULL;
34 options->host_key_file = NULL; 34 options->host_key_file = NULL;
35 options->dsa_key_file = NULL; 35 options->host_dsa_key_file = NULL;
36 options->pid_file = NULL; 36 options->pid_file = NULL;
37 options->server_key_bits = -1; 37 options->server_key_bits = -1;
38 options->login_grace_time = -1; 38 options->login_grace_time = -1;
@@ -51,6 +51,7 @@ initialize_server_options(ServerOptions *options)
51 options->rhosts_authentication = -1; 51 options->rhosts_authentication = -1;
52 options->rhosts_rsa_authentication = -1; 52 options->rhosts_rsa_authentication = -1;
53 options->rsa_authentication = -1; 53 options->rsa_authentication = -1;
54 options->dsa_authentication = -1;
54#ifdef KRB4 55#ifdef KRB4
55 options->kerberos_authentication = -1; 56 options->kerberos_authentication = -1;
56 options->kerberos_or_local_passwd = -1; 57 options->kerberos_or_local_passwd = -1;
@@ -72,6 +73,7 @@ initialize_server_options(ServerOptions *options)
72 options->num_deny_groups = 0; 73 options->num_deny_groups = 0;
73 options->ciphers = NULL; 74 options->ciphers = NULL;
74 options->protocol = SSH_PROTO_UNKNOWN; 75 options->protocol = SSH_PROTO_UNKNOWN;
76 options->gateway_ports = -1;
75} 77}
76 78
77void 79void
@@ -83,8 +85,8 @@ fill_default_server_options(ServerOptions *options)
83 add_listen_addr(options, NULL); 85 add_listen_addr(options, NULL);
84 if (options->host_key_file == NULL) 86 if (options->host_key_file == NULL)
85 options->host_key_file = HOST_KEY_FILE; 87 options->host_key_file = HOST_KEY_FILE;
86 if (options->dsa_key_file == NULL) 88 if (options->host_dsa_key_file == NULL)
87 options->dsa_key_file = DSA_KEY_FILE; 89 options->host_dsa_key_file = HOST_DSA_KEY_FILE;
88 if (options->pid_file == NULL) 90 if (options->pid_file == NULL)
89 options->pid_file = SSH_DAEMON_PID_FILE; 91 options->pid_file = SSH_DAEMON_PID_FILE;
90 if (options->server_key_bits == -1) 92 if (options->server_key_bits == -1)
@@ -121,6 +123,8 @@ fill_default_server_options(ServerOptions *options)
121 options->rhosts_rsa_authentication = 0; 123 options->rhosts_rsa_authentication = 0;
122 if (options->rsa_authentication == -1) 124 if (options->rsa_authentication == -1)
123 options->rsa_authentication = 1; 125 options->rsa_authentication = 1;
126 if (options->dsa_authentication == -1)
127 options->dsa_authentication = 1;
124#ifdef KRB4 128#ifdef KRB4
125 if (options->kerberos_authentication == -1) 129 if (options->kerberos_authentication == -1)
126 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0); 130 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
@@ -147,6 +151,8 @@ fill_default_server_options(ServerOptions *options)
147 options->use_login = 0; 151 options->use_login = 0;
148 if (options->protocol == SSH_PROTO_UNKNOWN) 152 if (options->protocol == SSH_PROTO_UNKNOWN)
149 options->protocol = SSH_PROTO_1|SSH_PROTO_2; 153 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
154 if (options->gateway_ports == -1)
155 options->gateway_ports = 0;
150} 156}
151 157
152#define WHITESPACE " \t\r\n" 158#define WHITESPACE " \t\r\n"
@@ -170,7 +176,8 @@ typedef enum {
170 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, 176 sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
171 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, 177 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
172 sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 178 sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
173 sIgnoreUserKnownHosts, sDSAKeyFile, sCiphers, sProtocol, sPidFile 179 sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
180 sGatewayPorts, sDSAAuthentication
174} ServerOpCodes; 181} ServerOpCodes;
175 182
176/* Textual representation of the tokens. */ 183/* Textual representation of the tokens. */
@@ -180,7 +187,7 @@ static struct {
180} keywords[] = { 187} keywords[] = {
181 { "port", sPort }, 188 { "port", sPort },
182 { "hostkey", sHostKeyFile }, 189 { "hostkey", sHostKeyFile },
183 { "dsakey", sDSAKeyFile }, 190 { "hostdsakey", sHostDSAKeyFile },
184 { "pidfile", sPidFile }, 191 { "pidfile", sPidFile },
185 { "serverkeybits", sServerKeyBits }, 192 { "serverkeybits", sServerKeyBits },
186 { "logingracetime", sLoginGraceTime }, 193 { "logingracetime", sLoginGraceTime },
@@ -191,6 +198,7 @@ static struct {
191 { "rhostsauthentication", sRhostsAuthentication }, 198 { "rhostsauthentication", sRhostsAuthentication },
192 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 199 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
193 { "rsaauthentication", sRSAAuthentication }, 200 { "rsaauthentication", sRSAAuthentication },
201 { "dsaauthentication", sDSAAuthentication },
194#ifdef KRB4 202#ifdef KRB4
195 { "kerberosauthentication", sKerberosAuthentication }, 203 { "kerberosauthentication", sKerberosAuthentication },
196 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, 204 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
@@ -222,6 +230,7 @@ static struct {
222 { "denygroups", sDenyGroups }, 230 { "denygroups", sDenyGroups },
223 { "ciphers", sCiphers }, 231 { "ciphers", sCiphers },
224 { "protocol", sProtocol }, 232 { "protocol", sProtocol },
233 { "gatewayports", sGatewayPorts },
225 { NULL, 0 } 234 { NULL, 0 }
226}; 235};
227 236
@@ -353,9 +362,9 @@ parse_int:
353 break; 362 break;
354 363
355 case sHostKeyFile: 364 case sHostKeyFile:
356 case sDSAKeyFile: 365 case sHostDSAKeyFile:
357 charptr = (opcode == sHostKeyFile ) ? 366 charptr = (opcode == sHostKeyFile ) ?
358 &options->host_key_file : &options->dsa_key_file; 367 &options->host_key_file : &options->host_dsa_key_file;
359 cp = strtok(NULL, WHITESPACE); 368 cp = strtok(NULL, WHITESPACE);
360 if (!cp) { 369 if (!cp) {
361 fprintf(stderr, "%s line %d: missing file name.\n", 370 fprintf(stderr, "%s line %d: missing file name.\n",
@@ -445,6 +454,10 @@ parse_flag:
445 intptr = &options->rsa_authentication; 454 intptr = &options->rsa_authentication;
446 goto parse_flag; 455 goto parse_flag;
447 456
457 case sDSAAuthentication:
458 intptr = &options->dsa_authentication;
459 goto parse_flag;
460
448#ifdef KRB4 461#ifdef KRB4
449 case sKerberosAuthentication: 462 case sKerberosAuthentication:
450 intptr = &options->kerberos_authentication; 463 intptr = &options->kerberos_authentication;
@@ -511,6 +524,10 @@ parse_flag:
511 intptr = &options->use_login; 524 intptr = &options->use_login;
512 goto parse_flag; 525 goto parse_flag;
513 526
527 case sGatewayPorts:
528 intptr = &options->gateway_ports;
529 goto parse_flag;
530
514 case sLogFacility: 531 case sLogFacility:
515 intptr = (int *) &options->log_facility; 532 intptr = (int *) &options->log_facility;
516 cp = strtok(NULL, WHITESPACE); 533 cp = strtok(NULL, WHITESPACE);
diff --git a/servconf.h b/servconf.h
index a5010093d..107438c05 100644
--- a/servconf.h
+++ b/servconf.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: servconf.h,v 1.10 2000/05/01 23:23:46 damien Exp $"); */ 16/* RCSID("$Id: servconf.h,v 1.11 2000/05/07 02:03:18 damien Exp $"); */
17 17
18#ifndef SERVCONF_H 18#ifndef SERVCONF_H
19#define SERVCONF_H 19#define SERVCONF_H
@@ -32,7 +32,7 @@ typedef struct {
32 char *listen_addr; /* Address on which the server listens. */ 32 char *listen_addr; /* Address on which the server listens. */
33 struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ 33 struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
34 char *host_key_file; /* File containing host key. */ 34 char *host_key_file; /* File containing host key. */
35 char *dsa_key_file; /* File containing dsa host key. */ 35 char *host_dsa_key_file; /* File containing dsa host key. */
36 char *pid_file; /* Where to put our pid */ 36 char *pid_file; /* Where to put our pid */
37 int server_key_bits;/* Size of the server key. */ 37 int server_key_bits;/* Size of the server key. */
38 int login_grace_time; /* Disconnect if no auth in this time 38 int login_grace_time; /* Disconnect if no auth in this time
@@ -51,6 +51,7 @@ typedef struct {
51 int keepalives; /* If true, set SO_KEEPALIVE. */ 51 int keepalives; /* If true, set SO_KEEPALIVE. */
52 char *ciphers; /* Ciphers in order of preference. */ 52 char *ciphers; /* Ciphers in order of preference. */
53 int protocol; /* Protocol in order of preference. */ 53 int protocol; /* Protocol in order of preference. */
54 int gateway_ports; /* If true, allow remote connects to forwarded ports. */
54 SyslogFacility log_facility; /* Facility for system logging. */ 55 SyslogFacility log_facility; /* Facility for system logging. */
55 LogLevel log_level; /* Level for system logging. */ 56 LogLevel log_level; /* Level for system logging. */
56 int rhosts_authentication; /* If true, permit rhosts 57 int rhosts_authentication; /* If true, permit rhosts
@@ -58,6 +59,7 @@ typedef struct {
58 int rhosts_rsa_authentication; /* If true, permit rhosts RSA 59 int rhosts_rsa_authentication; /* If true, permit rhosts RSA
59 * authentication. */ 60 * authentication. */
60 int rsa_authentication; /* If true, permit RSA authentication. */ 61 int rsa_authentication; /* If true, permit RSA authentication. */
62 int dsa_authentication; /* If true, permit DSA authentication. */
61#ifdef KRB4 63#ifdef KRB4
62 int kerberos_authentication; /* If true, permit Kerberos 64 int kerberos_authentication; /* If true, permit Kerberos
63 * authentication. */ 65 * authentication. */
diff --git a/serverloop.c b/serverloop.c
index 1e031873c..1bc5d8b75 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -171,7 +171,7 @@ retry_select:
171 * stdin or channel data. 171 * stdin or channel data.
172 */ 172 */
173 if (compat20) { 173 if (compat20) {
174 // wrong: bad conditionXXX 174 /* wrong: bad condition XXX */
175 if (channel_not_very_much_buffered_data()) 175 if (channel_not_very_much_buffered_data())
176 FD_SET(connection_in, readset); 176 FD_SET(connection_in, readset);
177 } else { 177 } else {
diff --git a/session.c b/session.c
index 0679d837c..c490f087e 100644
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$OpenBSD: session.c,v 1.8 2000/04/29 16:06:08 markus Exp $"); 11RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $");
12 12
13#include "xmalloc.h" 13#include "xmalloc.h"
14#include "ssh.h" 14#include "ssh.h"
@@ -57,6 +57,7 @@ struct Session {
57Session *session_new(void); 57Session *session_new(void);
58void session_set_fds(Session *s, int fdin, int fdout, int fderr); 58void session_set_fds(Session *s, int fdin, int fdout, int fderr);
59void session_pty_cleanup(Session *s); 59void session_pty_cleanup(Session *s);
60void session_proctitle(Session *s);
60void do_exec_pty(Session *s, const char *command, struct passwd * pw); 61void do_exec_pty(Session *s, const char *command, struct passwd * pw);
61void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); 62void do_exec_no_pty(Session *s, const char *command, struct passwd * pw);
62 63
@@ -240,6 +241,8 @@ do_authenticated(struct passwd * pw)
240 tty_parse_modes(s->ttyfd, &n_bytes); 241 tty_parse_modes(s->ttyfd, &n_bytes);
241 packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type); 242 packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type);
242 243
244 session_proctitle(s);
245
243 /* Indicate that we now have a pty. */ 246 /* Indicate that we now have a pty. */
244 success = 1; 247 success = 1;
245 have_pty = 1; 248 have_pty = 1;
@@ -312,7 +315,7 @@ do_authenticated(struct passwd * pw)
312 break; 315 break;
313 } 316 }
314 debug("Received TCP/IP port forwarding request."); 317 debug("Received TCP/IP port forwarding request.");
315 channel_input_port_forward_request(pw->pw_uid == 0); 318 channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports);
316 success = 1; 319 success = 1;
317 break; 320 break;
318 321
@@ -397,7 +400,7 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw)
397 if (s == NULL) 400 if (s == NULL)
398 fatal("do_exec_no_pty: no session"); 401 fatal("do_exec_no_pty: no session");
399 402
400 setproctitle("%s@notty", pw->pw_name); 403 session_proctitle(s);
401 404
402#ifdef USE_PAM 405#ifdef USE_PAM
403 do_pam_setcred(); 406 do_pam_setcred();
@@ -527,7 +530,6 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
527 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, 530 last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
528 buf, sizeof(buf)); 531 buf, sizeof(buf));
529 } 532 }
530 setproctitle("%s@%s", pw->pw_name, strrchr(s->tty, '/') + 1);
531 533
532#ifdef USE_PAM 534#ifdef USE_PAM
533 do_pam_session(pw->pw_name, s->tty); 535 do_pam_session(pw->pw_name, s->tty);
@@ -563,7 +565,7 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
563 /* Close the extra descriptor for the pseudo tty. */ 565 /* Close the extra descriptor for the pseudo tty. */
564 close(ttyfd); 566 close(ttyfd);
565 567
566///XXXX ? move to do_child() ?? 568/* XXXX ? move to do_child() ??*/
567 /* 569 /*
568 * Get IP address of client. This is needed because we want 570 * Get IP address of client. This is needed because we want
569 * to record where the user logged in from. If the 571 * to record where the user logged in from. If the
@@ -1257,6 +1259,8 @@ session_pty_req(Session *s)
1257 /* Get window size from the packet. */ 1259 /* Get window size from the packet. */
1258 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 1260 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1259 1261
1262 session_proctitle(s);
1263
1260 /* XXX parse and set terminal modes */ 1264 /* XXX parse and set terminal modes */
1261 xfree(term_modes); 1265 xfree(term_modes);
1262 return 1; 1266 return 1;
@@ -1499,6 +1503,7 @@ session_close(Session *s)
1499{ 1503{
1500 session_pty_cleanup(s); 1504 session_pty_cleanup(s);
1501 session_free(s); 1505 session_free(s);
1506 session_proctitle(s);
1502} 1507}
1503 1508
1504void 1509void
@@ -1542,6 +1547,34 @@ session_close_by_channel(int id, void *arg)
1542 } 1547 }
1543} 1548}
1544 1549
1550char *
1551session_tty_list(void)
1552{
1553 static char buf[1024];
1554 int i;
1555 buf[0] = '\0';
1556 for(i = 0; i < MAX_SESSIONS; i++) {
1557 Session *s = &sessions[i];
1558 if (s->used && s->ttyfd != -1) {
1559 if (buf[0] != '\0')
1560 strlcat(buf, ",", sizeof buf);
1561 strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
1562 }
1563 }
1564 if (buf[0] == '\0')
1565 strlcpy(buf, "notty", sizeof buf);
1566 return buf;
1567}
1568
1569void
1570session_proctitle(Session *s)
1571{
1572 if (s->pw == NULL)
1573 error("no user for session %d", s->self);
1574 else
1575 setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
1576}
1577
1545void 1578void
1546do_authenticated2(void) 1579do_authenticated2(void)
1547{ 1580{
diff --git a/ssh-add.1 b/ssh-add.1
index 88d0f7bf8..5d2f2497a 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -9,21 +9,21 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 23:55:14 1995 ylo 10.\" Created: Sat Apr 22 23:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh-add.1,v 1.12 2000/04/20 13:27:27 damien Exp $ 12.\" $Id: ssh-add.1,v 1.13 2000/05/07 02:03:18 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH-ADD 1 15.Dt SSH-ADD 1
16.Os 16.Os
17.Sh NAME 17.Sh NAME
18.Nm ssh-add 18.Nm ssh-add
19.Nd adds identities for the authentication agent 19.Nd adds RSA identities for the authentication agent
20.Sh SYNOPSIS 20.Sh SYNOPSIS
21.Nm ssh-add 21.Nm ssh-add
22.Op Fl lLdD 22.Op Fl lLdD
23.Op Ar 23.Op Ar
24.Sh DESCRIPTION 24.Sh DESCRIPTION
25.Nm 25.Nm
26adds identities to the authentication agent, 26adds RSA identities to the authentication agent,
27.Xr ssh-agent 1 . 27.Xr ssh-agent 1 .
28When run without arguments, it adds the file 28When run without arguments, it adds the file
29.Pa $HOME/.ssh/identity . 29.Pa $HOME/.ssh/identity .
diff --git a/ssh-agent.1 b/ssh-agent.1
index 68e6b84e1..66a475692 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-agent.1,v 1.11 2000/04/12 21:47:50 aaron Exp $ 1.\" $OpenBSD: ssh-agent.1,v 1.12 2000/05/03 18:04:39 markus Exp $
2.\" 2.\"
3.\" -*- nroff -*- 3.\" -*- nroff -*-
4.\" 4.\"
@@ -27,7 +27,7 @@
27.Oc 27.Oc
28.Sh DESCRIPTION 28.Sh DESCRIPTION
29.Nm 29.Nm
30is a program to hold authentication private keys. 30is a program to hold private keys used for RSA authentication.
31The idea is that 31The idea is that
32.Nm 32.Nm
33is started in the beginning of an X-session or a login session, and 33is started in the beginning of an X-session or a login session, and
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 486de0421..50e74e110 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 23:55:14 1995 ylo 10.\" Created: Sat Apr 22 23:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh-keygen.1,v 1.13 2000/04/29 13:57:12 damien Exp $ 12.\" $Id: ssh-keygen.1,v 1.14 2000/05/07 02:03:18 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH-KEYGEN 1 15.Dt SSH-KEYGEN 1
@@ -19,7 +19,7 @@
19.Nd authentication key generation 19.Nd authentication key generation
20.Sh SYNOPSIS 20.Sh SYNOPSIS
21.Nm ssh-keygen 21.Nm ssh-keygen
22.Op Fl q 22.Op Fl dq
23.Op Fl b Ar bits 23.Op Fl b Ar bits
24.Op Fl N Ar new_passphrase 24.Op Fl N Ar new_passphrase
25.Op Fl C Ar comment 25.Op Fl C Ar comment
@@ -30,6 +30,15 @@
30.Op Fl N Ar new_passphrase 30.Op Fl N Ar new_passphrase
31.Op Fl f Ar keyfile 31.Op Fl f Ar keyfile
32.Nm ssh-keygen 32.Nm ssh-keygen
33.Fl x
34.Op Fl f Ar keyfile
35.Nm ssh-keygen
36.Fl X
37.Op Fl f Ar keyfile
38.Nm ssh-keygen
39.Fl y
40.Op Fl f Ar keyfile
41.Nm ssh-keygen
33.Fl c 42.Fl c
34.Op Fl P Ar passphrase 43.Op Fl P Ar passphrase
35.Op Fl C Ar comment 44.Op Fl C Ar comment
@@ -43,11 +52,21 @@
43.Nm 52.Nm
44generates and manages authentication keys for 53generates and manages authentication keys for
45.Xr ssh 1 . 54.Xr ssh 1 .
55.Nm
56defaults to generating an RSA key for use by protocols 1.3 and 1.5;
57specifying the
58.Fl d
59flag will create a DSA key instead for use by protocol 2.0.
60.Pp
46Normally each user wishing to use SSH 61Normally each user wishing to use SSH
47with RSA authentication runs this once to create the authentication 62with RSA or DSA authentication runs this once to create the authentication
48key in 63key in
49.Pa $HOME/.ssh/identity . 64.Pa $HOME/.ssh/identity
50Additionally, the system administrator may use this to generate host keys. 65or
66.Pa $HOME/.ssh/id_dsa .
67Additionally, the system administrator may use this to generate host keys,
68as seen in
69.Pa /etc/rc .
51.Pp 70.Pp
52Normally this program generates the key and asks for a file in which 71Normally this program generates the key and asks for a file in which
53to store the private key. 72to store the private key.
@@ -71,7 +90,7 @@ If the passphrase is
71lost or forgotten, you will have to generate a new key and copy the 90lost or forgotten, you will have to generate a new key and copy the
72corresponding public key to other machines. 91corresponding public key to other machines.
73.Pp 92.Pp
74There is also a comment field in the key file that is only for 93For RSA, there is also a comment field in the key file that is only for
75convenience to the user to help identify the key. 94convenience to the user to help identify the key.
76The comment can tell what the key is for, or whatever is useful. 95The comment can tell what the key is for, or whatever is useful.
77The comment is initialized to 96The comment is initialized to
@@ -80,6 +99,9 @@ when the key is created, but can be changed using the
80.Fl c 99.Fl c
81option. 100option.
82.Pp 101.Pp
102After a key is generated, instructions below detail where the keys
103should be placed to be activated.
104.Pp
83The options are as follows: 105The options are as follows:
84.Bl -tag -width Ds 106.Bl -tag -width Ds
85.It Fl b Ar bits 107.It Fl b Ar bits
@@ -118,6 +140,15 @@ Provides the (old) passphrase.
118If RSA support is functional, immediately exits with code 0. If RSA 140If RSA support is functional, immediately exits with code 0. If RSA
119support is not functional, exits with code 1. This flag will be 141support is not functional, exits with code 1. This flag will be
120removed once the RSA patent expires. 142removed once the RSA patent expires.
143.It Fl x
144This option will read a private
145OpenSSH DSA format file and prints to stdout a SSH2-compatible public key.
146.It Fl X
147This option will read a
148SSH2-compatible public key file and print to stdout an OpenSSH DSA compatible public key.
149.It Fl y
150This option will read a private
151OpenSSH DSA format file and prints to stdout an OpenSSH DSA public key.
121.El 152.El
122.Sh FILES 153.Sh FILES
123.Bl -tag -width Ds 154.Bl -tag -width Ds
@@ -130,6 +161,8 @@ used to encrypt the private part of this file using 3DES.
130This file is not automatically accessed by 161This file is not automatically accessed by
131.Nm 162.Nm
132but it is offered as the default file for the private key. 163but it is offered as the default file for the private key.
164.Xr sshd 8
165will read this file when a login attempt is made.
133.It Pa $HOME/.ssh/identity.pub 166.It Pa $HOME/.ssh/identity.pub
134Contains the public key for authentication. 167Contains the public key for authentication.
135The contents of this file should be added to 168The contents of this file should be added to
@@ -137,6 +170,24 @@ The contents of this file should be added to
137on all machines 170on all machines
138where you wish to log in using RSA authentication. 171where you wish to log in using RSA authentication.
139There is no need to keep the contents of this file secret. 172There is no need to keep the contents of this file secret.
173.It Pa $HOME/.ssh/id_dsa
174Contains the DSA authentication identity of the user.
175This file should not be readable by anyone but the user.
176It is possible to
177specify a passphrase when generating the key; that passphrase will be
178used to encrypt the private part of this file using 3DES.
179This file is not automatically accessed by
180.Nm
181but it is offered as the default file for the private key.
182.Xr sshd 8
183will read this file when a login attempt is made.
184.It Pa $HOME/.ssh/id_dsa.pub
185Contains the public key for authentication.
186The contents of this file should be added to
187.Pa $HOME/.ssh/authorized_keys2
188on all machines
189where you wish to log in using DSA authentication.
190There is no need to keep the contents of this file secret.
140.Sh AUTHOR 191.Sh AUTHOR
141Tatu Ylonen <ylo@cs.hut.fi> 192Tatu Ylonen <ylo@cs.hut.fi>
142.Pp 193.Pp
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 2154e1ebf..a2599dab9 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -7,7 +7,7 @@
7 */ 7 */
8 8
9#include "includes.h" 9#include "includes.h"
10RCSID("$Id: ssh-keygen.c,v 1.16 2000/05/01 11:10:34 damien Exp $"); 10RCSID("$Id: ssh-keygen.c,v 1.17 2000/05/07 02:03:19 damien Exp $");
11 11
12#include <openssl/evp.h> 12#include <openssl/evp.h>
13#include <openssl/pem.h> 13#include <openssl/pem.h>
@@ -76,7 +76,8 @@ ask_filename(struct passwd *pw, const char *prompt)
76{ 76{
77 char buf[1024]; 77 char buf[1024];
78 snprintf(identity_file, sizeof(identity_file), "%s/%s", 78 snprintf(identity_file, sizeof(identity_file), "%s/%s",
79 pw->pw_dir, SSH_CLIENT_IDENTITY); 79 pw->pw_dir,
80 dsa_mode ? SSH_CLIENT_ID_DSA: SSH_CLIENT_IDENTITY);
80 printf("%s (%s): ", prompt, identity_file); 81 printf("%s (%s): ", prompt, identity_file);
81 fflush(stdout); 82 fflush(stdout);
82 if (fgets(buf, sizeof(buf), stdin) == NULL) 83 if (fgets(buf, sizeof(buf), stdin) == NULL)
@@ -491,8 +492,7 @@ do_change_comment(struct passwd *pw)
491void 492void
492usage(void) 493usage(void)
493{ 494{
494 printf("ssh-keygen version %s\n", SSH_VERSION); 495 printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname);
495 printf("Usage: %s [-b bits] [-c] [-d] [-f file] [-l] [-p] [-q] [-x] [-y] [-C comment] [-N new-pass] [-P pass] [-X]\n", __progname);
496 exit(1); 496 exit(1);
497} 497}
498 498
diff --git a/ssh.1 b/ssh.1
index c916927dc..a4738e63f 100644
--- a/ssh.1
+++ b/ssh.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 21:55:14 1995 ylo 10.\" Created: Sat Apr 22 21:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: ssh.1,v 1.23 2000/04/20 13:27:27 damien Exp $ 12.\" $Id: ssh.1,v 1.24 2000/05/07 02:03:19 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH 1 15.Dt SSH 1
@@ -63,7 +63,10 @@ arbitrary TCP/IP ports can also be forwarded over the secure channel.
63connects and logs into the specified 63connects and logs into the specified
64.Ar hostname . 64.Ar hostname .
65The user must prove 65The user must prove
66his/her identity to the remote machine using one of several methods. 66his/her identity to the remote machine using one of several methods
67depending on the protocol version used:
68.Pp
69.Ss SSH protocol version 1
67.Pp 70.Pp
68First, if the machine the user logs in from is listed in 71First, if the machine the user logs in from is listed in
69.Pa /etc/hosts.equiv 72.Pa /etc/hosts.equiv
@@ -88,8 +91,8 @@ or
88.Pa hosts.equiv 91.Pa hosts.equiv
89method combined with RSA-based host authentication. 92method combined with RSA-based host authentication.
90It means that if the login would be permitted by 93It means that if the login would be permitted by
91.Pa \&.rhosts , 94.Pa $HOME/.rhosts ,
92.Pa \&.shosts , 95.Pa $HOME/.shosts ,
93.Pa /etc/hosts.equiv , 96.Pa /etc/hosts.equiv ,
94or 97or
95.Pa /etc/shosts.equiv , 98.Pa /etc/shosts.equiv ,
@@ -105,7 +108,7 @@ This authentication method closes security holes due to IP
105spoofing, DNS spoofing and routing spoofing. 108spoofing, DNS spoofing and routing spoofing.
106[Note to the administrator: 109[Note to the administrator:
107.Pa /etc/hosts.equiv , 110.Pa /etc/hosts.equiv ,
108.Pa \&.rhosts , 111.Pa $HOME/.rhosts ,
109and the rlogin/rsh protocol in general, are inherently insecure and should be 112and the rlogin/rsh protocol in general, are inherently insecure and should be
110disabled if security is desired.] 113disabled if security is desired.]
111.Pp 114.Pp
@@ -143,18 +146,18 @@ implements the RSA authentication protocol automatically.
143The user creates his/her RSA key pair by running 146The user creates his/her RSA key pair by running
144.Xr ssh-keygen 1 . 147.Xr ssh-keygen 1 .
145This stores the private key in 148This stores the private key in
146.Pa \&.ssh/identity 149.Pa $HOME/.ssh/identity
147and the public key in 150and the public key in
148.Pa \&.ssh/identity.pub 151.Pa $HOME/.ssh/identity.pub
149in the user's home directory. 152in the user's home directory.
150The user should then copy the 153The user should then copy the
151.Pa identity.pub 154.Pa identity.pub
152to 155to
153.Pa \&.ssh/authorized_keys 156.Pa $HOME/.ssh/authorized_keys
154in his/her home directory on the remote machine (the 157in his/her home directory on the remote machine (the
155.Pa authorized_keys 158.Pa authorized_keys
156file corresponds to the conventional 159file corresponds to the conventional
157.Pa \&.rhosts 160.Pa $HOME/.rhosts
158file, and has one key 161file, and has one key
159per line, though the lines can be very long). 162per line, though the lines can be very long).
160After this, the user can log in without giving the password. 163After this, the user can log in without giving the password.
@@ -174,6 +177,38 @@ The password is sent to the remote
174host for checking; however, since all communications are encrypted, 177host for checking; however, since all communications are encrypted,
175the password cannot be seen by someone listening on the network. 178the password cannot be seen by someone listening on the network.
176.Pp 179.Pp
180.Ss SSH protocol version 2
181.Pp
182When a user connects using the protocol version 2
183different authentication methods are available:
184At first, the client attempts to authenticate using the public key method.
185If this method fails password authentication is tried.
186.Pp
187The public key method is similar to RSA authentication described
188in the previous section except that the DSA algorithm is used
189instead of the patented RSA algorithm.
190The client uses his private DSA key
191.Pa $HOME/.ssh/id_dsa
192to sign the session identifier and sends the result to the server.
193The server checks whether the matching public key is listed in
194.Pa $HOME/.ssh/authorized_keys2
195and grants access if both the key is found and the signature is correct.
196The session identifier is derived from a shared Diffie-Hellman value
197and is only known to the client and the server.
198.Pp
199If public key authentication fails or is not available a password
200can be sent encrypted to the remote host for proving the user's identity.
201This protocol 2 implementation does not yet support Kerberos or
202S/Key authentication.
203.Pp
204Protocol 2 provides additional mechanisms for confidentiality
205(the traffic is encrypted using 3DES, blowfish, cast128 or arcfour)
206and integrity (hmac-sha1, hmac-md5).
207Note that protocol 1 lacks a strong mechanism for ensuring the
208integrity of the connection.
209.Pp
210.Ss Login session and remote execution
211.Pp
177When the user's identity has been accepted by the server, the server 212When the user's identity has been accepted by the server, the server
178either executes the given command, or logs into the machine and gives 213either executes the given command, or logs into the machine and gives
179the user a normal shell on the remote machine. 214the user a normal shell on the remote machine.
@@ -219,6 +254,8 @@ The exit status of the remote program is returned as the exit status
219of 254of
220.Nm ssh . 255.Nm ssh .
221.Pp 256.Pp
257.Ss X11 and TCP forwarding
258.Pp
222If the user is using X11 (the 259If the user is using X11 (the
223.Ev DISPLAY 260.Ev DISPLAY
224environment variable is set), the connection to the X11 display is 261environment variable is set), the connection to the X11 display is
@@ -262,15 +299,22 @@ be specified either on command line or in a configuration file.
262One possible application of TCP/IP forwarding is a secure connection to an 299One possible application of TCP/IP forwarding is a secure connection to an
263electronic purse; another is going trough firewalls. 300electronic purse; another is going trough firewalls.
264.Pp 301.Pp
302.Ss Server authentication
303.Pp
265.Nm 304.Nm
266automatically maintains and checks a database containing RSA-based 305automatically maintains and checks a database containing
267identifications for all hosts it has ever been used with. 306identifications for all hosts it has ever been used with.
268The database is stored in 307RSA host keys are stored in
269.Pa \&.ssh/known_hosts 308.Pa $HOME/.ssh/known_hosts
309and
310DSA host keys are stored in
311.Pa $HOME/.ssh/known_hosts2
270in the user's home directory. 312in the user's home directory.
271Additionally, the file 313Additionally, the files
272.Pa /etc/ssh_known_hosts 314.Pa /etc/ssh_known_hosts
273is automatically checked for known hosts. 315and
316.Pa /etc/ssh_known_hosts2
317are automatically checked for known hosts.
274Any new hosts are automatically added to the user's file. 318Any new hosts are automatically added to the user's file.
275If a host's identification 319If a host's identification
276ever changes, 320ever changes,
@@ -333,7 +377,7 @@ Allows remote hosts to connect to local forwarded ports.
333Selects the file from which the identity (private key) for 377Selects the file from which the identity (private key) for
334RSA authentication is read. 378RSA authentication is read.
335Default is 379Default is
336.Pa \&.ssh/identity 380.Pa $HOME/.ssh/identity
337in the user's home directory. 381in the user's home directory.
338Identity files may also be specified on 382Identity files may also be specified on
339a per-host basis in the configuration file. 383a per-host basis in the configuration file.
@@ -458,7 +502,7 @@ logging in as root on the remote machine.
458.It Fl 2 502.It Fl 2
459Forces 503Forces
460.Nm 504.Nm
461to use protocol version 2 only. 505to try protocol version 2 only.
462.It Fl 4 506.It Fl 4
463Forces 507Forces
464.Nm 508.Nm
@@ -575,6 +619,15 @@ Specifies the number of tries (one per second) to make before falling
575back to rsh or exiting. 619back to rsh or exiting.
576The argument must be an integer. 620The argument must be an integer.
577This may be useful in scripts if the connection sometimes fails. 621This may be useful in scripts if the connection sometimes fails.
622.It Cm DSAAuthentication
623Specifies whether to try DSA authentication.
624The argument to this keyword must be
625.Dq yes
626or
627.Dq no .
628DSA authentication will only be
629attempted if a DSA identity file exists.
630Note that this option applies to protocol version 2 only.
578.It Cm EscapeChar 631.It Cm EscapeChar
579Sets the escape character (default: 632Sets the escape character (default:
580.Ql ~ ) . 633.Ql ~ ) .
@@ -640,7 +693,7 @@ specifications).
640.It Cm IdentityFile 693.It Cm IdentityFile
641Specifies the file from which the user's RSA authentication identity 694Specifies the file from which the user's RSA authentication identity
642is read (default 695is read (default
643.Pa .ssh/identity 696.Pa $HOME/.ssh/identity
644in the user's home directory). 697in the user's home directory).
645Additionally, any identities represented by the authentication agent 698Additionally, any identities represented by the authentication agent
646will be used for authentication. 699will be used for authentication.
@@ -649,6 +702,16 @@ syntax to refer to a user's home directory.
649It is possible to have 702It is possible to have
650multiple identity files specified in configuration files; all these 703multiple identity files specified in configuration files; all these
651identities will be tried in sequence. 704identities will be tried in sequence.
705.It Cm IdentityFile2
706Specifies the file from which the user's DSA authentication identity
707is read (default
708.Pa $HOME/.ssh/id_dsa
709in the user's home directory).
710The file name may use the tilde
711syntax to refer to a user's home directory.
712It is possible to have
713multiple identity files specified in configuration files; all these
714identities will be tried in sequence.
652.It Cm KeepAlive 715.It Cm KeepAlive
653Specifies whether the system should send keepalive messages to the 716Specifies whether the system should send keepalive messages to the
654other side. 717other side.
@@ -704,6 +767,7 @@ The argument to this keyword must be
704.Dq yes 767.Dq yes
705or 768or
706.Dq no . 769.Dq no .
770Note that this option applies to both protocol version 1 and 2.
707.It Cm Port 771.It Cm Port
708Specifies the port number to connect on the remote host. 772Specifies the port number to connect on the remote host.
709Default is 22. 773Default is 22.
@@ -717,7 +781,11 @@ and
717.Dq 2 . 781.Dq 2 .
718Multiple versions must be comma-separated. 782Multiple versions must be comma-separated.
719The default is 783The default is
720.Dq 1 . 784.Dq 1,2 .
785This means that
786.Nm
787tries version 1 and falls back to version 2
788if version 1 is no available.
721.It Cm ProxyCommand 789.It Cm ProxyCommand
722Specifies the command to use to connect to the server. 790Specifies the command to use to connect to the server.
723The command 791The command
@@ -782,6 +850,7 @@ or
782RSA authentication will only be 850RSA authentication will only be
783attempted if the identity file exists, or an authentication agent is 851attempted if the identity file exists, or an authentication agent is
784running. 852running.
853Note that this option applies to protocol version 1 only.
785.It Cm SkeyAuthentication 854.It Cm SkeyAuthentication
786Specifies whether to use 855Specifies whether to use
787.Xr skey 1 856.Xr skey 1
@@ -798,10 +867,14 @@ If this flag is set to
798.Nm 867.Nm
799ssh will never automatically add host keys to the 868ssh will never automatically add host keys to the
800.Pa $HOME/.ssh/known_hosts 869.Pa $HOME/.ssh/known_hosts
801file, and refuses to connect hosts whose host key has changed. 870and
871.Pa $HOME/.ssh/known_hosts2
872files, and refuses to connect hosts whose host key has changed.
802This provides maximum protection against trojan horse attacks. 873This provides maximum protection against trojan horse attacks.
803However, it can be somewhat annoying if you don't have good 874However, it can be somewhat annoying if you don't have good
804.Pa /etc/ssh_known_hosts 875.Pa /etc/ssh_known_hosts
876and
877.Pa /etc/ssh_known_hosts2
805files installed and frequently 878files installed and frequently
806connect new hosts. 879connect new hosts.
807Basically this option forces the user to manually 880Basically this option forces the user to manually
@@ -921,28 +994,36 @@ in
921.Pa /etc/ssh_known_hosts ) . 994.Pa /etc/ssh_known_hosts ) .
922See 995See
923.Xr sshd 8 . 996.Xr sshd 8 .
924.It Pa $HOME/.ssh/identity 997.It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa
925Contains the RSA authentication identity of the user. 998Contains the RSA and the DSA authentication identity of the user.
926This file 999These files
927contains sensitive data and should be readable by the user but not 1000contain sensitive data and should be readable by the user but not
928accessible by others (read/write/execute). 1001accessible by others (read/write/execute).
929Note that 1002Note that
930.Nm 1003.Nm
931ignores this file if it is accessible by others. 1004ignores a private key file if it is accessible by others.
932It is possible to specify a passphrase when 1005It is possible to specify a passphrase when
933generating the key; the passphrase will be used to encrypt the 1006generating the key; the passphrase will be used to encrypt the
934sensitive part of this file using 3DES. 1007sensitive part of this file using 3DES.
935.It Pa $HOME/.ssh/identity.pub 1008.It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub
936Contains the public key for authentication (public part of the 1009Contains the public key for authentication (public part of the
937identity file in human-readable form). 1010identity file in human-readable form).
938The contents of this file should be added to 1011The contents of the
1012.Pa $HOME/.ssh/identity.pub
1013file should be added to
939.Pa $HOME/.ssh/authorized_keys 1014.Pa $HOME/.ssh/authorized_keys
940on all machines 1015on all machines
941where you wish to log in using RSA authentication. 1016where you wish to log in using RSA authentication.
942This file is not 1017The contents of the
1018.Pa $HOME/.ssh/id_dsa.pub
1019file should be added to
1020.Pa $HOME/.ssh/authorized_keys2
1021on all machines
1022where you wish to log in using DSA authentication.
1023These files are not
943sensitive and can (but need not) be readable by anyone. 1024sensitive and can (but need not) be readable by anyone.
944This file is 1025These files are
945never used automatically and is not necessary; it is only provided for 1026never used automatically and are not necessary; they is only provided for
946the convenience of the user. 1027the convenience of the user.
947.It Pa $HOME/.ssh/config 1028.It Pa $HOME/.ssh/config
948This is the per-user configuration file. 1029This is the per-user configuration file.
@@ -964,9 +1045,17 @@ modulus, public exponent, modulus, and comment fields, separated by
964spaces). 1045spaces).
965This file is not highly sensitive, but the recommended 1046This file is not highly sensitive, but the recommended
966permissions are read/write for the user, and not accessible by others. 1047permissions are read/write for the user, and not accessible by others.
967.It Pa /etc/ssh_known_hosts 1048.It Pa $HOME/.ssh/authorized_keys2
1049Lists the DSA keys that can be used for logging in as this user.
1050This file is not highly sensitive, but the recommended
1051permissions are read/write for the user, and not accessible by others.
1052.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2
968Systemwide list of known host keys. 1053Systemwide list of known host keys.
969This file should be prepared by the 1054.Pa /etc/ssh_known_hosts
1055contains RSA and
1056.Pa /etc/ssh_known_hosts2
1057contains DSA keys.
1058These files should be prepared by the
970system administrator to contain the public host keys of all machines in the 1059system administrator to contain the public host keys of all machines in the
971organization. 1060organization.
972This file should be world-readable. 1061This file should be world-readable.
@@ -1025,7 +1114,7 @@ you can store it in
1025.Pa $HOME/.ssh/known_hosts . 1114.Pa $HOME/.ssh/known_hosts .
1026The easiest way to do this is to 1115The easiest way to do this is to
1027connect back to the client from the server machine using ssh; this 1116connect back to the client from the server machine using ssh; this
1028will automatically add the host key inxi 1117will automatically add the host key to
1029.Pa $HOME/.ssh/known_hosts . 1118.Pa $HOME/.ssh/known_hosts .
1030.It Pa $HOME/.shosts 1119.It Pa $HOME/.shosts
1031This file is used exactly the same way as 1120This file is used exactly the same way as
@@ -1086,6 +1175,7 @@ but with bugs removed and newer features re-added.
1086Rapidly after the 1175Rapidly after the
10871.2.12 release, newer versions of the original ssh bore successively 11761.2.12 release, newer versions of the original ssh bore successively
1088more restrictive licenses, and thus demand for a free version was born. 1177more restrictive licenses, and thus demand for a free version was born.
1178.Pp
1089This version of OpenSSH 1179This version of OpenSSH
1090.Bl -bullet 1180.Bl -bullet
1091.It 1181.It
@@ -1094,8 +1184,8 @@ directly removed from the source code; any licensed or patented components
1094are chosen from 1184are chosen from
1095external libraries. 1185external libraries.
1096.It 1186.It
1097has been updated to support ssh protocol 1.5, making it compatible with 1187has been updated to support SSH protocol 1.5 and 2, making it compatible with
1098all other ssh protocol 1 clients and servers. 1188all other SSH clients and servers.
1099.It 1189.It
1100contains added support for 1190contains added support for
1101.Xr kerberos 8 1191.Xr kerberos 8
@@ -1107,6 +1197,8 @@ supports one-time password authentication with
1107.Pp 1197.Pp
1108OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl, 1198OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl,
1109Niels Provos, Theo de Raadt, and Dug Song. 1199Niels Provos, Theo de Raadt, and Dug Song.
1200.Pp
1201The support for SSH protocol 2 was written by Markus Friedl.
1110.Sh SEE ALSO 1202.Sh SEE ALSO
1111.Xr rlogin 1 , 1203.Xr rlogin 1 ,
1112.Xr rsh 1 , 1204.Xr rsh 1 ,
diff --git a/ssh.h b/ssh.h
index b45350d12..649c89de2 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: ssh.h,v 1.37 2000/05/01 23:56:42 damien Exp $"); */ 16/* RCSID("$Id: ssh.h,v 1.38 2000/05/07 02:03:19 damien Exp $"); */
17 17
18#ifndef SSH_H 18#ifndef SSH_H
19#define SSH_H 19#define SSH_H
@@ -97,7 +97,7 @@
97#define HOST_KEY_FILE ETCDIR "/ssh_host_key" 97#define HOST_KEY_FILE ETCDIR "/ssh_host_key"
98#define SERVER_CONFIG_FILE ETCDIR "/sshd_config" 98#define SERVER_CONFIG_FILE ETCDIR "/sshd_config"
99#define HOST_CONFIG_FILE ETCDIR "/ssh_config" 99#define HOST_CONFIG_FILE ETCDIR "/ssh_config"
100#define DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key" 100#define HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key"
101 101
102#ifndef SSH_PROGRAM 102#ifndef SSH_PROGRAM
103#define SSH_PROGRAM "/usr/bin/ssh" 103#define SSH_PROGRAM "/usr/bin/ssh"
@@ -146,6 +146,7 @@
146 * file should only be readable by the user him/herself. 146 * file should only be readable by the user him/herself.
147 */ 147 */
148#define SSH_CLIENT_IDENTITY ".ssh/identity" 148#define SSH_CLIENT_IDENTITY ".ssh/identity"
149#define SSH_CLIENT_ID_DSA ".ssh/id_dsa"
149 150
150/* 151/*
151 * Configuration file in user\'s home directory. This file need not be 152 * Configuration file in user\'s home directory. This file need not be
@@ -527,7 +528,7 @@ int auth_krb4_password(struct passwd * pw, const char *password);
527int auth_kerberos_tgt(struct passwd * pw, const char *string); 528int auth_kerberos_tgt(struct passwd * pw, const char *string);
528int auth_afs_token(struct passwd * pw, const char *token_string); 529int auth_afs_token(struct passwd * pw, const char *token_string);
529 530
530int creds_to_radix(CREDENTIALS * creds, unsigned char *buf); 531int creds_to_radix(CREDENTIALS * creds, unsigned char *buf, size_t buflen);
531int radix_to_creds(const char *buf, CREDENTIALS * creds); 532int radix_to_creds(const char *buf, CREDENTIALS * creds);
532#endif /* AFS */ 533#endif /* AFS */
533 534
diff --git a/sshconnect.c b/sshconnect.c
index 859450d36..9b25d7c20 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$OpenBSD: sshconnect.c,v 1.71 2000/04/26 21:28:33 markus Exp $"); 11RCSID("$OpenBSD: sshconnect.c,v 1.72 2000/05/04 09:50:22 markus Exp $");
12 12
13#include <openssl/bn.h> 13#include <openssl/bn.h>
14#include <openssl/dsa.h> 14#include <openssl/dsa.h>
@@ -465,6 +465,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
465 const char *user_hostfile, const char *system_hostfile) 465 const char *user_hostfile, const char *system_hostfile)
466{ 466{
467 Key *file_key; 467 Key *file_key;
468 char *type = key_type(host_key);
468 char *ip = NULL; 469 char *ip = NULL;
469 char hostline[1000], *hostp; 470 char hostline[1000], *hostp;
470 HostStatus host_status; 471 HostStatus host_status;
@@ -551,18 +552,19 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
551 switch (host_status) { 552 switch (host_status) {
552 case HOST_OK: 553 case HOST_OK:
553 /* The host is known and the key matches. */ 554 /* The host is known and the key matches. */
554 debug("Host '%.200s' is known and matches the host key.", host); 555 debug("Host '%.200s' is known and matches the %s host key.",
556 host, type);
555 if (options.check_host_ip) { 557 if (options.check_host_ip) {
556 if (ip_status == HOST_NEW) { 558 if (ip_status == HOST_NEW) {
557 if (!add_host_to_hostfile(user_hostfile, ip, host_key)) 559 if (!add_host_to_hostfile(user_hostfile, ip, host_key))
558 log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", 560 log("Failed to add the %s host key for IP address '%.30s' to the list of known hosts (%.30s).",
559 ip, user_hostfile); 561 type, ip, user_hostfile);
560 else 562 else
561 log("Warning: Permanently added host key for IP address '%.30s' to the list of known hosts.", 563 log("Warning: Permanently added the %s host key for IP address '%.30s' to the list of known hosts.",
562 ip); 564 type, ip);
563 } else if (ip_status != HOST_OK) 565 } else if (ip_status != HOST_OK)
564 log("Warning: the host key for '%.200s' differs from the key for the IP address '%.30s'", 566 log("Warning: the %s host key for '%.200s' differs from the key for the IP address '%.30s'",
565 host, ip); 567 type, host, ip);
566 } 568 }
567 break; 569 break;
568 case HOST_NEW: 570 case HOST_NEW:
@@ -570,16 +572,16 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
570 if (options.strict_host_key_checking == 1) { 572 if (options.strict_host_key_checking == 1) {
571 /* User has requested strict host key checking. We will not add the host key 573 /* User has requested strict host key checking. We will not add the host key
572 automatically. The only alternative left is to abort. */ 574 automatically. The only alternative left is to abort. */
573 fatal("No host key is known for %.200s and you have requested strict checking.", host); 575 fatal("No %s host key is known for %.200s and you have requested strict checking.", type, host);
574 } else if (options.strict_host_key_checking == 2) { 576 } else if (options.strict_host_key_checking == 2) {
575 /* The default */ 577 /* The default */
576 char prompt[1024]; 578 char prompt[1024];
577 char *fp = key_fingerprint(host_key); 579 char *fp = key_fingerprint(host_key);
578 snprintf(prompt, sizeof(prompt), 580 snprintf(prompt, sizeof(prompt),
579 "The authenticity of host '%.200s' can't be established.\n" 581 "The authenticity of host '%.200s' can't be established.\n"
580 "Key fingerprint is %s.\n" 582 "%s key fingerprint is %s.\n"
581 "Are you sure you want to continue connecting (yes/no)? ", 583 "Are you sure you want to continue connecting (yes/no)? ",
582 host, fp); 584 host, type, fp);
583 if (!read_yes_or_no(prompt, -1)) 585 if (!read_yes_or_no(prompt, -1))
584 fatal("Aborted by user!\n"); 586 fatal("Aborted by user!\n");
585 } 587 }
@@ -594,8 +596,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
594 log("Failed to add the host to the list of known hosts (%.500s).", 596 log("Failed to add the host to the list of known hosts (%.500s).",
595 user_hostfile); 597 user_hostfile);
596 else 598 else
597 log("Warning: Permanently added '%.200s' to the list of known hosts.", 599 log("Warning: Permanently added '%.200s' (%s) to the list of known hosts.",
598 hostp); 600 hostp, type);
599 break; 601 break;
600 case HOST_CHANGED: 602 case HOST_CHANGED:
601 if (options.check_host_ip && host_ip_differ) { 603 if (options.check_host_ip && host_ip_differ) {
@@ -609,7 +611,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
609 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 611 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
610 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); 612 error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @");
611 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 613 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
612 error("The host key for %s has changed,", host); 614 error("The %s host key for %s has changed,", type, host);
613 error("and the key for the according IP address %s", ip); 615 error("and the key for the according IP address %s", ip);
614 error("%s. This could either mean that", msg); 616 error("%s. This could either mean that", msg);
615 error("DNS SPOOFING is happening or the IP address for the host"); 617 error("DNS SPOOFING is happening or the IP address for the host");
@@ -621,7 +623,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
621 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 623 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
622 error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); 624 error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
623 error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); 625 error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
624 error("It is also possible that the host key has just been changed."); 626 error("It is also possible that the %s host key has just been changed.", type);
625 error("Please contact your system administrator."); 627 error("Please contact your system administrator.");
626 error("Add correct host key in %.100s to get rid of this message.", 628 error("Add correct host key in %.100s to get rid of this message.",
627 user_hostfile); 629 user_hostfile);
@@ -631,7 +633,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
631 * to edit the key manually and we can only abort. 633 * to edit the key manually and we can only abort.
632 */ 634 */
633 if (options.strict_host_key_checking) 635 if (options.strict_host_key_checking)
634 fatal("Host key for %.200s has changed and you have requested strict checking.", host); 636 fatal("%s host key for %.200s has changed and you have requested strict checking.", type, host);
635 637
636 /* 638 /*
637 * If strict host key checking has not been requested, allow 639 * If strict host key checking has not been requested, allow
diff --git a/sshconnect1.c b/sshconnect1.c
index c5a76654b..31ee9843c 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -9,7 +9,7 @@
9 */ 9 */
10 10
11#include "includes.h" 11#include "includes.h"
12RCSID("$OpenBSD: sshconnect1.c,v 1.1 2000/04/26 21:28:33 markus Exp $"); 12RCSID("$OpenBSD: sshconnect1.c,v 1.2 2000/05/04 22:38:00 markus Exp $");
13 13
14#include <openssl/bn.h> 14#include <openssl/bn.h>
15#include <openssl/dsa.h> 15#include <openssl/dsa.h>
@@ -505,7 +505,7 @@ send_kerberos_tgt()
505 debug("Kerberos V4 ticket expired: %s", TKT_FILE); 505 debug("Kerberos V4 ticket expired: %s", TKT_FILE);
506 return 0; 506 return 0;
507 } 507 }
508 creds_to_radix(creds, (unsigned char *)buffer); 508 creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer);
509 xfree(creds); 509 xfree(creds);
510 510
511 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); 511 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
@@ -573,7 +573,7 @@ send_afs_tokens(void)
573 creds.pinst[0] = '\0'; 573 creds.pinst[0] = '\0';
574 574
575 /* Encode token, ship it off. */ 575 /* Encode token, ship it off. */
576 if (!creds_to_radix(&creds, (unsigned char*) buffer)) 576 if (creds_to_radix(&creds, (unsigned char*) buffer, sizeof buffer) <= 0)
577 break; 577 break;
578 packet_start(SSH_CMSG_HAVE_AFS_TOKEN); 578 packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
579 packet_put_string(buffer, strlen(buffer)); 579 packet_put_string(buffer, strlen(buffer));
diff --git a/sshconnect2.c b/sshconnect2.c
index a4342e2df..17325b097 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$OpenBSD: sshconnect2.c,v 1.5 2000/05/01 18:41:06 markus Exp $"); 31RCSID("$OpenBSD: sshconnect2.c,v 1.7 2000/05/06 17:45:37 markus Exp $");
32 32
33#include <openssl/bn.h> 33#include <openssl/bn.h>
34#include <openssl/rsa.h> 34#include <openssl/rsa.h>
@@ -283,9 +283,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
283int 283int
284ssh2_try_passwd(const char *server_user, const char *host, const char *service) 284ssh2_try_passwd(const char *server_user, const char *host, const char *service)
285{ 285{
286 static int attempt = 0;
286 char prompt[80]; 287 char prompt[80];
287 char *password; 288 char *password;
288 289
290 if (attempt++ > options.number_of_password_prompts)
291 return 0;
292
289 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", 293 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
290 server_user, host); 294 server_user, host);
291 password = read_passphrase(prompt, 0); 295 password = read_passphrase(prompt, 0);
@@ -428,7 +432,7 @@ ssh_userauth2(const char *server_user, char *host)
428 packet_done(); 432 packet_done();
429 if (partial) 433 if (partial)
430 debug("partial success"); 434 debug("partial success");
431 if (options.rsa_authentication && 435 if (options.dsa_authentication &&
432 strstr(auths, "publickey") != NULL) { 436 strstr(auths, "publickey") != NULL) {
433 while (i < options.num_identity_files2) { 437 while (i < options.num_identity_files2) {
434 sent = ssh2_try_pubkey( 438 sent = ssh2_try_pubkey(
diff --git a/sshd.8 b/sshd.8
index 85da7c4a1..78f4ea10f 100644
--- a/sshd.8
+++ b/sshd.8
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sat Apr 22 21:55:14 1995 ylo 10.\" Created: Sat Apr 22 21:55:14 1995 ylo
11.\" 11.\"
12.\" $Id: sshd.8,v 1.20 2000/05/01 23:23:46 damien Exp $ 12.\" $Id: sshd.8,v 1.21 2000/05/07 02:03:20 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSHD 8 15.Dt SSHD 8
@@ -46,9 +46,14 @@ daemon for each incoming connection.
46The forked daemons handle 46The forked daemons handle
47key exchange, encryption, authentication, command execution, 47key exchange, encryption, authentication, command execution,
48and data exchange. 48and data exchange.
49.Pp 49This implementation of
50.Nm
51supports both SSH protocol version 1 and 2 simultaneously.
50.Nm 52.Nm
51works as follows. 53works as follows.
54.Pp
55.Ss SSH protocol version 1
56.Pp
52Each host has a host-specific RSA key 57Each host has a host-specific RSA key
53(normally 1024 bits) used to identify the host. 58(normally 1024 bits) used to identify the host.
54Additionally, when 59Additionally, when
@@ -59,7 +64,7 @@ is never stored on disk.
59Whenever a client connects the daemon responds with its public 64Whenever a client connects the daemon responds with its public
60host and server keys. 65host and server keys.
61The client compares the 66The client compares the
62host key against its own database to verify that it has not changed. 67RSA host key against its own database to verify that it has not changed.
63The client then generates a 256 bit random number. 68The client then generates a 256 bit random number.
64It encrypts this 69It encrypts this
65random number using both the host key and the server key, and sends 70random number using both the host key and the server key, and sends
@@ -97,6 +102,28 @@ and
97.Xr rsh 1 102.Xr rsh 1
98into the machine). 103into the machine).
99.Pp 104.Pp
105.Ss SSH protocol version 2
106.Pp
107Version 2 works similar:
108Each host has a host-specific DSA key used to identify the host.
109However, when the daemon starts, it does not generate a server key.
110Forward security is provided through a Diffie-Hellman key agreement.
111This key agreement results in a shared session key.
112The rest of the session is encrypted
113using a symmetric cipher, currently
114Blowfish, 3DES or CAST128 in CBC mode or Arcfour.
115The client selects the encryption algorithm
116to use from those offered by the server.
117Additionally, session integrity is provided
118through a crytographic message authentication code
119(hmac-sha1 or hmac-md5).
120.Pp
121Protocol version 2 provides a public key based
122user authentication method (DSAAuthentication)
123and conventional password authentication.
124.Pp
125.Ss Command execution and data forwarding
126.Pp
100If the client successfully authenticates itself, a dialog for 127If the client successfully authenticates itself, a dialog for
101preparing the session is entered. 128preparing the session is entered.
102At this time the client may request 129At this time the client may request
@@ -148,7 +175,7 @@ If the client fails to authenticate the user within
148this many seconds, the server disconnects and exits. 175this many seconds, the server disconnects and exits.
149A value of zero indicates no limit. 176A value of zero indicates no limit.
150.It Fl h Ar host_key_file 177.It Fl h Ar host_key_file
151Specifies the file from which the host key is read (default 178Specifies the file from which the RSA host key is read (default
152.Pa /etc/ssh_host_key ) . 179.Pa /etc/ssh_host_key ) .
153This option must be given if 180This option must be given if
154.Nm 181.Nm
@@ -280,12 +307,34 @@ and
280can be used as wildcards in the patterns. 307can be used as wildcards in the patterns.
281Only user names are valid, a numerical user ID isn't recognized. 308Only user names are valid, a numerical user ID isn't recognized.
282By default login is allowed regardless of the user name. 309By default login is allowed regardless of the user name.
310.It Cm DSAAuthentication
311Specifies whether DSA authentication is allowed.
312The default is
313.Dq yes .
314Note that this option applies to protocol version 2 only.
315.It Cm GatewayPorts
316Specifies whether remote hosts are allowed to connect to ports
317forwarded for the client.
318The argument must be
319.Dq yes
320or
321.Dq no .
322The default is
323.Dq no .
324.It Cm HostDsaKey
325Specifies the file containing the private DSA host key (default
326.Pa /etc/ssh_host_dsa_key )
327used by SSH protocol 2.0.
328Note that
329.Nm
330disables protcol 2.0 if this file is group/world-accessible.
283.It Cm HostKey 331.It Cm HostKey
284Specifies the file containing the private host key (default 332Specifies the file containing the private RSA host key (default
285.Pa /etc/ssh_host_key ) . 333.Pa /etc/ssh_host_key )
334used by SSH protocols 1.3 and 1.5.
286Note that 335Note that
287.Nm 336.Nm
288does not start if this file is group/world-accessible. 337disables protcols 1.3 and 1.5 if this file is group/world-accessible.
289.It Cm IgnoreRhosts 338.It Cm IgnoreRhosts
290Specifies that 339Specifies that
291.Pa .rhosts 340.Pa .rhosts
@@ -390,6 +439,7 @@ and is not recommended.
390Specifies whether password authentication is allowed. 439Specifies whether password authentication is allowed.
391The default is 440The default is
392.Dq yes . 441.Dq yes .
442Note that this option applies to both protocol version 1 and 2.
393.It Cm PermitEmptyPasswords 443.It Cm PermitEmptyPasswords
394When password authentication is allowed, it specifies whether the 444When password authentication is allowed, it specifies whether the
395server allows login to accounts with empty password strings. 445server allows login to accounts with empty password strings.
@@ -471,6 +521,7 @@ The default is
471Specifies whether pure RSA authentication is allowed. 521Specifies whether pure RSA authentication is allowed.
472The default is 522The default is
473.Dq yes . 523.Dq yes .
524Note that this option applies to protocol version 1 only.
474.It Cm ServerKeyBits 525.It Cm ServerKeyBits
475Defines the number of bits in the server key. 526Defines the number of bits in the server key.
476The minimum value is 512, and the default is 768. 527The minimum value is 512, and the default is 768.
@@ -568,7 +619,11 @@ Runs user's shell or command.
568The 619The
569.Pa $HOME/.ssh/authorized_keys 620.Pa $HOME/.ssh/authorized_keys
570file lists the RSA keys that are 621file lists the RSA keys that are
571permitted for RSA authentication. 622permitted for RSA authentication in SSH protocols 1.3 and 1.5
623Similarily, the
624.Pa $HOME/.ssh/authorized_keys2
625file lists the DSA keys that are
626permitted for DSA authentication in SSH protocol 2.0.
572Each line of the file contains one 627Each line of the file contains one
573key (empty lines and lines starting with a 628key (empty lines and lines starting with a
574.Ql # 629.Ql #
@@ -655,9 +710,11 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula
655command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi 710command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hut.fi
656.Sh SSH_KNOWN_HOSTS FILE FORMAT 711.Sh SSH_KNOWN_HOSTS FILE FORMAT
657The 712The
658.Pa /etc/ssh_known_hosts 713.Pa /etc/ssh_known_hosts ,
714.Pa /etc/ssh_known_hosts2 ,
715.Pa $HOME/.ssh/known_hosts ,
659and 716and
660.Pa $HOME/.ssh/known_hosts 717.Pa $HOME/.ssh/known_hosts2
661files contain host public keys for all known hosts. 718files contain host public keys for all known hosts.
662The global file should 719The global file should
663be prepared by the administrator (optional), and the per-user file is 720be prepared by the administrator (optional), and the per-user file is
@@ -678,7 +735,7 @@ to indicate negation: if the host name matches a negated
678pattern, it is not accepted (by that line) even if it matched another 735pattern, it is not accepted (by that line) even if it matched another
679pattern on the line. 736pattern on the line.
680.Pp 737.Pp
681Bits, exponent, and modulus are taken directly from the host key; they 738Bits, exponent, and modulus are taken directly from the RSA host key; they
682can be obtained, e.g., from 739can be obtained, e.g., from
683.Pa /etc/ssh_host_key.pub . 740.Pa /etc/ssh_host_key.pub .
684The optional comment field continues to the end of the line, and is not used. 741The optional comment field continues to the end of the line, and is not used.
@@ -744,6 +801,21 @@ it being world-readable if the user's home directory resides on an NFS
744volume). 801volume).
745It is recommended that it not be accessible by others. 802It is recommended that it not be accessible by others.
746The format of this file is described above. 803The format of this file is described above.
804Users will place the contents of their
805.Pa identity.pub
806files into this file, as described in
807.Xr ssh-keygen 1 .
808.It Pa $HOME/.ssh/authorized_keys2
809Lists the DSA keys that can be used to log into the user's account.
810This file must be readable by root (which may on some machines imply
811it being world-readable if the user's home directory resides on an NFS
812volume).
813It is recommended that it not be accessible by others.
814The format of this file is described above.
815Users will place the contents of their
816.Pa id_dsa.pub
817files into this file, as described in
818.Xr ssh-keygen 1 .
747.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts" 819.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
748These files are consulted when using rhosts with RSA host 820These files are consulted when using rhosts with RSA host
749authentication to check the public key of the host. 821authentication to check the public key of the host.
@@ -875,6 +947,7 @@ but with bugs removed and newer features re-added.
875Rapidly after the 947Rapidly after the
8761.2.12 release, newer versions of the original ssh bore successively 9481.2.12 release, newer versions of the original ssh bore successively
877more restrictive licenses, and thus demand for a free version was born. 949more restrictive licenses, and thus demand for a free version was born.
950.Pp
878This version of OpenSSH 951This version of OpenSSH
879.Bl -bullet 952.Bl -bullet
880.It 953.It
@@ -883,8 +956,8 @@ directly removed from the source code; any licensed or patented components
883are chosen from 956are chosen from
884external libraries. 957external libraries.
885.It 958.It
886has been updated to support ssh protocol 1.5, making it compatible with 959has been updated to support SSH protocol 1.5 and 2, making it compatible with
887all other ssh protocol 1 clients and servers. 960all other SSH clients and servers.
888.It 961.It
889contains added support for 962contains added support for
890.Xr kerberos 8 963.Xr kerberos 8
@@ -893,6 +966,11 @@ authentication and ticket passing.
893supports one-time password authentication with 966supports one-time password authentication with
894.Xr skey 1 . 967.Xr skey 1 .
895.El 968.El
969.Pp
970OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl,
971Niels Provos, Theo de Raadt, and Dug Song.
972.Pp
973The support for SSH protocol 2 was written by Markus Friedl.
896.Sh SEE ALSO 974.Sh SEE ALSO
897.Xr scp 1 , 975.Xr scp 1 ,
898.Xr ssh 1 , 976.Xr ssh 1 ,
diff --git a/sshd.c b/sshd.c
index 70f292cc7..d1ed1506e 100644
--- a/sshd.c
+++ b/sshd.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: sshd.c,v 1.113 2000/05/01 20:34:51 markus Exp $"); 17RCSID("$OpenBSD: sshd.c,v 1.115 2000/05/03 10:21:49 markus Exp $");
18 18
19#include "xmalloc.h" 19#include "xmalloc.h"
20#include "rsa.h" 20#include "rsa.h"
@@ -562,8 +562,9 @@ main(int ac, char **av)
562 } 562 }
563 if (options.protocol & SSH_PROTO_2) { 563 if (options.protocol & SSH_PROTO_2) {
564 sensitive_data.dsa_host_key = key_new(KEY_DSA); 564 sensitive_data.dsa_host_key = key_new(KEY_DSA);
565 if (!load_private_key(options.dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) { 565 if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) {
566 error("Could not load DSA host key: %.200s", options.dsa_key_file); 566
567 error("Could not load DSA host key: %.200s", options.host_dsa_key_file);
567 log("Disabling protocol version 2"); 568 log("Disabling protocol version 2");
568 options.protocol &= ~SSH_PROTO_2; 569 options.protocol &= ~SSH_PROTO_2;
569 } 570 }
@@ -1320,7 +1321,7 @@ do_ssh2_kex()
1320 /* send server hostkey, DH pubkey 'f' and singed H */ 1321 /* send server hostkey, DH pubkey 'f' and singed H */
1321 packet_start(SSH2_MSG_KEXDH_REPLY); 1322 packet_start(SSH2_MSG_KEXDH_REPLY);
1322 packet_put_string((char *)server_host_key_blob, sbloblen); 1323 packet_put_string((char *)server_host_key_blob, sbloblen);
1323 packet_put_bignum2(dh->pub_key); // f 1324 packet_put_bignum2(dh->pub_key); /* f */
1324 packet_put_string((char *)signature, slen); 1325 packet_put_string((char *)signature, slen);
1325 packet_send(); 1326 packet_send();
1326 xfree(signature); 1327 xfree(signature);
diff --git a/uuencode.c b/uuencode.c
index 626890050..fc84d5a58 100644
--- a/uuencode.c
+++ b/uuencode.c
@@ -1,106 +1,36 @@
1/* 1/*
2 * base-64 encoding pinched from lynx2-7-2, who pinched it from rpem. 2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 * Originally written by Mark Riordan 12 August 1990 and 17 Feb 1991
4 * and placed in the public domain.
5 *
6 * Dug Song <dugsong@UMICH.EDU>
7 */ 3 */
8
9#include "includes.h" 4#include "includes.h"
10#include "xmalloc.h" 5#include "xmalloc.h"
11 6
12char six2pr[64] = { 7#include <resolv.h>
13 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
14 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
15 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
16 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
17 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
18};
19
20unsigned char pr2six[256];
21 8
22int 9int
23uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded) 10uuencode(unsigned char *src, unsigned int srclength,
11 char *target, size_t targsize)
24{ 12{
25 /* ENC is the basic 1 character encoding function to make a char printing */ 13 return __b64_ntop(src, srclength, target, targsize);
26#define ENC(c) six2pr[c]
27
28 register char *outptr = bufcoded;
29 unsigned int i;
30
31 for (i = 0; i < nbytes; i += 3) {
32 *(outptr++) = ENC(*bufin >> 2); /* c1 */
33 *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /* c2 */
34 *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)); /* c3 */
35 *(outptr++) = ENC(bufin[2] & 077); /* c4 */
36 bufin += 3;
37 }
38 if (i == nbytes + 1) {
39 outptr[-1] = '=';
40 } else if (i == nbytes + 2) {
41 outptr[-1] = '=';
42 outptr[-2] = '=';
43 } else if (i == nbytes) {
44 *(outptr++) = '=';
45 }
46 *outptr = '\0';
47 return (outptr - bufcoded);
48} 14}
49 15
50int 16int
51uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize) 17uudecode(const char *src, unsigned char *target, size_t targsize)
52{ 18{
53 /* single character decode */ 19 int len;
54#define DEC(c) pr2six[(unsigned char)c] 20 char *encoded, *p;
55#define MAXVAL 63
56
57 static int first = 1;
58 int nbytesdecoded, j;
59 const char *bufin = bufcoded;
60 register unsigned char *bufout = bufplain;
61 register int nprbytes;
62 21
63 /* If this is the first call, initialize the mapping table. */ 22 /* copy the 'readonly' source */
64 if (first) { 23 encoded = xstrdup(src);
65 first = 0; 24 /* skip whitespace and data */
66 for (j = 0; j < 256; j++) 25 for (p = encoded; *p == ' ' || *p == '\t'; p++)
67 pr2six[j] = MAXVAL + 1;
68 for (j = 0; j < 64; j++)
69 pr2six[(unsigned char) six2pr[j]] = (unsigned char) j;
70 }
71 /* Strip leading whitespace. */
72 while (*bufcoded == ' ' || *bufcoded == '\t')
73 bufcoded++;
74
75 /*
76 * Figure out how many characters are in the input buffer. If this
77 * would decode into more bytes than would fit into the output
78 * buffer, adjust the number of input bytes downwards.
79 */
80 bufin = bufcoded;
81 while (DEC(*(bufin++)) <= MAXVAL)
82 ; 26 ;
83 nprbytes = bufin - bufcoded - 1; 27 for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
84 nbytesdecoded = ((nprbytes + 3) / 4) * 3; 28 ;
85 if (nbytesdecoded > outbufsize) 29 /* and remote trailing whitespace because __b64_pton needs this */
86 nprbytes = (outbufsize * 4) / 3; 30 *p = '\0';
87 31 len = __b64_pton(encoded, target, targsize);
88 bufin = bufcoded; 32 xfree(encoded);
89 33 return len;
90 while (nprbytes > 0) {
91 *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
92 *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
93 *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
94 bufin += 4;
95 nprbytes -= 4;
96 }
97 if (nprbytes & 03) {
98 if (DEC(bufin[-2]) > MAXVAL)
99 nbytesdecoded -= 2;
100 else
101 nbytesdecoded -= 1;
102 }
103 return (nbytesdecoded);
104} 34}
105 35
106void 36void
@@ -108,7 +38,7 @@ dump_base64(FILE *fp, unsigned char *data, int len)
108{ 38{
109 unsigned char *buf = xmalloc(2*len); 39 unsigned char *buf = xmalloc(2*len);
110 int i, n; 40 int i, n;
111 n = uuencode(data, len, buf); 41 n = uuencode(data, len, buf, 2*len);
112 for (i = 0; i < n; i++) { 42 for (i = 0; i < n; i++) {
113 fprintf(fp, "%c", buf[i]); 43 fprintf(fp, "%c", buf[i]);
114 if (i % 70 == 69) 44 if (i % 70 == 69)
diff --git a/uuencode.h b/uuencode.h
index d3f446284..c92c62744 100644
--- a/uuencode.h
+++ b/uuencode.h
@@ -1,6 +1,6 @@
1#ifndef UUENCODE_H 1#ifndef UUENCODE_H
2#define UUENCODE_H 2#define UUENCODE_H
3int uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded); 3int uuencode(unsigned char *src, unsigned int srclength, char *target, size_t targsize);
4int uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize); 4int uudecode(const char *src, unsigned char *target, size_t targsize);
5void dump_base64(FILE *fp, unsigned char *data, int len); 5void dump_base64(FILE *fp, unsigned char *data, int len);
6#endif 6#endif