summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-03-26 13:04:51 +1000
committerDamien Miller <djm@mindrot.org>2000-03-26 13:04:51 +1000
commit450a7a1ff40fe7c2d84c93b83cf2df53445d807d (patch)
treedb6d08bdea65edd34ba2e323a31e2b1ca5e5fbd4
parent2c9279fa667827384fceb243f890cba1dbe480de (diff)
- OpenBSD CVS update
- [auth-krb4.c] -Wall - [auth-rh-rsa.c auth-rsa.c hostfile.c hostfile.h key.c key.h match.c] [match.h ssh.c ssh.h sshconnect.c sshd.c] initial support for DSA keys. ok deraadt@, niels@ - [cipher.c cipher.h] remove unused cipher_attack_detected code - [scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] Fix some formatting problems I missed before. - [ssh.1 sshd.8] fix spelling errors, From: FreeBSD - [ssh.c] switch to raw mode only if he _get_ a pty (not if we _want_ a pty).
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.in2
-rw-r--r--README.Ylonen4
-rw-r--r--auth-krb4.c2
-rw-r--r--auth-rh-rsa.c49
-rw-r--r--auth-rsa.c37
-rw-r--r--cipher.c16
-rw-r--r--cipher.h8
-rw-r--r--hostfile.c202
-rw-r--r--hostfile.h22
-rw-r--r--key.c301
-rw-r--r--key.h23
-rw-r--r--match.c61
-rw-r--r--match.h18
-rw-r--r--scp.129
-rw-r--r--ssh-add.133
-rw-r--r--ssh-agent.152
-rw-r--r--ssh-keygen.162
-rw-r--r--ssh.136
-rw-r--r--ssh.c13
-rw-r--r--ssh.h36
-rw-r--r--sshconnect.c72
-rw-r--r--sshd.8388
-rw-r--r--sshd.c30
24 files changed, 965 insertions, 545 deletions
diff --git a/ChangeLog b/ChangeLog
index 17f3e66d7..2462417dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,20 @@
2 - Better tests for OpenSSL w/ RSAref 2 - Better tests for OpenSSL w/ RSAref
3 - Added replacement setenv() function from OpenBSD libc. Suggested by 3 - Added replacement setenv() function from OpenBSD libc. Suggested by
4 Ben Lindstrom <mouring@pconline.com> 4 Ben Lindstrom <mouring@pconline.com>
5 - OpenBSD CVS update
6 - [auth-krb4.c]
7 -Wall
8 - [auth-rh-rsa.c auth-rsa.c hostfile.c hostfile.h key.c key.h match.c]
9 [match.h ssh.c ssh.h sshconnect.c sshd.c]
10 initial support for DSA keys. ok deraadt@, niels@
11 - [cipher.c cipher.h]
12 remove unused cipher_attack_detected code
13 - [scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8]
14 Fix some formatting problems I missed before.
15 - [ssh.1 sshd.8]
16 fix spelling errors, From: FreeBSD
17 - [ssh.c]
18 switch to raw mode only if he _get_ a pty (not if we _want_ a pty).
5 19
620000324 2020000324
7 - Released 1.2.3 21 - Released 1.2.3
diff --git a/Makefile.in b/Makefile.in
index 5db02beb6..6fee608df 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -31,7 +31,7 @@ LDFLAGS=-L. @LDFLAGS@
31 31
32TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) 32TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS)
33 33
34LIBOBJS= 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 fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hostfile.o log.o match.o mpaux.o nchan.o packet.o radix.o random.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o 34LIBOBJS= 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 fake-getaddrinfo.o fake-getnameinfo.o fingerprint.o hostfile.o key.o log.o match.o mpaux.o nchan.o packet.o radix.o random.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o
35 35
36SSHOBJS= ssh.o sshconnect.o log-client.o readconf.o clientloop.o 36SSHOBJS= ssh.o sshconnect.o log-client.o readconf.o clientloop.o
37 37
diff --git a/README.Ylonen b/README.Ylonen
index ed3608441..38987b926 100644
--- a/README.Ylonen
+++ b/README.Ylonen
@@ -1,3 +1,7 @@
1
2[ Please note that this file has not been updated for OpenSSH and
3 covers the ssh-1.2.12 release from Dec 1995 only. ]
4
1Ssh (Secure Shell) is a program to log into another computer over a 5Ssh (Secure Shell) is a program to log into another computer over a
2network, to execute commands in a remote machine, and to move files 6network, to execute commands in a remote machine, and to move files
3from one machine to another. It provides strong authentication and 7from one machine to another. It provides strong authentication and
diff --git a/auth-krb4.c b/auth-krb4.c
index 95fc7229f..7e30646f8 100644
--- a/auth-krb4.c
+++ b/auth-krb4.c
@@ -139,7 +139,7 @@ int
139krb4_init(uid_t uid) 139krb4_init(uid_t uid)
140{ 140{
141 static int cleanup_registered = 0; 141 static int cleanup_registered = 0;
142 char *tkt_root = TKT_ROOT; 142 const char *tkt_root = TKT_ROOT;
143 struct stat st; 143 struct stat st;
144 int fd; 144 int fd;
145 145
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
index 1392455cb..19782577b 100644
--- a/auth-rh-rsa.c
+++ b/auth-rh-rsa.c
@@ -15,7 +15,18 @@
15 */ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: auth-rh-rsa.c,v 1.7 1999/11/25 00:54:57 damien Exp $"); 18RCSID("$Id: auth-rh-rsa.c,v 1.8 2000/03/26 03:04:52 damien Exp $");
19
20#ifdef HAVE_OPENSSL
21#include <openssl/bn.h>
22#include <openssl/rsa.h>
23#include <openssl/dsa.h>
24#endif
25#ifdef HAVE_SSL
26#include <ssl/bn.h>
27#include <ssl/rsa.h>
28#include <ssl/dsa.h>
29#endif
19 30
20#include "packet.h" 31#include "packet.h"
21#include "ssh.h" 32#include "ssh.h"
@@ -23,37 +34,44 @@ RCSID("$Id: auth-rh-rsa.c,v 1.7 1999/11/25 00:54:57 damien Exp $");
23#include "uidswap.h" 34#include "uidswap.h"
24#include "servconf.h" 35#include "servconf.h"
25 36
37#include "key.h"
38#include "hostfile.h"
39
26/* 40/*
27 * Tries to authenticate the user using the .rhosts file and the host using 41 * Tries to authenticate the user using the .rhosts file and the host using
28 * its host key. Returns true if authentication succeeds. 42 * its host key. Returns true if authentication succeeds.
29 */ 43 */
30 44
31int 45int
32auth_rhosts_rsa(struct passwd *pw, const char *client_user, 46auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key)
33 BIGNUM *client_host_key_e, BIGNUM *client_host_key_n)
34{ 47{
35 extern ServerOptions options; 48 extern ServerOptions options;
36 const char *canonical_hostname; 49 const char *canonical_hostname;
37 HostStatus host_status; 50 HostStatus host_status;
38 BIGNUM *ke, *kn; 51 Key *client_key, *found;
39 52
40 debug("Trying rhosts with RSA host authentication for %.100s", client_user); 53 debug("Trying rhosts with RSA host authentication for %.100s", client_user);
41 54
55 if (client_host_key == NULL)
56 return 0;
57
42 /* Check if we would accept it using rhosts authentication. */ 58 /* Check if we would accept it using rhosts authentication. */
43 if (!auth_rhosts(pw, client_user)) 59 if (!auth_rhosts(pw, client_user))
44 return 0; 60 return 0;
45 61
46 canonical_hostname = get_canonical_hostname(); 62 canonical_hostname = get_canonical_hostname();
47 63
48 debug("Rhosts RSA authentication: canonical host %.900s", 64 debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname);
49 canonical_hostname); 65
66 /* wrap the RSA key into a 'generic' key */
67 client_key = key_new(KEY_RSA);
68 BN_copy(client_key->rsa->e, client_host_key->e);
69 BN_copy(client_key->rsa->n, client_host_key->n);
70 found = key_new(KEY_RSA);
50 71
51 /* Check if we know the host and its host key. */ 72 /* Check if we know the host and its host key. */
52 ke = BN_new();
53 kn = BN_new();
54 host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, 73 host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname,
55 client_host_key_e, client_host_key_n, 74 client_key, found);
56 ke, kn);
57 75
58 /* Check user host file unless ignored. */ 76 /* Check user host file unless ignored. */
59 if (host_status != HOST_OK && !options.ignore_user_known_hosts) { 77 if (host_status != HOST_OK && !options.ignore_user_known_hosts) {
@@ -73,14 +91,13 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user,
73 /* XXX race between stat and the following open() */ 91 /* XXX race between stat and the following open() */
74 temporarily_use_uid(pw->pw_uid); 92 temporarily_use_uid(pw->pw_uid);
75 host_status = check_host_in_hostfile(user_hostfile, canonical_hostname, 93 host_status = check_host_in_hostfile(user_hostfile, canonical_hostname,
76 client_host_key_e, client_host_key_n, 94 client_key, found);
77 ke, kn);
78 restore_uid(); 95 restore_uid();
79 } 96 }
80 xfree(user_hostfile); 97 xfree(user_hostfile);
81 } 98 }
82 BN_free(ke); 99 key_free(client_key);
83 BN_free(kn); 100 key_free(found);
84 101
85 if (host_status != HOST_OK) { 102 if (host_status != HOST_OK) {
86 debug("Rhosts with RSA host authentication denied: unknown or invalid host key"); 103 debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
@@ -90,7 +107,7 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user,
90 /* A matching host key was found and is known. */ 107 /* A matching host key was found and is known. */
91 108
92 /* Perform the challenge-response dialog with the client for the host key. */ 109 /* Perform the challenge-response dialog with the client for the host key. */
93 if (!auth_rsa_challenge_dialog(client_host_key_e, client_host_key_n)) { 110 if (!auth_rsa_challenge_dialog(client_host_key)) {
94 log("Client on %.800s failed to respond correctly to host authentication.", 111 log("Client on %.800s failed to respond correctly to host authentication.",
95 canonical_hostname); 112 canonical_hostname);
96 return 0; 113 return 0;
@@ -101,7 +118,7 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user,
101 */ 118 */
102 119
103 verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", 120 verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.",
104 pw->pw_name, client_user, canonical_hostname); 121 pw->pw_name, client_user, canonical_hostname);
105 packet_send_debug("Rhosts with RSA host authentication accepted."); 122 packet_send_debug("Rhosts with RSA host authentication accepted.");
106 return 1; 123 return 1;
107} 124}
diff --git a/auth-rsa.c b/auth-rsa.c
index ef7a2274e..22ac09c45 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include "includes.h" 18#include "includes.h"
19RCSID("$Id: auth-rsa.c,v 1.13 2000/03/09 10:27:50 damien Exp $"); 19RCSID("$Id: auth-rsa.c,v 1.14 2000/03/26 03:04:52 damien Exp $");
20 20
21#include "rsa.h" 21#include "rsa.h"
22#include "packet.h" 22#include "packet.h"
@@ -24,6 +24,7 @@ RCSID("$Id: auth-rsa.c,v 1.13 2000/03/09 10:27:50 damien Exp $");
24#include "ssh.h" 24#include "ssh.h"
25#include "mpaux.h" 25#include "mpaux.h"
26#include "uidswap.h" 26#include "uidswap.h"
27#include "match.h"
27#include "servconf.h" 28#include "servconf.h"
28 29
29#ifdef HAVE_OPENSSL 30#ifdef HAVE_OPENSSL
@@ -66,10 +67,9 @@ extern unsigned char session_id[16];
66 */ 67 */
67 68
68int 69int
69auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) 70auth_rsa_challenge_dialog(RSA *pk)
70{ 71{
71 BIGNUM *challenge, *encrypted_challenge; 72 BIGNUM *challenge, *encrypted_challenge;
72 RSA *pk;
73 BN_CTX *ctx; 73 BN_CTX *ctx;
74 unsigned char buf[32], mdbuf[16], response[16]; 74 unsigned char buf[32], mdbuf[16], response[16];
75 MD5_CTX md; 75 MD5_CTX md;
@@ -82,19 +82,11 @@ auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n)
82 /* Generate a random challenge. */ 82 /* Generate a random challenge. */
83 BN_rand(challenge, 256, 0, 0); 83 BN_rand(challenge, 256, 0, 0);
84 ctx = BN_CTX_new(); 84 ctx = BN_CTX_new();
85 BN_mod(challenge, challenge, n, ctx); 85 BN_mod(challenge, challenge, pk->n, ctx);
86 BN_CTX_free(ctx); 86 BN_CTX_free(ctx);
87 87
88 /* Create the public key data structure. */
89 pk = RSA_new();
90 pk->e = BN_new();
91 BN_copy(pk->e, e);
92 pk->n = BN_new();
93 BN_copy(pk->n, n);
94
95 /* Encrypt the challenge with the public key. */ 88 /* Encrypt the challenge with the public key. */
96 rsa_public_encrypt(encrypted_challenge, challenge, pk); 89 rsa_public_encrypt(encrypted_challenge, challenge, pk);
97 RSA_free(pk);
98 90
99 /* Send the encrypted challenge to the client. */ 91 /* Send the encrypted challenge to the client. */
100 packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); 92 packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE);
@@ -146,7 +138,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
146 FILE *f; 138 FILE *f;
147 unsigned long linenum = 0; 139 unsigned long linenum = 0;
148 struct stat st; 140 struct stat st;
149 BIGNUM *e, *n; 141 RSA *pk;
150 142
151 /* Temporarily use the user's uid. */ 143 /* Temporarily use the user's uid. */
152 temporarily_use_uid(pw->pw_uid); 144 temporarily_use_uid(pw->pw_uid);
@@ -208,8 +200,9 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
208 /* Flag indicating whether authentication has succeeded. */ 200 /* Flag indicating whether authentication has succeeded. */
209 authenticated = 0; 201 authenticated = 0;
210 202
211 e = BN_new(); 203 pk = RSA_new();
212 n = BN_new(); 204 pk->e = BN_new();
205 pk->n = BN_new();
213 206
214 /* 207 /*
215 * Go though the accepted keys, looking for the current key. If 208 * Go though the accepted keys, looking for the current key. If
@@ -247,7 +240,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
247 options = NULL; 240 options = NULL;
248 241
249 /* Parse the key from the line. */ 242 /* Parse the key from the line. */
250 if (!auth_rsa_read_key(&cp, &bits, e, n)) { 243 if (!auth_rsa_read_key(&cp, &bits, pk->e, pk->n)) {
251 debug("%.100s, line %lu: bad key syntax", 244 debug("%.100s, line %lu: bad key syntax",
252 SSH_USER_PERMITTED_KEYS, linenum); 245 SSH_USER_PERMITTED_KEYS, linenum);
253 packet_send_debug("%.100s, line %lu: bad key syntax", 246 packet_send_debug("%.100s, line %lu: bad key syntax",
@@ -257,19 +250,20 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
257 /* cp now points to the comment part. */ 250 /* cp now points to the comment part. */
258 251
259 /* Check if the we have found the desired key (identified by its modulus). */ 252 /* Check if the we have found the desired key (identified by its modulus). */
260 if (BN_cmp(n, client_n) != 0) 253 if (BN_cmp(pk->n, client_n) != 0)
261 continue; 254 continue;
262 255
263 /* check the real bits */ 256 /* check the real bits */
264 if (bits != BN_num_bits(n)) 257 if (bits != BN_num_bits(pk->n))
265 log("Warning: %s, line %ld: keysize mismatch: " 258 log("Warning: %s, line %ld: keysize mismatch: "
266 "actual %d vs. announced %d.", 259 "actual %d vs. announced %d.",
267 file, linenum, BN_num_bits(n), bits); 260 file, linenum, BN_num_bits(pk->n), bits);
268 261
269 /* We have found the desired key. */ 262 /* We have found the desired key. */
270 263
264
271 /* Perform the challenge-response dialog for this key. */ 265 /* Perform the challenge-response dialog for this key. */
272 if (!auth_rsa_challenge_dialog(e, n)) { 266 if (!auth_rsa_challenge_dialog(pk)) {
273 /* Wrong response. */ 267 /* Wrong response. */
274 verbose("Wrong response to RSA authentication challenge."); 268 verbose("Wrong response to RSA authentication challenge.");
275 packet_send_debug("Wrong response to RSA authentication challenge."); 269 packet_send_debug("Wrong response to RSA authentication challenge.");
@@ -472,8 +466,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
472 /* Close the file. */ 466 /* Close the file. */
473 fclose(f); 467 fclose(f);
474 468
475 BN_clear_free(n); 469 RSA_free(pk);
476 BN_clear_free(e);
477 470
478 if (authenticated) 471 if (authenticated)
479 packet_send_debug("RSA authentication accepted."); 472 packet_send_debug("RSA authentication accepted.");
diff --git a/cipher.c b/cipher.c
index c55c7dcbd..bf1518ded 100644
--- a/cipher.c
+++ b/cipher.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: cipher.c,v 1.13 2000/03/09 10:27:50 damien Exp $"); 15RCSID("$Id: cipher.c,v 1.14 2000/03/26 03:04:52 damien Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "cipher.h" 18#include "cipher.h"
@@ -110,18 +110,6 @@ swap_bytes(const unsigned char *src, unsigned char *dst_, int n)
110 } 110 }
111} 111}
112 112
113void (*cipher_attack_detected) (const char *fmt,...) = fatal;
114
115static inline void
116detect_cbc_attack(const unsigned char *src,
117 unsigned int len)
118{
119 return;
120
121 log("CRC-32 CBC insertion attack detected");
122 cipher_attack_detected("CRC-32 CBC insertion attack detected");
123}
124
125/* 113/*
126 * Names of all encryption algorithms. 114 * Names of all encryption algorithms.
127 * These must match the numbers defined in cipher.h. 115 * These must match the numbers defined in cipher.h.
@@ -304,7 +292,6 @@ cipher_decrypt(CipherContext *context, unsigned char *dest,
304 break; 292 break;
305 293
306 case SSH_CIPHER_3DES: 294 case SSH_CIPHER_3DES:
307 /* CRC-32 attack? */
308 SSH_3CBC_DECRYPT(context->u.des3.key1, 295 SSH_3CBC_DECRYPT(context->u.des3.key1,
309 context->u.des3.key2, &context->u.des3.iv2, 296 context->u.des3.key2, &context->u.des3.iv2,
310 context->u.des3.key3, &context->u.des3.iv3, 297 context->u.des3.key3, &context->u.des3.iv3,
@@ -312,7 +299,6 @@ cipher_decrypt(CipherContext *context, unsigned char *dest,
312 break; 299 break;
313 300
314 case SSH_CIPHER_BLOWFISH: 301 case SSH_CIPHER_BLOWFISH:
315 detect_cbc_attack(src, len);
316 swap_bytes(src, dest, len); 302 swap_bytes(src, dest, len);
317 BF_cbc_encrypt((void *) dest, dest, len, 303 BF_cbc_encrypt((void *) dest, dest, len,
318 &context->u.bf.key, context->u.bf.iv, 304 &context->u.bf.key, context->u.bf.iv,
diff --git a/cipher.h b/cipher.h
index 79e8fb878..c323a6c50 100644
--- a/cipher.h
+++ b/cipher.h
@@ -11,7 +11,7 @@
11 * 11 *
12 */ 12 */
13 13
14/* RCSID("$Id: cipher.h,v 1.5 1999/11/25 00:54:58 damien Exp $"); */ 14/* RCSID("$Id: cipher.h,v 1.6 2000/03/26 03:04:52 damien Exp $"); */
15 15
16#ifndef CIPHER_H 16#ifndef CIPHER_H
17#define CIPHER_H 17#define CIPHER_H
@@ -96,10 +96,4 @@ void
96cipher_decrypt(CipherContext * context, unsigned char *dest, 96cipher_decrypt(CipherContext * context, unsigned char *dest,
97 const unsigned char *src, unsigned int len); 97 const unsigned char *src, unsigned int len);
98 98
99/*
100 * If and CRC-32 attack is detected this function is called. Defaults to
101 * fatal, changed to packet_disconnect in sshd and ssh.
102 */
103extern void (*cipher_attack_detected) (const char *fmt, ...);
104
105#endif /* CIPHER_H */ 99#endif /* CIPHER_H */
diff --git a/hostfile.c b/hostfile.c
index ea92fa048..a6684fa2c 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -14,63 +14,32 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: hostfile.c,v 1.13 2000/02/18 10:20:20 markus Exp $"); 17RCSID("$OpenBSD: hostfile.c,v 1.14 2000/03/23 22:15:33 markus Exp $");
18
19#ifdef HAVE_OPENSSL
20#include <openssl/bn.h>
21#include <openssl/rsa.h>
22#include <openssl/dsa.h>
23#endif
24#ifdef HAVE_SSL
25#include <ssl/bn.h>
26#include <ssl/rsa.h>
27#include <ssl/dsa.h>
28#endif
18 29
19#include "packet.h" 30#include "packet.h"
31#include "match.h"
20#include "ssh.h" 32#include "ssh.h"
33#include "key.h"
34#include "hostfile.h"
21 35
22/* 36/*
23 * Reads a multiple-precision integer in decimal from the buffer, and advances 37 * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the
24 * the pointer. The integer must already be initialized. This function is 38 * pointer over the key. Skips any whitespace at the beginning and at end.
25 * permitted to modify the buffer. This leaves *cpp to point just beyond the
26 * last processed (and maybe modified) character. Note that this may modify
27 * the buffer containing the number.
28 */ 39 */
29 40
30int 41int
31auth_rsa_read_bignum(char **cpp, BIGNUM * value) 42hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
32{
33 char *cp = *cpp;
34 int old;
35
36 /* Skip any leading whitespace. */
37 for (; *cp == ' ' || *cp == '\t'; cp++)
38 ;
39
40 /* Check that it begins with a decimal digit. */
41 if (*cp < '0' || *cp > '9')
42 return 0;
43
44 /* Save starting position. */
45 *cpp = cp;
46
47 /* Move forward until all decimal digits skipped. */
48 for (; *cp >= '0' && *cp <= '9'; cp++)
49 ;
50
51 /* Save the old terminating character, and replace it by \0. */
52 old = *cp;
53 *cp = 0;
54
55 /* Parse the number. */
56 if (BN_dec2bn(&value, *cpp) == 0)
57 return 0;
58
59 /* Restore old terminating character. */
60 *cp = old;
61
62 /* Move beyond the number and return success. */
63 *cpp = cp;
64 return 1;
65}
66
67/*
68 * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer
69 * over the key. Skips any whitespace at the beginning and at end.
70 */
71
72int
73auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
74{ 43{
75 unsigned int bits; 44 unsigned int bits;
76 char *cp; 45 char *cp;
@@ -85,12 +54,7 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
85 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 54 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
86 bits = 10 * bits + *cp - '0'; 55 bits = 10 * bits + *cp - '0';
87 56
88 /* Get public exponent. */ 57 if (!key_read(ret, bits, &cp))
89 if (!auth_rsa_read_bignum(&cp, e))
90 return 0;
91
92 /* Get public modulus. */
93 if (!auth_rsa_read_bignum(&cp, n))
94 return 0; 58 return 0;
95 59
96 /* Skip trailing whitespace. */ 60 /* Skip trailing whitespace. */
@@ -103,63 +67,30 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
103 return 1; 67 return 1;
104} 68}
105 69
106/*
107 * Tries to match the host name (which must be in all lowercase) against the
108 * comma-separated sequence of subpatterns (each possibly preceded by ! to
109 * indicate negation). Returns true if there is a positive match; zero
110 * otherwise.
111 */
112
113int 70int
114match_hostname(const char *host, const char *pattern, unsigned int len) 71auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
115{ 72{
116 char sub[1024]; 73 Key *k = key_new(KEY_RSA);
117 int negated; 74 int ret = hostfile_read_key(cpp, bitsp, k);
118 int got_positive; 75 BN_copy(e, k->rsa->e);
119 unsigned int i, subi; 76 BN_copy(n, k->rsa->n);
120 77 key_free(k);
121 got_positive = 0; 78 return ret;
122 for (i = 0; i < len;) { 79}
123 /* Check if the subpattern is negated. */
124 if (pattern[i] == '!') {
125 negated = 1;
126 i++;
127 } else
128 negated = 0;
129
130 /*
131 * Extract the subpattern up to a comma or end. Convert the
132 * subpattern to lowercase.
133 */
134 for (subi = 0;
135 i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
136 subi++, i++)
137 sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
138 /* If subpattern too long, return failure (no match). */
139 if (subi >= sizeof(sub) - 1)
140 return 0;
141
142 /* If the subpattern was terminated by a comma, skip the comma. */
143 if (i < len && pattern[i] == ',')
144 i++;
145
146 /* Null-terminate the subpattern. */
147 sub[subi] = '\0';
148 80
149 /* Try to match the subpattern against the host name. */ 81int
150 if (match_pattern(host, sub)) { 82hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum)
151 if (negated) 83{
152 return 0; /* Fail */ 84 if (key == NULL || key->type != KEY_RSA || key->rsa == NULL)
153 else 85 return 1;
154 got_positive = 1; 86 if (bits != BN_num_bits(key->rsa->n)) {
155 } 87 error("Warning: %s, line %d: keysize mismatch for host %s: "
88 "actual %d vs. announced %d.",
89 filename, linenum, host, BN_num_bits(key->rsa->n), bits);
90 error("Warning: replace %d with %d in %s, line %d.",
91 bits, BN_num_bits(key->rsa->n), filename, linenum);
156 } 92 }
157 93 return 1;
158 /*
159 * Return success if got a positive match. If there was a negative
160 * match, we have already returned zero and never get here.
161 */
162 return got_positive;
163} 94}
164 95
165/* 96/*
@@ -170,8 +101,7 @@ match_hostname(const char *host, const char *pattern, unsigned int len)
170 */ 101 */
171 102
172HostStatus 103HostStatus
173check_host_in_hostfile(const char *filename, const char *host, 104check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found)
174 BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn)
175{ 105{
176 FILE *f; 106 FILE *f;
177 char line[8192]; 107 char line[8192];
@@ -180,6 +110,8 @@ check_host_in_hostfile(const char *filename, const char *host,
180 char *cp, *cp2; 110 char *cp, *cp2;
181 HostStatus end_return; 111 HostStatus end_return;
182 112
113 if (key == NULL)
114 fatal("no key to look up");
183 /* Open the file containing the list of known hosts. */ 115 /* Open the file containing the list of known hosts. */
184 f = fopen(filename, "r"); 116 f = fopen(filename, "r");
185 if (!f) 117 if (!f)
@@ -221,18 +153,13 @@ check_host_in_hostfile(const char *filename, const char *host,
221 * Extract the key from the line. This will skip any leading 153 * Extract the key from the line. This will skip any leading
222 * whitespace. Ignore badly formatted lines. 154 * whitespace. Ignore badly formatted lines.
223 */ 155 */
224 if (!auth_rsa_read_key(&cp, &kbits, ke, kn)) 156 if (!hostfile_read_key(&cp, &kbits, found))
157 continue;
158 if (!hostfile_check_key(kbits, found, host, filename, linenum))
225 continue; 159 continue;
226 160
227 if (kbits != BN_num_bits(kn)) {
228 error("Warning: %s, line %d: keysize mismatch for host %s: "
229 "actual %d vs. announced %d.",
230 filename, linenum, host, BN_num_bits(kn), kbits);
231 error("Warning: replace %d with %d in %s, line %d.",
232 kbits, BN_num_bits(kn), filename, linenum);
233 }
234 /* Check if the current key is the same as the given key. */ 161 /* Check if the current key is the same as the given key. */
235 if (BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) { 162 if (key_equal(key, found)) {
236 /* Ok, they match. */ 163 /* Ok, they match. */
237 fclose(f); 164 fclose(f);
238 return HOST_OK; 165 return HOST_OK;
@@ -260,41 +187,28 @@ check_host_in_hostfile(const char *filename, const char *host,
260 */ 187 */
261 188
262int 189int
263add_host_to_hostfile(const char *filename, const char *host, 190add_host_to_hostfile(const char *filename, const char *host, Key *key)
264 BIGNUM * e, BIGNUM * n)
265{ 191{
266 FILE *f; 192 FILE *f;
267 char *buf; 193 int success = 0;
268 unsigned int bits; 194
195 if (key == NULL)
196 return 1;
269 197
270 /* Open the file for appending. */ 198 /* Open the file for appending. */
271 f = fopen(filename, "a"); 199 f = fopen(filename, "a");
272 if (!f) 200 if (!f)
273 return 0; 201 return 0;
274 202
275 /* size of modulus 'n' */ 203 fprintf(f, "%s ", host);
276 bits = BN_num_bits(n); 204 if (key_write(key, f)) {
277 205 fprintf(f, "\n");
278 /* Print the host name and key to the file. */ 206 success = 1;
279 fprintf(f, "%s %u ", host, bits); 207 } else {
280 buf = BN_bn2dec(e); 208 error("add_host_to_hostfile: saving key failed");
281 if (buf == NULL) {
282 error("add_host_to_hostfile: BN_bn2dec(e) failed");
283 fclose(f);
284 return 0;
285 } 209 }
286 fprintf(f, "%s ", buf);
287 free(buf);
288 buf = BN_bn2dec(n);
289 if (buf == NULL) {
290 error("add_host_to_hostfile: BN_bn2dec(n) failed");
291 fclose(f);
292 return 0;
293 }
294 fprintf(f, "%s\n", buf);
295 free(buf);
296 210
297 /* Close the file. */ 211 /* Close the file. */
298 fclose(f); 212 fclose(f);
299 return 1; 213 return success;
300} 214}
diff --git a/hostfile.h b/hostfile.h
new file mode 100644
index 000000000..64fe185da
--- /dev/null
+++ b/hostfile.h
@@ -0,0 +1,22 @@
1#ifndef HOSTFILE_H
2#define HOSTFILE_H
3
4/*
5 * Checks whether the given host is already in the list of our known hosts.
6 * Returns HOST_OK if the host is known and has the specified key, HOST_NEW
7 * if the host is not known, and HOST_CHANGED if the host is known but used
8 * to have a different host key. The host must be in all lowercase.
9 */
10typedef enum {
11 HOST_OK, HOST_NEW, HOST_CHANGED
12} HostStatus;
13HostStatus
14check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found);
15
16/*
17 * Appends an entry to the host file. Returns false if the entry could not
18 * be appended.
19 */
20int add_host_to_hostfile(const char *filename, const char *host, Key *key);
21
22#endif
diff --git a/key.c b/key.c
new file mode 100644
index 000000000..437a5e245
--- /dev/null
+++ b/key.c
@@ -0,0 +1,301 @@
1/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * read_bignum():
31 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
32 */
33
34#include "includes.h"
35
36#ifdef HAVE_OPENSSL
37#include <openssl/bn.h>
38#include <openssl/rsa.h>
39#include <openssl/dsa.h>
40#include <openssl/evp.h>
41#endif
42#ifdef HAVE_SSL
43#include <ssl/bn.h>
44#include <ssl/rsa.h>
45#include <ssl/dsa.h>
46#include <ssl/evp.h>
47#endif
48
49#include "ssh.h"
50#include "xmalloc.h"
51#include "key.h"
52
53Key *
54key_new(int type)
55{
56 Key *k;
57 RSA *rsa;
58 DSA *dsa;
59 k = xmalloc(sizeof(*k));
60 k->type = type;
61 switch (k->type) {
62 case KEY_RSA:
63 rsa = RSA_new();
64 rsa->n = BN_new();
65 rsa->e = BN_new();
66 k->rsa = rsa;
67 break;
68 case KEY_DSA:
69 dsa = DSA_new();
70 dsa->p = BN_new();
71 dsa->q = BN_new();
72 dsa->g = BN_new();
73 dsa->pub_key = BN_new();
74 k->dsa = dsa;
75 break;
76 case KEY_EMPTY:
77 k->dsa = NULL;
78 k->rsa = NULL;
79 break;
80 default:
81 fatal("key_new: bad key type %d", k->type);
82 break;
83 }
84 return k;
85}
86void
87key_free(Key *k)
88{
89 switch (k->type) {
90 case KEY_RSA:
91 if (k->rsa != NULL)
92 RSA_free(k->rsa);
93 k->rsa = NULL;
94 break;
95 case KEY_DSA:
96 if (k->dsa != NULL)
97 DSA_free(k->dsa);
98 k->dsa = NULL;
99 break;
100 default:
101 fatal("key_free: bad key type %d", k->type);
102 break;
103 }
104 xfree(k);
105}
106int
107key_equal(Key *a, Key *b)
108{
109 if (a == NULL || b == NULL || a->type != b->type)
110 return 0;
111 switch (a->type) {
112 case KEY_RSA:
113 return a->rsa != NULL && b->rsa != NULL &&
114 BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
115 BN_cmp(a->rsa->n, b->rsa->n) == 0;
116 break;
117 case KEY_DSA:
118 return a->dsa != NULL && b->dsa != NULL &&
119 BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
120 BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
121 BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
122 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
123 break;
124 default:
125 fatal("key_free: bad key type %d", a->type);
126 break;
127 }
128 return 0;
129}
130
131#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
132
133/*
134 * Generate key fingerprint in ascii format.
135 * Based on ideas and code from Bjoern Groenvall <bg@sics.se>
136 */
137char *
138key_fingerprint(Key *k)
139{
140 static char retval[80];
141 unsigned char *buf = NULL;
142 int len = 0;
143 int nlen, elen, plen, qlen, glen, publen;
144
145 switch (k->type) {
146 case KEY_RSA:
147 nlen = BN_num_bytes(k->rsa->n);
148 elen = BN_num_bytes(k->rsa->e);
149 len = nlen + elen;
150 buf = xmalloc(len);
151 BN_bn2bin(k->rsa->n, buf);
152 BN_bn2bin(k->rsa->e, buf + nlen);
153 break;
154 case KEY_DSA:
155 plen = BN_num_bytes(k->dsa->p);
156 qlen = BN_num_bytes(k->dsa->q);
157 glen = BN_num_bytes(k->dsa->g);
158 publen = BN_num_bytes(k->dsa->pub_key);
159 len = qlen + qlen + glen + publen;
160 buf = xmalloc(len);
161 BN_bn2bin(k->dsa->p, buf);
162 BN_bn2bin(k->dsa->q, buf + plen);
163 BN_bn2bin(k->dsa->g, buf + plen + qlen);
164 BN_bn2bin(k->dsa->pub_key , buf + plen + qlen + glen);
165 break;
166 default:
167 fatal("key_fingerprint: bad key type %d", k->type);
168 break;
169 }
170 if (buf != NULL) {
171 unsigned char d[16];
172 EVP_MD_CTX md;
173 EVP_DigestInit(&md, EVP_md5());
174 EVP_DigestUpdate(&md, buf, len);
175 EVP_DigestFinal(&md, d, NULL);
176 snprintf(retval, sizeof(retval), FPRINT,
177 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
178 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
179 memset(buf, 0, len);
180 xfree(buf);
181 }
182 return retval;
183}
184
185/*
186 * Reads a multiple-precision integer in decimal from the buffer, and advances
187 * the pointer. The integer must already be initialized. This function is
188 * permitted to modify the buffer. This leaves *cpp to point just beyond the
189 * last processed (and maybe modified) character. Note that this may modify
190 * the buffer containing the number.
191 */
192int
193read_bignum(char **cpp, BIGNUM * value)
194{
195 char *cp = *cpp;
196 int old;
197
198 /* Skip any leading whitespace. */
199 for (; *cp == ' ' || *cp == '\t'; cp++)
200 ;
201
202 /* Check that it begins with a decimal digit. */
203 if (*cp < '0' || *cp > '9')
204 return 0;
205
206 /* Save starting position. */
207 *cpp = cp;
208
209 /* Move forward until all decimal digits skipped. */
210 for (; *cp >= '0' && *cp <= '9'; cp++)
211 ;
212
213 /* Save the old terminating character, and replace it by \0. */
214 old = *cp;
215 *cp = 0;
216
217 /* Parse the number. */
218 if (BN_dec2bn(&value, *cpp) == 0)
219 return 0;
220
221 /* Restore old terminating character. */
222 *cp = old;
223
224 /* Move beyond the number and return success. */
225 *cpp = cp;
226 return 1;
227}
228int
229write_bignum(FILE *f, BIGNUM *num)
230{
231 char *buf = BN_bn2dec(num);
232 if (buf == NULL) {
233 error("write_bignum: BN_bn2dec() failed");
234 return 0;
235 }
236 fprintf(f, " %s", buf);
237 free(buf);
238 return 1;
239}
240int
241key_read(Key *ret, unsigned int bits, char **cpp)
242{
243 switch(ret->type) {
244 case KEY_RSA:
245 if (bits == 0)
246 return 0;
247 /* Get public exponent, public modulus. */
248 if (!read_bignum(cpp, ret->rsa->e))
249 return 0;
250 if (!read_bignum(cpp, ret->rsa->n))
251 return 0;
252 break;
253 case KEY_DSA:
254 if (bits != 0)
255 return 0;
256 if (!read_bignum(cpp, ret->dsa->p))
257 return 0;
258 if (!read_bignum(cpp, ret->dsa->q))
259 return 0;
260 if (!read_bignum(cpp, ret->dsa->g))
261 return 0;
262 if (!read_bignum(cpp, ret->dsa->pub_key))
263 return 0;
264 break;
265 default:
266 fatal("bad key type: %d", ret->type);
267 break;
268 }
269 return 1;
270}
271int
272key_write(Key *key, FILE *f)
273{
274 int success = 0;
275 unsigned int bits = 0;
276
277 if (key->type == KEY_RSA && key->rsa != NULL) {
278 /* size of modulus 'n' */
279 bits = BN_num_bits(key->rsa->n);
280 fprintf(f, "%u", bits);
281 if (write_bignum(f, key->rsa->e) &&
282 write_bignum(f, key->rsa->n)) {
283 success = 1;
284 } else {
285 error("key_write: failed for RSA key");
286 }
287 } else if (key->type == KEY_DSA && key->dsa != NULL) {
288 /* bits == 0 means DSA key */
289 bits = 0;
290 fprintf(f, "%u", bits);
291 if (write_bignum(f, key->dsa->p) &&
292 write_bignum(f, key->dsa->q) &&
293 write_bignum(f, key->dsa->g) &&
294 write_bignum(f, key->dsa->pub_key)) {
295 success = 1;
296 } else {
297 error("key_write: failed for DSA key");
298 }
299 }
300 return success;
301}
diff --git a/key.h b/key.h
new file mode 100644
index 000000000..70f0c518b
--- /dev/null
+++ b/key.h
@@ -0,0 +1,23 @@
1#ifndef KEY_H
2#define KEY_H
3
4typedef struct Key Key;
5enum types {
6 KEY_RSA,
7 KEY_DSA,
8 KEY_EMPTY
9};
10struct Key {
11 int type;
12 RSA *rsa;
13 DSA *dsa;
14};
15
16Key *key_new(int type);
17void key_free(Key *k);
18int key_equal(Key *a, Key *b);
19char *key_fingerprint(Key *k);
20int key_write(Key *key, FILE *f);
21int key_read(Key *key, unsigned int bits, char **cpp);
22
23#endif
diff --git a/match.c b/match.c
index 5386df6c4..b72efca7e 100644
--- a/match.c
+++ b/match.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: match.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); 17RCSID("$Id: match.c,v 1.4 2000/03/26 03:04:53 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20 20
@@ -80,3 +80,62 @@ match_pattern(const char *s, const char *pattern)
80 } 80 }
81 /* NOTREACHED */ 81 /* NOTREACHED */
82} 82}
83
84/*
85 * Tries to match the host name (which must be in all lowercase) against the
86 * comma-separated sequence of subpatterns (each possibly preceded by ! to
87 * indicate negation). Returns true if there is a positive match; zero
88 * otherwise.
89 */
90
91int
92match_hostname(const char *host, const char *pattern, unsigned int len)
93{
94 char sub[1024];
95 int negated;
96 int got_positive;
97 unsigned int i, subi;
98
99 got_positive = 0;
100 for (i = 0; i < len;) {
101 /* Check if the subpattern is negated. */
102 if (pattern[i] == '!') {
103 negated = 1;
104 i++;
105 } else
106 negated = 0;
107
108 /*
109 * Extract the subpattern up to a comma or end. Convert the
110 * subpattern to lowercase.
111 */
112 for (subi = 0;
113 i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
114 subi++, i++)
115 sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
116 /* If subpattern too long, return failure (no match). */
117 if (subi >= sizeof(sub) - 1)
118 return 0;
119
120 /* If the subpattern was terminated by a comma, skip the comma. */
121 if (i < len && pattern[i] == ',')
122 i++;
123
124 /* Null-terminate the subpattern. */
125 sub[subi] = '\0';
126
127 /* Try to match the subpattern against the host name. */
128 if (match_pattern(host, sub)) {
129 if (negated)
130 return 0; /* Fail */
131 else
132 got_positive = 1;
133 }
134 }
135
136 /*
137 * Return success if got a positive match. If there was a negative
138 * match, we have already returned zero and never get here.
139 */
140 return got_positive;
141}
diff --git a/match.h b/match.h
new file mode 100644
index 000000000..4625d9769
--- /dev/null
+++ b/match.h
@@ -0,0 +1,18 @@
1#ifndef MATCH_H
2#define MATCH_H
3
4/*
5 * Returns true if the given string matches the pattern (which may contain ?
6 * and * as wildcards), and zero if it does not match.
7 */
8int match_pattern(const char *s, const char *pattern);
9
10/*
11 * Tries to match the host name (which must be in all lowercase) against the
12 * comma-separated sequence of subpatterns (each possibly preceded by ! to
13 * indicate negation). Returns true if there is a positive match; zero
14 * otherwise.
15 */
16int match_hostname(const char *host, const char *pattern, unsigned int len);
17
18#endif
diff --git a/scp.1 b/scp.1
index b9f686155..5604cb80b 100644
--- a/scp.1
+++ b/scp.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sun May 7 00:14:37 1995 ylo 10.\" Created: Sun May 7 00:14:37 1995 ylo
11.\" 11.\"
12.\" $Id: scp.1,v 1.5 2000/01/20 12:13:36 damien Exp $ 12.\" $Id: scp.1,v 1.6 2000/03/26 03:04:53 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SCP 1 15.Dt SCP 1
@@ -38,7 +38,8 @@
38.Sm on 38.Sm on
39.Sh DESCRIPTION 39.Sh DESCRIPTION
40.Nm 40.Nm
41copies files between hosts on a network. It uses 41copies files between hosts on a network.
42It uses
42.Xr ssh 1 43.Xr ssh 1
43for data transfer, and uses the same authentication and provides the 44for data transfer, and uses the same authentication and provides the
44same security as 45same security as
@@ -50,18 +51,19 @@ will ask for passwords or passphrases if they are needed for
50authentication. 51authentication.
51.Pp 52.Pp
52Any file name may contain a host and user specification to indicate 53Any file name may contain a host and user specification to indicate
53that the file is to be copied to/from that host. Copies between two 54that the file is to be copied to/from that host.
54remote hosts are permitted. 55Copies between two remote hosts are permitted.
55.Pp 56.Pp
56The options are as follows: 57The options are as follows:
57.Bl -tag -width Ds 58.Bl -tag -width Ds
58.It Fl c Ar cipher 59.It Fl c Ar cipher
59Selects the cipher to use for encrypting the data transfer. This 60Selects the cipher to use for encrypting the data transfer.
60option is directly passed to 61This option is directly passed to
61.Xr ssh 1 . 62.Xr ssh 1 .
62.It Fl i Ar identity_file 63.It Fl i Ar identity_file
63Selects the file from which the identity (private key) for RSA 64Selects the file from which the identity (private key) for RSA
64authentication is read. This option is directly passed to 65authentication is read.
66This option is directly passed to
65.Xr ssh 1 . 67.Xr ssh 1 .
66.It Fl p 68.It Fl p
67Preserves modification times, access times, and modes from the 69Preserves modification times, access times, and modes from the
@@ -69,25 +71,28 @@ original file.
69.It Fl r 71.It Fl r
70Recursively copy entire directories. 72Recursively copy entire directories.
71.It Fl v 73.It Fl v
72Verbose mode. Causes 74Verbose mode.
75Causes
73.Nm 76.Nm
74and 77and
75.Xr ssh 1 78.Xr ssh 1
76to print debugging messages about their progress. This is helpful in 79to print debugging messages about their progress.
80This is helpful in
77debugging connection, authentication, and configuration problems. 81debugging connection, authentication, and configuration problems.
78.It Fl B 82.It Fl B
79Selects batch mode (prevents asking for passwords or passphrases). 83Selects batch mode (prevents asking for passwords or passphrases).
80.It Fl q 84.It Fl q
81Disables the progress meter. 85Disables the progress meter.
82.It Fl C 86.It Fl C
83Compression enable. Passes the 87Compression enable.
88Passes the
84.Fl C 89.Fl C
85flag to 90flag to
86.Xr ssh 1 91.Xr ssh 1
87to enable compression. 92to enable compression.
88.It Fl P Ar port 93.It Fl P Ar port
89Specifies the port to connect to on the remote host. Note that this 94Specifies the port to connect to on the remote host.
90option is written with a capital 95Note that this option is written with a capital
91.Sq P , 96.Sq P ,
92because 97because
93.Fl p 98.Fl p
diff --git a/ssh-add.1 b/ssh-add.1
index e56140d12..6c35996b6 100644
--- a/ssh-add.1
+++ b/ssh-add.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-add.1,v 1.9 2000/01/22 08:57:40 damien Exp $ 12.\" $Id: ssh-add.1,v 1.10 2000/03/26 03:04:53 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH-ADD 1 15.Dt SSH-ADD 1
@@ -27,11 +27,11 @@ adds 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 .
30Alternative file names can be given on the 30Alternative file names can be given on the command line.
31command line. If any file requires a passphrase, 31If any file requires a passphrase,
32.Nm 32.Nm
33asks for the passphrase from the user. 33asks for the passphrase from the user.
34The Passphrase it is read from the user's tty. 34The Passphrase it is read from the user's tty.
35.Pp 35.Pp
36The authentication agent must be running and must be an ancestor of 36The authentication agent must be running and must be an ancestor of
37the current process for 37the current process for
@@ -52,15 +52,15 @@ Deletes all identities from the agent.
52.Sh FILES 52.Sh FILES
53.Bl -tag -width Ds 53.Bl -tag -width Ds
54.It Pa $HOME/.ssh/identity 54.It Pa $HOME/.ssh/identity
55Contains the RSA authentication identity of the user. This file 55Contains the RSA authentication identity of the user.
56should not be readable by anyone but the user. 56This file should not be readable by anyone but the user.
57Note that 57Note that
58.Nm 58.Nm
59ignores this file if it is accessible by others. 59ignores this file if it is accessible by others.
60It is possible to 60It is possible to
61specify a passphrase when generating the key; that passphrase will be 61specify a passphrase when generating the key; that passphrase will be
62used to encrypt the private part of this file. This is the 62used to encrypt the private part of this file.
63default file added by 63This is the default file added by
64.Nm 64.Nm
65when no other files have been specified. 65when no other files have been specified.
66.Pp 66.Pp
@@ -70,7 +70,8 @@ when no other files have been specified.
70If 70If
71.Nm 71.Nm
72needs a passphrase, it will read the passphrase from the current 72needs a passphrase, it will read the passphrase from the current
73terminal if it was run from a terminal. If 73terminal if it was run from a terminal.
74If
74.Nm 75.Nm
75does not have a terminal associated with it but 76does not have a terminal associated with it but
76.Ev DISPLAY 77.Ev DISPLAY
@@ -78,12 +79,13 @@ and
78.Ev SSH_ASKPASS 79.Ev SSH_ASKPASS
79are set, it will execute the program specified by 80are set, it will execute the program specified by
80.Ev SSH_ASKPASS 81.Ev SSH_ASKPASS
81and open an X11 window to read the passphrase. This is particularly 82and open an X11 window to read the passphrase.
82useful when calling 83This is particularly useful when calling
83.Nm 84.Nm
84from a 85from a
85.Pa .Xsession 86.Pa .Xsession
86or related script. (Note that on some machines it 87or related script.
88(Note that on some machines it
87may be necessary to redirect the input from 89may be necessary to redirect the input from
88.Pa /dev/null 90.Pa /dev/null
89to make this work.) 91to make this work.)
@@ -92,9 +94,10 @@ Tatu Ylonen <ylo@cs.hut.fi>
92.Pp 94.Pp
93OpenSSH 95OpenSSH
94is a derivative of the original (free) ssh 1.2.12 release, but with bugs 96is a derivative of the original (free) ssh 1.2.12 release, but with bugs
95removed and newer features re-added. Rapidly after the 1.2.12 release, 97removed and newer features re-added.
96newer versions bore successively more restrictive licenses. This version 98Rapidly after the 1.2.12 release,
97of OpenSSH 99newer versions bore successively more restrictive licenses.
100This version of OpenSSH
98.Bl -bullet 101.Bl -bullet
99.It 102.It
100has all components of a restrictive nature (i.e., patents, see 103has all components of a restrictive nature (i.e., patents, see
diff --git a/ssh-agent.1 b/ssh-agent.1
index b98775d90..7029b60dc 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-agent.1,v 1.9 2000/01/22 02:17:50 aaron Exp $ 1.\" $OpenBSD: ssh-agent.1,v 1.10 2000/03/23 21:10:10 aaron Exp $
2.\" 2.\"
3.\" -*- nroff -*- 3.\" -*- nroff -*-
4.\" 4.\"
@@ -27,12 +27,13 @@
27.Oc 27.Oc
28.Sh DESCRIPTION 28.Sh DESCRIPTION
29.Nm 29.Nm
30is a program to hold authentication private keys. The 30is a program to hold authentication private keys.
31idea 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
34all other windows or programs are started as clients to the ssh-agent 34all other windows or programs are started as clients to the ssh-agent
35program. Through use of environment variables the agent can be located 35program.
36Through use of environment variables the agent can be located
36and automatically used for RSA authentication when logging in to other 37and automatically used for RSA authentication when logging in to other
37machines using 38machines using
38.Xr ssh 1 . 39.Xr ssh 1 .
@@ -60,30 +61,34 @@ environment variable).
60If a commandline is given, this is executed as a subprocess of the agent. 61If a commandline is given, this is executed as a subprocess of the agent.
61When the command dies, so does the agent. 62When the command dies, so does the agent.
62.Pp 63.Pp
63The agent initially does not have any private keys. Keys are added 64The agent initially does not have any private keys.
64using 65Keys are added using
65.Xr ssh-add 1 . 66.Xr ssh-add 1 .
66When executed without arguments, 67When executed without arguments,
67.Xr ssh-add 1 68.Xr ssh-add 1
68adds the 69adds the
69.Pa $HOME/.ssh/identity 70.Pa $HOME/.ssh/identity
70file. If the identity has a passphrase, 71file.
72If the identity has a passphrase,
71.Xr ssh-add 1 73.Xr ssh-add 1
72asks for the passphrase (using a small X11 application if running 74asks for the passphrase (using a small X11 application if running
73under X11, or from the terminal if running without X). It then sends 75under X11, or from the terminal if running without X).
74the identity to the agent. Several identities can be stored in the 76It then sends the identity to the agent.
77Several identities can be stored in the
75agent; the agent can automatically use any of these identities. 78agent; the agent can automatically use any of these identities.
76.Ic ssh-add -l 79.Ic ssh-add -l
77displays the identities currently held by the agent. 80displays the identities currently held by the agent.
78.Pp 81.Pp
79The idea is that the agent is run in the user's local PC, laptop, or 82The idea is that the agent is run in the user's local PC, laptop, or
80terminal. Authentication data need not be stored on any other 83terminal.
84Authentication data need not be stored on any other
81machine, and authentication passphrases never go over the network. 85machine, and authentication passphrases never go over the network.
82However, the connection to the agent is forwarded over SSH 86However, the connection to the agent is forwarded over SSH
83remote logins, and the user can thus use the privileges given by the 87remote logins, and the user can thus use the privileges given by the
84identities anywhere in the network in a secure way. 88identities anywhere in the network in a secure way.
85.Pp 89.Pp
86There are two main ways to get an agent setup: Either you let the agent 90There are two main ways to get an agent setup:
91Either you let the agent
87start a new subcommand into which some environment variables are exported, or 92start a new subcommand into which some environment variables are exported, or
88you let the agent print the needed shell commands (either 93you let the agent print the needed shell commands (either
89.Xr sh 1 94.Xr sh 1
@@ -99,7 +104,8 @@ A unix-domain socket is created
99and the name of this socket is stored in the 104and the name of this socket is stored in the
100.Ev SSH_AUTH_SOCK 105.Ev SSH_AUTH_SOCK
101environment 106environment
102variable. The socket is made accessible only to the current user. 107variable.
108The socket is made accessible only to the current user.
103This method is easily abused by root or another instance of the same 109This method is easily abused by root or another instance of the same
104user. 110user.
105.Pp 111.Pp
@@ -112,28 +118,30 @@ line terminates.
112.Sh FILES 118.Sh FILES
113.Bl -tag -width Ds 119.Bl -tag -width Ds
114.It Pa $HOME/.ssh/identity 120.It Pa $HOME/.ssh/identity
115Contains the RSA authentication identity of the user. This file 121Contains the RSA authentication identity of the user.
116should not be readable by anyone but the user. It is possible to 122This file should not be readable by anyone but the user.
123It is possible to
117specify a passphrase when generating the key; that passphrase will be 124specify a passphrase when generating the key; that passphrase will be
118used to encrypt the private part of this file. This file 125used to encrypt the private part of this file.
119is not used by 126This file is not used by
120.Nm 127.Nm
121but is normally added to the agent using 128but is normally added to the agent using
122.Xr ssh-add 1 129.Xr ssh-add 1
123at login time. 130at login time.
124.It Pa /tmp/ssh-XXXX/agent.<pid> , 131.It Pa /tmp/ssh-XXXX/agent.<pid> ,
125Unix-domain sockets used to contain the connection to the 132Unix-domain sockets used to contain the connection to the
126authentication agent. These sockets should only be readable by the 133authentication agent.
127owner. The sockets should get automatically removed when the agent 134These sockets should only be readable by the owner.
128exits. 135The sockets should get automatically removed when the agent exits.
129.Sh AUTHOR 136.Sh AUTHOR
130Tatu Ylonen <ylo@cs.hut.fi> 137Tatu Ylonen <ylo@cs.hut.fi>
131.Pp 138.Pp
132OpenSSH 139OpenSSH
133is a derivative of the original (free) ssh 1.2.12 release, but with bugs 140is a derivative of the original (free) ssh 1.2.12 release, but with bugs
134removed and newer features re-added. Rapidly after the 1.2.12 release, 141removed and newer features re-added.
135newer versions bore successively more restrictive licenses. This version 142Rapidly after the 1.2.12 release,
136of OpenSSH 143newer versions bore successively more restrictive licenses.
144This version of OpenSSH
137.Bl -bullet 145.Bl -bullet
138.It 146.It
139has all components of a restrictive nature (i.e., patents, see 147has all components of a restrictive nature (i.e., patents, see
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 74fe86906..8474e8f9d 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.9 2000/01/22 08:57:40 damien Exp $ 12.\" $Id: ssh-keygen.1,v 1.10 2000/03/26 03:04:53 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH-KEYGEN 1 15.Dt SSH-KEYGEN 1
@@ -48,27 +48,31 @@ key in
48Additionally, the system administrator may use this to generate host keys. 48Additionally, the system administrator may use this to generate host keys.
49.Pp 49.Pp
50Normally this program generates the key and asks for a file in which 50Normally this program generates the key and asks for a file in which
51to store the private key. The public key is stored in a file with the 51to store the private key.
52same name but 52The public key is stored in a file with the same name but
53.Dq .pub 53.Dq .pub
54appended. The program also asks for a 54appended.
55passphrase. The passphrase may be empty to indicate no passphrase 55The program also asks for a passphrase.
56The passphrase may be empty to indicate no passphrase
56(host keys must have empty passphrase), or it may be a string of 57(host keys must have empty passphrase), or it may be a string of
57arbitrary length. Good passphrases are 10-30 characters long and are 58arbitrary length.
59Good passphrases are 10-30 characters long and are
58not simple sentences or otherwise easily guessable (English 60not simple sentences or otherwise easily guessable (English
59prose has only 1-2 bits of entropy per word, and provides very bad 61prose has only 1-2 bits of entropy per word, and provides very bad
60passphrases). The passphrase can be changed later by using the 62passphrases).
63The passphrase can be changed later by using the
61.Fl p 64.Fl p
62option. 65option.
63.Pp 66.Pp
64There is no way to recover a lost passphrase. If the passphrase is 67There is no way to recover a lost passphrase.
68If the passphrase is
65lost or forgotten, you will have to generate a new key and copy the 69lost or forgotten, you will have to generate a new key and copy the
66corresponding public key to other machines. 70corresponding public key to other machines.
67.Pp 71.Pp
68There is also a comment field in the key file that is only for 72There is also a comment field in the key file that is only for
69convenience to the user to help identify the key. The comment can 73convenience to the user to help identify the key.
70tell what the key is for, or whatever is useful. The comment is 74The comment can tell what the key is for, or whatever is useful.
71initialized to 75The comment is initialized to
72.Dq user@host 76.Dq user@host
73when the key is created, but can be changed using the 77when the key is created, but can be changed using the
74.Fl c 78.Fl c
@@ -77,10 +81,11 @@ option.
77The options are as follows: 81The options are as follows:
78.Bl -tag -width Ds 82.Bl -tag -width Ds
79.It Fl b Ar bits 83.It Fl b Ar bits
80Specifies the number of bits in the key to create. Minimum is 512 84Specifies the number of bits in the key to create.
81bits. Generally 1024 bits is considered sufficient, and key sizes 85Minimum is 512 bits.
82above that no longer improve security but make things slower. The 86Generally 1024 bits is considered sufficient, and key sizes
83default is 1024 bits. 87above that no longer improve security but make things slower.
88The default is 1024 bits.
84.It Fl c 89.It Fl c
85Requests changing the comment in the private and public key files. 90Requests changing the comment in the private and public key files.
86The program will prompt for the file containing the private keys, for 91The program will prompt for the file containing the private keys, for
@@ -91,7 +96,8 @@ Specifies the filename of the key file.
91Show fingerprint of specified private or public key file. 96Show fingerprint of specified private or public key file.
92.It Fl p 97.It Fl p
93Requests changing the passphrase of a private key file instead of 98Requests changing the passphrase of a private key file instead of
94creating a new private key. The program will prompt for the file 99creating a new private key.
100The program will prompt for the file
95containing the private key, for the old passphrase, and twice for the 101containing the private key, for the old passphrase, and twice for the
96new passphrase. 102new passphrase.
97.It Fl q 103.It Fl q
@@ -110,28 +116,30 @@ Provides the (old) passphrase.
110.Sh FILES 116.Sh FILES
111.Bl -tag -width Ds 117.Bl -tag -width Ds
112.It Pa $HOME/.ssh/identity 118.It Pa $HOME/.ssh/identity
113Contains the RSA authentication identity of the user. This file 119Contains the RSA authentication identity of the user.
114should not be readable by anyone but the user. It is possible to 120This file should not be readable by anyone but the user.
121It is possible to
115specify a passphrase when generating the key; that passphrase will be 122specify a passphrase when generating the key; that passphrase will be
116used to encrypt the private part of this file using 3DES. This file 123used to encrypt the private part of this file using 3DES.
117is not automatically accessed by 124This file is not automatically accessed by
118.Nm 125.Nm
119but it is offered as the default file for the private key. 126but it is offered as the default file for the private key.
120.It Pa $HOME/.ssh/identity.pub 127.It Pa $HOME/.ssh/identity.pub
121Contains the public key for authentication. The contents of this file 128Contains the public key for authentication.
122should be added to 129The contents of this file should be added to
123.Pa $HOME/.ssh/authorized_keys 130.Pa $HOME/.ssh/authorized_keys
124on all machines 131on all machines
125where you wish to log in using RSA authentication. There is no 132where you wish to log in using RSA authentication.
126need to keep the contents of this file secret. 133There is no need to keep the contents of this file secret.
127.Sh AUTHOR 134.Sh AUTHOR
128Tatu Ylonen <ylo@cs.hut.fi> 135Tatu Ylonen <ylo@cs.hut.fi>
129.Pp 136.Pp
130OpenSSH 137OpenSSH
131is a derivative of the original (free) ssh 1.2.12 release, but with bugs 138is a derivative of the original (free) ssh 1.2.12 release, but with bugs
132removed and newer features re-added. Rapidly after the 1.2.12 release, 139removed and newer features re-added.
133newer versions bore successively more restrictive licenses. This version 140Rapidly after the 1.2.12 release,
134of OpenSSH 141newer versions bore successively more restrictive licenses.
142This version of OpenSSH
135.Bl -bullet 143.Bl -bullet
136.It 144.It
137has all components of a restrictive nature (i.e., patents, see 145has all components of a restrictive nature (i.e., patents, see
diff --git a/ssh.1 b/ssh.1
index 0116977b6..eba0e0f93 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.19 2000/03/17 12:40:17 damien Exp $ 12.\" $Id: ssh.1,v 1.20 2000/03/26 03:04:54 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSH 1 15.Dt SSH 1
@@ -287,8 +287,8 @@ host key is not known or has changed.
287.Sh OPTIONS 287.Sh OPTIONS
288.Bl -tag -width Ds 288.Bl -tag -width Ds
289.It Fl a 289.It Fl a
290Disables forwarding of the authentication agent connection. This may 290Disables forwarding of the authentication agent connection.
291also be specified on a per-host basis in the configuration file. 291This may also be specified on a per-host basis in the configuration file.
292.It Fl c Ar blowfish|3des 292.It Fl c Ar blowfish|3des
293Selects the cipher to use for encrypting the session. 293Selects the cipher to use for encrypting the session.
294.Ar 3des 294.Ar 3des
@@ -342,8 +342,8 @@ It is possible to have multiple
342options (and multiple identities specified in 342options (and multiple identities specified in
343configuration files). 343configuration files).
344.It Fl k 344.It Fl k
345Disables forwarding of Kerberos tickets and AFS tokens. This may 345Disables forwarding of Kerberos tickets and AFS tokens.
346also be specified on a per-host basis in the configuration file. 346This may also be specified on a per-host basis in the configuration file.
347.It Fl l Ar login_name 347.It Fl l Ar login_name
348Specifies the user to log in as on the remote machine. 348Specifies the user to log in as on the remote machine.
349This also may be specified on a per-host basis in the configuration file. 349This also may be specified on a per-host basis in the configuration file.
@@ -390,7 +390,7 @@ Causes all warning and diagnostic messages to be suppressed.
390Only fatal errors are displayed. 390Only fatal errors are displayed.
391.It Fl t 391.It Fl t
392Force pseudo-tty allocation. 392Force pseudo-tty allocation.
393This can be used to execute arbitary 393This can be used to execute arbitrary
394screen-based programs on a remote machine, which can be very useful, 394screen-based programs on a remote machine, which can be very useful,
395e.g., when implementing menu services. 395e.g., when implementing menu services.
396.It Fl v 396.It Fl v
@@ -514,8 +514,8 @@ The host is the
514argument given on the command line (i.e., the name is not converted to 514argument given on the command line (i.e., the name is not converted to
515a canonicalized host name before matching). 515a canonicalized host name before matching).
516.It Cm AFSTokenPassing 516.It Cm AFSTokenPassing
517Specifies whether to pass AFS tokens to remote host. The argument to 517Specifies whether to pass AFS tokens to remote host.
518this keyword must be 518The argument to this keyword must be
519.Dq yes 519.Dq yes
520or 520or
521.Dq no . 521.Dq no .
@@ -534,7 +534,8 @@ If this flag is set to
534.Dq yes , 534.Dq yes ,
535ssh will additionally check the host ip address in the 535ssh will additionally check the host ip address in the
536.Pa known_hosts 536.Pa known_hosts
537file. This allows ssh to detect if a host key changed due to DNS spoofing. 537file.
538This allows ssh to detect if a host key changed due to DNS spoofing.
538If the option is set to 539If the option is set to
539.Dq no , 540.Dq no ,
540the check will not be executed. 541the check will not be executed.
@@ -645,7 +646,7 @@ If they are sent, death of the connection or crash of one
645of the machines will be properly noticed. 646of the machines will be properly noticed.
646However, this means that 647However, this means that
647connections will die if the route is down temporarily, and some people 648connections will die if the route is down temporarily, and some people
648find it annoying. 649find it annoying.
649.Pp 650.Pp
650The default is 651The default is
651.Dq yes 652.Dq yes
@@ -657,15 +658,15 @@ To disable keepalives, the value should be set to
657.Dq no 658.Dq no
658in both the server and the client configuration files. 659in both the server and the client configuration files.
659.It Cm KerberosAuthentication 660.It Cm KerberosAuthentication
660Specifies whether Kerberos authentication will be used. The argument to 661Specifies whether Kerberos authentication will be used.
661this keyword must be 662The argument to this keyword must be
662.Dq yes 663.Dq yes
663or 664or
664.Dq no . 665.Dq no .
665.It Cm KerberosTgtPassing 666.It Cm KerberosTgtPassing
666Specifies whether a Kerberos TGT will be forwarded to the server. This 667Specifies whether a Kerberos TGT will be forwarded to the server.
667will only work if the Kerberos server is actually an AFS kaserver. The 668This will only work if the Kerberos server is actually an AFS kaserver.
668argument to this keyword must be 669The argument to this keyword must be
669.Dq yes 670.Dq yes
670or 671or
671.Dq no . 672.Dq no .
@@ -684,8 +685,9 @@ The possible values are:
684QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. 685QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
685The default is INFO. 686The default is INFO.
686.It Cm NumberOfPasswordPrompts 687.It Cm NumberOfPasswordPrompts
687Specifies the number of password prompts before giving up. The 688Specifies the number of password prompts before giving up.
688argument to this keyword must be an integer. Default is 3. 689The argument to this keyword must be an integer.
690Default is 3.
689.It Cm PasswordAuthentication 691.It Cm PasswordAuthentication
690Specifies whether to use password authentication. 692Specifies whether to use password authentication.
691The argument to this keyword must be 693The argument to this keyword must be
diff --git a/ssh.c b/ssh.c
index bada8e189..faba54ec1 100644
--- a/ssh.c
+++ b/ssh.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$Id: ssh.c,v 1.21 2000/03/09 10:27:52 damien Exp $"); 14RCSID("$Id: ssh.c,v 1.22 2000/03/26 03:04:54 damien Exp $");
15 15
16#include "xmalloc.h" 16#include "xmalloc.h"
17#include "ssh.h" 17#include "ssh.h"
@@ -181,6 +181,7 @@ main(int ac, char **av)
181 struct stat st; 181 struct stat st;
182 struct passwd *pw, pwcopy; 182 struct passwd *pw, pwcopy;
183 int interactive = 0, dummy; 183 int interactive = 0, dummy;
184 int have_pty = 0;
184 uid_t original_effective_uid; 185 uid_t original_effective_uid;
185 int plen; 186 int plen;
186 187
@@ -618,9 +619,6 @@ main(int ac, char **av)
618 if (host_private_key_loaded) 619 if (host_private_key_loaded)
619 RSA_free(host_private_key); /* Destroys contents safely */ 620 RSA_free(host_private_key); /* Destroys contents safely */
620 621
621 /* Close connection cleanly after attack. */
622 cipher_attack_detected = packet_disconnect;
623
624 /* Enable compression if requested. */ 622 /* Enable compression if requested. */
625 if (options.compression) { 623 if (options.compression) {
626 debug("Requesting compression at level %d.", options.compression_level); 624 debug("Requesting compression at level %d.", options.compression_level);
@@ -672,9 +670,10 @@ main(int ac, char **av)
672 670
673 /* Read response from the server. */ 671 /* Read response from the server. */
674 type = packet_read(&plen); 672 type = packet_read(&plen);
675 if (type == SSH_SMSG_SUCCESS) 673 if (type == SSH_SMSG_SUCCESS) {
676 interactive = 1; 674 interactive = 1;
677 else if (type == SSH_SMSG_FAILURE) 675 have_pty = 1;
676 } else if (type == SSH_SMSG_FAILURE)
678 log("Warning: Remote host failed or refused to allocate a pseudo tty."); 677 log("Warning: Remote host failed or refused to allocate a pseudo tty.");
679 else 678 else
680 packet_disconnect("Protocol error waiting for pty request response."); 679 packet_disconnect("Protocol error waiting for pty request response.");
@@ -802,7 +801,7 @@ main(int ac, char **av)
802 } 801 }
803 802
804 /* Enter the interactive session. */ 803 /* Enter the interactive session. */
805 exit_status = client_loop(tty_flag, tty_flag ? options.escape_char : -1); 804 exit_status = client_loop(have_pty, tty_flag ? options.escape_char : -1);
806 805
807 /* Close the connection to the remote host. */ 806 /* Close the connection to the remote host. */
808 packet_close(); 807 packet_close();
diff --git a/ssh.h b/ssh.h
index ee6e3c1f1..8bd708150 100644
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@
13 * 13 *
14 */ 14 */
15 15
16/* RCSID("$Id: ssh.h,v 1.27 2000/03/09 10:27:52 damien Exp $"); */ 16/* RCSID("$Id: ssh.h,v 1.28 2000/03/26 03:04:54 damien Exp $"); */
17 17
18#ifndef SSH_H 18#ifndef SSH_H
19#define SSH_H 19#define SSH_H
@@ -338,8 +338,7 @@ int auth_rhosts(struct passwd * pw, const char *client_user);
338 * its host key. Returns true if authentication succeeds. 338 * its host key. Returns true if authentication succeeds.
339 */ 339 */
340int 340int
341auth_rhosts_rsa(struct passwd * pw, const char *client_user, 341auth_rhosts_rsa(struct passwd * pw, const char *client_user, RSA* client_host_key);
342 BIGNUM * client_host_key_e, BIGNUM * client_host_key_n);
343 342
344/* 343/*
345 * Tries to authenticate the user using password. Returns true if 344 * Tries to authenticate the user using password. Returns true if
@@ -388,40 +387,11 @@ int get_local_port(void);
388 387
389 388
390/* 389/*
391 * Tries to match the host name (which must be in all lowercase) against the
392 * comma-separated sequence of subpatterns (each possibly preceded by ! to
393 * indicate negation). Returns true if there is a positive match; zero
394 * otherwise.
395 */
396int match_hostname(const char *host, const char *pattern, unsigned int len);
397
398/*
399 * Checks whether the given host is already in the list of our known hosts.
400 * Returns HOST_OK if the host is known and has the specified key, HOST_NEW
401 * if the host is not known, and HOST_CHANGED if the host is known but used
402 * to have a different host key. The host must be in all lowercase.
403 */
404typedef enum {
405 HOST_OK, HOST_NEW, HOST_CHANGED
406} HostStatus;
407HostStatus
408check_host_in_hostfile(const char *filename, const char *host,
409 BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn);
410
411/*
412 * Appends an entry to the host file. Returns false if the entry could not
413 * be appended.
414 */
415int
416add_host_to_hostfile(const char *filename, const char *host,
417 BIGNUM * e, BIGNUM * n);
418
419/*
420 * Performs the RSA authentication challenge-response dialog with the client, 390 * Performs the RSA authentication challenge-response dialog with the client,
421 * and returns true (non-zero) if the client gave the correct answer to our 391 * and returns true (non-zero) if the client gave the correct answer to our
422 * challenge; returns zero if the client gives a wrong answer. 392 * challenge; returns zero if the client gives a wrong answer.
423 */ 393 */
424int auth_rsa_challenge_dialog(BIGNUM * e, BIGNUM * n); 394int auth_rsa_challenge_dialog(RSA *pk);
425 395
426/* 396/*
427 * Reads a passphrase from /dev/tty with echo turned off. Returns the 397 * Reads a passphrase from /dev/tty with echo turned off. Returns the
diff --git a/sshconnect.c b/sshconnect.c
index 910548fac..d64c0e2c0 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -8,15 +8,19 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$OpenBSD: sshconnect.c,v 1.57 2000/03/16 20:56:14 markus Exp $"); 11RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $");
12 12
13#ifdef HAVE_OPENSSL 13#ifdef HAVE_OPENSSL
14#include <openssl/bn.h> 14#include <openssl/rsa.h>
15#include <openssl/dsa.h>
15#include <openssl/md5.h> 16#include <openssl/md5.h>
17#include <openssl/bn.h>
16#endif 18#endif
17#ifdef HAVE_SSL 19#ifdef HAVE_SSL
18#include <ssl/bn.h> 20#include <ssl/rsa.h>
21#include <ssl/dsa.h>
19#include <ssl/md5.h> 22#include <ssl/md5.h>
23#include <ssl/bn.h>
20#endif 24#endif
21 25
22#include "xmalloc.h" 26#include "xmalloc.h"
@@ -29,7 +33,8 @@ RCSID("$OpenBSD: sshconnect.c,v 1.57 2000/03/16 20:56:14 markus Exp $");
29#include "uidswap.h" 33#include "uidswap.h"
30#include "compat.h" 34#include "compat.h"
31#include "readconf.h" 35#include "readconf.h"
32#include "fingerprint.h" 36#include "key.h"
37#include "hostfile.h"
33 38
34/* Session id for the current session. */ 39/* Session id for the current session. */
35unsigned char session_id[16]; 40unsigned char session_id[16];
@@ -1073,9 +1078,9 @@ read_yes_or_no(const char *prompt, int defval)
1073 */ 1078 */
1074 1079
1075void 1080void
1076check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) 1081check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1077{ 1082{
1078 RSA *file_key; 1083 Key *file_key;
1079 char *ip = NULL; 1084 char *ip = NULL;
1080 char hostline[1000], *hostp; 1085 char hostline[1000], *hostp;
1081 HostStatus host_status; 1086 HostStatus host_status;
@@ -1129,47 +1134,34 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
1129 * Store the host key from the known host file in here so that we can 1134 * Store the host key from the known host file in here so that we can
1130 * compare it with the key for the IP address. 1135 * compare it with the key for the IP address.
1131 */ 1136 */
1132 file_key = RSA_new(); 1137 file_key = key_new(host_key->type);
1133 file_key->n = BN_new();
1134 file_key->e = BN_new();
1135 1138
1136 /* 1139 /*
1137 * Check if the host key is present in the user\'s list of known 1140 * Check if the host key is present in the user\'s list of known
1138 * hosts or in the systemwide list. 1141 * hosts or in the systemwide list.
1139 */ 1142 */
1140 host_status = check_host_in_hostfile(options.user_hostfile, host, 1143 host_status = check_host_in_hostfile(options.user_hostfile, host, host_key, file_key);
1141 host_key->e, host_key->n,
1142 file_key->e, file_key->n);
1143 if (host_status == HOST_NEW) 1144 if (host_status == HOST_NEW)
1144 host_status = check_host_in_hostfile(options.system_hostfile, host, 1145 host_status = check_host_in_hostfile(options.system_hostfile, host, host_key, file_key);
1145 host_key->e, host_key->n,
1146 file_key->e, file_key->n);
1147 /* 1146 /*
1148 * Also perform check for the ip address, skip the check if we are 1147 * Also perform check for the ip address, skip the check if we are
1149 * localhost or the hostname was an ip address to begin with 1148 * localhost or the hostname was an ip address to begin with
1150 */ 1149 */
1151 if (options.check_host_ip && !local && strcmp(host, ip)) { 1150 if (options.check_host_ip && !local && strcmp(host, ip)) {
1152 RSA *ip_key = RSA_new(); 1151 Key *ip_key = key_new(host_key->type);
1153 ip_key->n = BN_new(); 1152 ip_status = check_host_in_hostfile(options.user_hostfile, ip, host_key, ip_key);
1154 ip_key->e = BN_new();
1155 ip_status = check_host_in_hostfile(options.user_hostfile, ip,
1156 host_key->e, host_key->n,
1157 ip_key->e, ip_key->n);
1158 1153
1159 if (ip_status == HOST_NEW) 1154 if (ip_status == HOST_NEW)
1160 ip_status = check_host_in_hostfile(options.system_hostfile, ip, 1155 ip_status = check_host_in_hostfile(options.system_hostfile, ip, host_key, ip_key);
1161 host_key->e, host_key->n,
1162 ip_key->e, ip_key->n);
1163 if (host_status == HOST_CHANGED && 1156 if (host_status == HOST_CHANGED &&
1164 (ip_status != HOST_CHANGED || 1157 (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
1165 (BN_cmp(ip_key->e, file_key->e) || BN_cmp(ip_key->n, file_key->n))))
1166 host_ip_differ = 1; 1158 host_ip_differ = 1;
1167 1159
1168 RSA_free(ip_key); 1160 key_free(ip_key);
1169 } else 1161 } else
1170 ip_status = host_status; 1162 ip_status = host_status;
1171 1163
1172 RSA_free(file_key); 1164 key_free(file_key);
1173 1165
1174 switch (host_status) { 1166 switch (host_status) {
1175 case HOST_OK: 1167 case HOST_OK:
@@ -1177,8 +1169,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
1177 debug("Host '%.200s' is known and matches the host key.", host); 1169 debug("Host '%.200s' is known and matches the host key.", host);
1178 if (options.check_host_ip) { 1170 if (options.check_host_ip) {
1179 if (ip_status == HOST_NEW) { 1171 if (ip_status == HOST_NEW) {
1180 if (!add_host_to_hostfile(options.user_hostfile, ip, 1172 if (!add_host_to_hostfile(options.user_hostfile, ip, host_key))
1181 host_key->e, host_key->n))
1182 log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).", 1173 log("Failed to add the host key for IP address '%.30s' to the list of known hosts (%.30s).",
1183 ip, options.user_hostfile); 1174 ip, options.user_hostfile);
1184 else 1175 else
@@ -1198,12 +1189,12 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
1198 } else if (options.strict_host_key_checking == 2) { 1189 } else if (options.strict_host_key_checking == 2) {
1199 /* The default */ 1190 /* The default */
1200 char prompt[1024]; 1191 char prompt[1024];
1201 char *fp = fingerprint(host_key->e, host_key->n); 1192 char *fp = key_fingerprint(host_key);
1202 snprintf(prompt, sizeof(prompt), 1193 snprintf(prompt, sizeof(prompt),
1203 "The authenticity of host '%.200s' can't be established.\n" 1194 "The authenticity of host '%.200s' can't be established.\n"
1204 "Key fingerprint is %d %s.\n" 1195 "Key fingerprint is %s.\n"
1205 "Are you sure you want to continue connecting (yes/no)? ", 1196 "Are you sure you want to continue connecting (yes/no)? ",
1206 host, BN_num_bits(host_key->n), fp); 1197 host, fp);
1207 if (!read_yes_or_no(prompt, -1)) 1198 if (!read_yes_or_no(prompt, -1))
1208 fatal("Aborted by user!\n"); 1199 fatal("Aborted by user!\n");
1209 } 1200 }
@@ -1214,8 +1205,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
1214 hostp = host; 1205 hostp = host;
1215 1206
1216 /* If not in strict mode, add the key automatically to the local known_hosts file. */ 1207 /* If not in strict mode, add the key automatically to the local known_hosts file. */
1217 if (!add_host_to_hostfile(options.user_hostfile, hostp, 1208 if (!add_host_to_hostfile(options.user_hostfile, hostp, host_key))
1218 host_key->e, host_key->n))
1219 log("Failed to add the host to the list of known hosts (%.500s).", 1209 log("Failed to add the host to the list of known hosts (%.500s).",
1220 options.user_hostfile); 1210 options.user_hostfile);
1221 else 1211 else
@@ -1283,6 +1273,14 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
1283 if (options.check_host_ip) 1273 if (options.check_host_ip)
1284 xfree(ip); 1274 xfree(ip);
1285} 1275}
1276void
1277check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
1278{
1279 Key k;
1280 k.type = KEY_RSA;
1281 k.rsa = host_key;
1282 check_host_key(host, hostaddr, &k);
1283}
1286 1284
1287/* 1285/*
1288 * SSH1 key exchange 1286 * SSH1 key exchange
@@ -1358,7 +1356,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
1358 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, 1356 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
1359 SSH_SMSG_PUBLIC_KEY); 1357 SSH_SMSG_PUBLIC_KEY);
1360 1358
1361 check_host_key(host, hostaddr, host_key); 1359 check_rsa_host_key(host, hostaddr, host_key);
1362 1360
1363 client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; 1361 client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
1364 1362
@@ -1617,7 +1615,6 @@ ssh_userauth(int host_key_valid, RSA *own_host_key,
1617 fatal("Permission denied."); 1615 fatal("Permission denied.");
1618 /* NOTREACHED */ 1616 /* NOTREACHED */
1619} 1617}
1620
1621/* 1618/*
1622 * Starts a dialog with the server, and authenticates the current user on the 1619 * Starts a dialog with the server, and authenticates the current user on the
1623 * server. This does not need any extra privileges. The basic connection 1620 * server. This does not need any extra privileges. The basic connection
@@ -1648,6 +1645,7 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost,
1648 ssh_kex(host, hostaddr); 1645 ssh_kex(host, hostaddr);
1649 if (supported_authentications == 0) 1646 if (supported_authentications == 0)
1650 fatal("supported_authentications == 0."); 1647 fatal("supported_authentications == 0.");
1648
1651 /* authenticate user */ 1649 /* authenticate user */
1652 ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); 1650 ssh_userauth(host_key_valid, own_host_key, original_real_uid, host);
1653} 1651}
diff --git a/sshd.8 b/sshd.8
index a20490188..3c24210bd 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.14 2000/03/17 12:40:18 damien Exp $ 12.\" $Id: sshd.8,v 1.15 2000/03/26 03:04:55 damien Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SSHD 8 15.Dt SSHD 8
@@ -33,39 +33,48 @@
33.Xr ssh 1 . 33.Xr ssh 1 .
34Together these programs replace rlogin and rsh programs, and 34Together these programs replace rlogin and rsh programs, and
35provide secure encrypted communications between two untrusted hosts 35provide secure encrypted communications between two untrusted hosts
36over an insecure network. The programs are intended to be as easy to 36over an insecure network.
37The programs are intended to be as easy to
37install and use as possible. 38install and use as possible.
38.Pp 39.Pp
39.Nm 40.Nm
40is the daemon that listens for connections from clients. It is 41is the daemon that listens for connections from clients.
41normally started at boot from 42It is normally started at boot from
42.Pa /etc/rc . 43.Pa /etc/rc .
43It forks a new 44It forks a new
44daemon for each incoming connection. The forked daemons handle 45daemon for each incoming connection.
46The forked daemons handle
45key exchange, encryption, authentication, command execution, 47key exchange, encryption, authentication, command execution,
46and data exchange. 48and data exchange.
47.Pp 49.Pp
48.Nm 50.Nm
49works as follows. Each host has a host-specific RSA key 51works as follows.
50(normally 1024 bits) used to identify the host. Additionally, when 52Each host has a host-specific RSA key
53(normally 1024 bits) used to identify the host.
54Additionally, when
51the daemon starts, it generates a server RSA key (normally 768 bits). 55the daemon starts, it generates a server RSA key (normally 768 bits).
52This key is normally regenerated every hour if it has been used, and 56This key is normally regenerated every hour if it has been used, and
53is never stored on disk. 57is never stored on disk.
54.Pp 58.Pp
55Whenever a client connects the daemon, the daemon sends its host 59Whenever a client connects the daemon, the daemon sends its host
56and server public keys to the client. The client compares the 60and server public keys to the client.
61The client compares the
57host key against its own database to verify that it has not changed. 62host key against its own database to verify that it has not changed.
58The client then generates a 256 bit random number. It encrypts this 63The client then generates a 256 bit random number.
64It encrypts this
59random number using both the host key and the server key, and sends 65random number using both the host key and the server key, and sends
60the encrypted number to the server. Both sides then start to use this 66the encrypted number to the server.
67Both sides then start to use this
61random number as a session key which is used to encrypt all further 68random number as a session key which is used to encrypt all further
62communications in the session. The rest of the session is encrypted 69communications in the session.
70The rest of the session is encrypted
63using a conventional cipher, currently Blowfish and 3DES, with 3DES 71using a conventional cipher, currently Blowfish and 3DES, with 3DES
64being is used by default. The client selects the encryption algorithm 72being is used by default.
73The client selects the encryption algorithm
65to use from those offered by the server. 74to use from those offered by the server.
66.Pp 75.Pp
67Next, the server and the client enter an authentication dialog. The 76Next, the server and the client enter an authentication dialog.
68client tries to authenticate itself using 77The client tries to authenticate itself using
69.Pa .rhosts 78.Pa .rhosts
70authentication, 79authentication,
71.Pa .rhosts 80.Pa .rhosts
@@ -75,7 +84,8 @@ based authentication.
75.Pp 84.Pp
76Rhosts authentication is normally disabled 85Rhosts authentication is normally disabled
77because it is fundamentally insecure, but can be enabled in the server 86because it is fundamentally insecure, but can be enabled in the server
78configuration file if desired. System security is not improved unless 87configuration file if desired.
88System security is not improved unless
79.Xr rshd 8 , 89.Xr rshd 8 ,
80.Xr rlogind 8 , 90.Xr rlogind 8 ,
81.Xr rexecd 8 , 91.Xr rexecd 8 ,
@@ -88,13 +98,15 @@ and
88into that machine). 98into that machine).
89.Pp 99.Pp
90If the client successfully authenticates itself, a dialog for 100If the client successfully authenticates itself, a dialog for
91preparing the session is entered. At this time the client may request 101preparing the session is entered.
102At this time the client may request
92things like allocating a pseudo-tty, forwarding X11 connections, 103things like allocating a pseudo-tty, forwarding X11 connections,
93forwarding TCP/IP connections, or forwarding the authentication agent 104forwarding TCP/IP connections, or forwarding the authentication agent
94connection over the secure channel. 105connection over the secure channel.
95.Pp 106.Pp
96Finally, the client either requests a shell or execution of a command. 107Finally, the client either requests a shell or execution of a command.
97The sides then enter session mode. In this mode, either side may send 108The sides then enter session mode.
109In this mode, either side may send
98data at any time, and such data is forwarded to/from the shell or 110data at any time, and such data is forwarded to/from the shell or
99command on the server side, and the user terminal in the client side. 111command on the server side, and the user terminal in the client side.
100.Pp 112.Pp
@@ -104,7 +116,8 @@ the client, and both sides exit.
104.Pp 116.Pp
105.Nm 117.Nm
106can be configured using command-line options or a configuration 118can be configured using command-line options or a configuration
107file. Command-line options override values specified in the 119file.
120Command-line options override values specified in the
108configuration file. 121configuration file.
109.Pp 122.Pp
110.Nm 123.Nm
@@ -117,20 +130,23 @@ The options are as follows:
117Specifies the number of bits in the server key (default 768). 130Specifies the number of bits in the server key (default 768).
118.Pp 131.Pp
119.It Fl d 132.It Fl d
120Debug mode. The server sends verbose debug output to the system 133Debug mode.
121log, and does not put itself in the background. The server also will 134The server sends verbose debug output to the system
122not fork and will only process one connection. This option is only 135log, and does not put itself in the background.
123intended for debugging for the server. 136The server also will not fork and will only process one connection.
137This option is only intended for debugging for the server.
124.It Fl f Ar configuration_file 138.It Fl f Ar configuration_file
125Specifies the name of the configuration file. The default is 139Specifies the name of the configuration file.
140The default is
126.Pa /etc/sshd_config . 141.Pa /etc/sshd_config .
127.Nm 142.Nm
128refuses to start if there is no configuration file. 143refuses to start if there is no configuration file.
129.It Fl g Ar login_grace_time 144.It Fl g Ar login_grace_time
130Gives the grace time for clients to authenticate themselves (default 145Gives the grace time for clients to authenticate themselves (default
131300 seconds). If the client fails to authenticate the user within 146300 seconds).
132this many seconds, the server disconnects and exits. A value of zero 147If the client fails to authenticate the user within
133indicates no limit. 148this many seconds, the server disconnects and exits.
149A value of zero indicates no limit.
134.It Fl h Ar host_key_file 150.It Fl h Ar host_key_file
135Specifies the file from which the host key is read (default 151Specifies the file from which the host key is read (default
136.Pa /etc/ssh_host_key ) . 152.Pa /etc/ssh_host_key ) .
@@ -145,24 +161,28 @@ is being run from inetd.
145.Nm 161.Nm
146is normally not run 162is normally not run
147from inetd because it needs to generate the server key before it can 163from inetd because it needs to generate the server key before it can
148respond to the client, and this may take tens of seconds. Clients 164respond to the client, and this may take tens of seconds.
149would have to wait too long if the key was regenerated every time. 165Clients would have to wait too long if the key was regenerated every time.
150However, with small key sizes (e.g., 512) using 166However, with small key sizes (e.g., 512) using
151.Nm 167.Nm
152from inetd may 168from inetd may
153be feasible. 169be feasible.
154.It Fl k Ar key_gen_time 170.It Fl k Ar key_gen_time
155Specifies how often the server key is regenerated (default 3600 171Specifies how often the server key is regenerated (default 3600
156seconds, or one hour). The motivation for regenerating the key fairly 172seconds, or one hour).
173The motivation for regenerating the key fairly
157often is that the key is not stored anywhere, and after about an hour, 174often is that the key is not stored anywhere, and after about an hour,
158it becomes impossible to recover the key for decrypting intercepted 175it becomes impossible to recover the key for decrypting intercepted
159communications even if the machine is cracked into or physically 176communications even if the machine is cracked into or physically
160seized. A value of zero indicates that the key will never be regenerated. 177seized.
178A value of zero indicates that the key will never be regenerated.
161.It Fl p Ar port 179.It Fl p Ar port
162Specifies the port on which the server listens for connections 180Specifies the port on which the server listens for connections
163(default 22). 181(default 22).
164.It Fl q 182.It Fl q
165Quiet mode. Nothing is sent to the system log. Normally the beginning, 183Quiet mode.
184Nothing is sent to the system log.
185Normally the beginning,
166authentication, and termination of each connection is logged. 186authentication, and termination of each connection is logged.
167.It Fl Q 187.It Fl Q
168Do not print an error message if RSA support is missing. 188Do not print an error message if RSA support is missing.
@@ -188,39 +208,43 @@ reads configuration data from
188.Pa /etc/sshd_config 208.Pa /etc/sshd_config
189(or the file specified with 209(or the file specified with
190.Fl f 210.Fl f
191on the command line). The file 211on the command line).
192contains keyword-value pairs, one per line. Lines starting with 212The file contains keyword-value pairs, one per line.
213Lines starting with
193.Ql # 214.Ql #
194and empty lines are interpreted as comments. 215and empty lines are interpreted as comments.
195.Pp 216.Pp
196The following keywords are possible. 217The following keywords are possible.
197.Bl -tag -width Ds 218.Bl -tag -width Ds
198.It Cm AFSTokenPassing 219.It Cm AFSTokenPassing
199Specifies whether an AFS token may be forwarded to the server. Default is 220Specifies whether an AFS token may be forwarded to the server.
221Default is
200.Dq yes . 222.Dq yes .
201.It Cm AllowGroups 223.It Cm AllowGroups
202This keyword can be followed by a number of group names, separated 224This keyword can be followed by a number of group names, separated
203by spaces. If specified, login is allowed only for users whose primary 225by spaces.
226If specified, login is allowed only for users whose primary
204group matches one of the patterns. 227group matches one of the patterns.
205.Ql \&* 228.Ql \&*
206and 229and
207.Ql ? 230.Ql ?
208can be used as 231can be used as
209wildcards in the patterns. Only group names are valid, a numerical group 232wildcards in the patterns.
210id isn't recognized. By default login is allowed regardless of 233Only group names are valid, a numerical group ID isn't recognized.
211the primary group. 234By default login is allowed regardless of the primary group.
212.Pp 235.Pp
213.It Cm AllowUsers 236.It Cm AllowUsers
214This keyword can be followed by a number of user names, separated 237This keyword can be followed by a number of user names, separated
215by spaces. If specified, login is allowed only for users names that 238by spaces.
239If specified, login is allowed only for users names that
216match one of the patterns. 240match one of the patterns.
217.Ql \&* 241.Ql \&*
218and 242and
219.Ql ? 243.Ql ?
220can be used as 244can be used as
221wildcards in the patterns. Only user names are valid, a numerical user 245wildcards in the patterns.
222id isn't recognized. By default login is allowed regardless of 246Only user names are valid, a numerical user ID isn't recognized.
223the user name. 247By default login is allowed regardless of the user name.
224.Pp 248.Pp
225.It Cm CheckMail 249.It Cm CheckMail
226Specifies whether 250Specifies whether
@@ -230,27 +254,27 @@ The default is
230.Dq no . 254.Dq no .
231.It Cm DenyGroups 255.It Cm DenyGroups
232This keyword can be followed by a number of group names, separated 256This keyword can be followed by a number of group names, separated
233by spaces. Users whose primary group matches one of the patterns 257by spaces.
258Users whose primary group matches one of the patterns
234aren't allowed to log in. 259aren't allowed to log in.
235.Ql \&* 260.Ql \&*
236and 261and
237.Ql ? 262.Ql ?
238can be used as 263can be used as
239wildcards in the patterns. Only group names are valid, a numerical group 264wildcards in the patterns.
240id isn't recognized. By default login is allowed regardless of 265Only group names are valid, a numerical group ID isn't recognized.
241the primary group. 266By default login is allowed regardless of the primary group.
242.Pp 267.Pp
243.It Cm DenyUsers 268.It Cm DenyUsers
244This keyword can be followed by a number of user names, separated 269This keyword can be followed by a number of user names, separated
245by spaces. Login is disallowed for user names that match 270by spaces.
246one of the patterns. 271Login is disallowed for user names that match one of the patterns.
247.Ql \&* 272.Ql \&*
248and 273and
249.Ql ? 274.Ql ?
250can be used as 275can be used as wildcards in the patterns.
251wildcards in the patterns. Only user names are valid, a numerical user 276Only user names are valid, a numerical user ID isn't recognized.
252id isn't recognized. By default login is allowed regardless of 277By default login is allowed regardless of the user name.
253the user name.
254.It Cm HostKey 278.It Cm HostKey
255Specifies the file containing the private host key (default 279Specifies the file containing the private host key (default
256.Pa /etc/ssh_host_key ) . 280.Pa /etc/ssh_host_key ) .
@@ -266,7 +290,8 @@ files will not be used in authentication.
266.Pa /etc/hosts.equiv 290.Pa /etc/hosts.equiv
267and 291and
268.Pa /etc/shosts.equiv 292.Pa /etc/shosts.equiv
269are still used. The default is 293are still used.
294The default is
270.Dq yes . 295.Dq yes .
271.It Cm IgnoreUserKnownHosts 296.It Cm IgnoreUserKnownHosts
272Specifies whether 297Specifies whether
@@ -279,10 +304,13 @@ The default is
279.Dq no . 304.Dq no .
280.It Cm KeepAlive 305.It Cm KeepAlive
281Specifies whether the system should send keepalive messages to the 306Specifies whether the system should send keepalive messages to the
282other side. If they are sent, death of the connection or crash of one 307other side.
283of the machines will be properly noticed. However, this means that 308If they are sent, death of the connection or crash of one
309of the machines will be properly noticed.
310However, this means that
284connections will die if the route is down temporarily, and some people 311connections will die if the route is down temporarily, and some people
285find it annoying. On the other hand, if keepalives are not send, 312find it annoying.
313On the other hand, if keepalives are not send,
286sessions may hang indefinitely on the server, leaving 314sessions may hang indefinitely on the server, leaving
287.Dq ghost 315.Dq ghost
288users and consuming server resources. 316users and consuming server resources.
@@ -290,25 +318,27 @@ users and consuming server resources.
290The default is 318The default is
291.Dq yes 319.Dq yes
292(to send keepalives), and the server will notice 320(to send keepalives), and the server will notice
293if the network goes down or the client host reboots. This avoids 321if the network goes down or the client host reboots.
294infinitely hanging sessions. 322This avoids infinitely hanging sessions.
295.Pp 323.Pp
296To disable keepalives, the value should be set to 324To disable keepalives, the value should be set to
297.Dq no 325.Dq no
298in both the server and the client configuration files. 326in both the server and the client configuration files.
299.It Cm KerberosAuthentication 327.It Cm KerberosAuthentication
300Specifies whether Kerberos authentication is allowed. This can 328Specifies whether Kerberos authentication is allowed.
301be in the form of a Kerberos ticket, or if 329This can be in the form of a Kerberos ticket, or if
302.Cm PasswordAuthentication 330.Cm PasswordAuthentication
303is yes, the password provided by the user will be validated through 331is yes, the password provided by the user will be validated through
304the Kerberos KDC. Default is 332the Kerberos KDC.
333Default is
305.Dq yes . 334.Dq yes .
306.It Cm KerberosOrLocalPasswd 335.It Cm KerberosOrLocalPasswd
307If set then if password authentication through Kerberos fails then 336If set then if password authentication through Kerberos fails then
308the password will be validated via any additional local mechanism 337the password will be validated via any additional local mechanism
309such as 338such as
310.Pa /etc/passwd 339.Pa /etc/passwd
311or SecurID. Default is 340or SecurID.
341Default is
312.Dq yes . 342.Dq yes .
313.It Cm KerberosTgtPassing 343.It Cm KerberosTgtPassing
314Specifies whether a Kerberos TGT may be forwarded to the server. 344Specifies whether a Kerberos TGT may be forwarded to the server.
@@ -317,15 +347,18 @@ Default is
317as this only works when the Kerberos KDC is actually an AFS kaserver. 347as this only works when the Kerberos KDC is actually an AFS kaserver.
318.It Cm KerberosTicketCleanup 348.It Cm KerberosTicketCleanup
319Specifies whether to automatically destroy the user's ticket cache 349Specifies whether to automatically destroy the user's ticket cache
320file on logout. Default is 350file on logout.
351Default is
321.Dq yes . 352.Dq yes .
322.It Cm KeyRegenerationInterval 353.It Cm KeyRegenerationInterval
323The server key is automatically regenerated after this many seconds 354The server key is automatically regenerated after this many seconds
324(if it has been used). The purpose of regeneration is to prevent 355(if it has been used).
356The purpose of regeneration is to prevent
325decrypting captured sessions by later breaking into the machine and 357decrypting captured sessions by later breaking into the machine and
326stealing the keys. The key is never stored anywhere. If the value is 358stealing the keys.
3270, the key is never regenerated. The default is 3600 359The key is never stored anywhere.
328(seconds). 360If the value is 0, the key is never regenerated.
361The default is 3600 (seconds).
329.It Cm ListenAddress 362.It Cm ListenAddress
330Specifies what local address 363Specifies what local address
331.Nm 364.Nm
@@ -337,7 +370,8 @@ Additionally, the
337options must precede this option. 370options must precede this option.
338.It Cm LoginGraceTime 371.It Cm LoginGraceTime
339The server disconnects after this time if the user has not 372The server disconnects after this time if the user has not
340successfully logged in. If the value is 0, there is no time limit. 373successfully logged in.
374If the value is 0, there is no time limit.
341The default is 600 (seconds). 375The default is 600 (seconds).
342.It Cm LogLevel 376.It Cm LogLevel
343Gives the verbosity level that is used when logging messages from 377Gives the verbosity level that is used when logging messages from
@@ -353,8 +387,8 @@ The default is
353.Dq yes . 387.Dq yes .
354.It Cm PermitEmptyPasswords 388.It Cm PermitEmptyPasswords
355When password authentication is allowed, it specifies whether the 389When password authentication is allowed, it specifies whether the
356server allows login to accounts with empty password strings. The default 390server allows login to accounts with empty password strings.
357is 391The default is
358.Dq no . 392.Dq no .
359.It Cm PermitRootLogin 393.It Cm PermitRootLogin
360Specifies whether the root can log in using 394Specifies whether the root can log in using
@@ -379,24 +413,27 @@ normally not allowed).
379.It Cm Port 413.It Cm Port
380Specifies the port number that 414Specifies the port number that
381.Nm 415.Nm
382listens on. The default is 22. 416listens on.
417The default is 22.
383Multiple options of this type are permitted. 418Multiple options of this type are permitted.
384.It Cm PrintMotd 419.It Cm PrintMotd
385Specifies whether 420Specifies whether
386.Nm 421.Nm
387should print 422should print
388.Pa /etc/motd 423.Pa /etc/motd
389when a user logs in interactively. (On some systems it is also 424when a user logs in interactively.
390printed by the shell, 425(On some systems it is also printed by the shell,
391.Pa /etc/profile , 426.Pa /etc/profile ,
392or equivalent.) The default is 427or equivalent.)
428The default is
393.Dq yes . 429.Dq yes .
394.It Cm RandomSeed 430.It Cm RandomSeed
395Obsolete. Random number generation uses other techniques. 431Obsolete.
432Random number generation uses other techniques.
396.It Cm RhostsAuthentication 433.It Cm RhostsAuthentication
397Specifies whether authentication using rhosts or /etc/hosts.equiv 434Specifies whether authentication using rhosts or /etc/hosts.equiv
398files is sufficient. Normally, this method should not be permitted 435files is sufficient.
399because it is insecure. 436Normally, this method should not be permitted because it is insecure.
400.Cm RhostsRSAAuthentication 437.Cm RhostsRSAAuthentication
401should be used 438should be used
402instead, because it performs RSA-based host authentication in addition 439instead, because it performs RSA-based host authentication in addition
@@ -405,18 +442,21 @@ The default is
405.Dq no . 442.Dq no .
406.It Cm RhostsRSAAuthentication 443.It Cm RhostsRSAAuthentication
407Specifies whether rhosts or /etc/hosts.equiv authentication together 444Specifies whether rhosts or /etc/hosts.equiv authentication together
408with successful RSA host authentication is allowed. The default is 445with successful RSA host authentication is allowed.
446The default is
409.Dq no . 447.Dq no .
410.It Cm RSAAuthentication 448.It Cm RSAAuthentication
411Specifies whether pure RSA authentication is allowed. The default is 449Specifies whether pure RSA authentication is allowed.
450The default is
412.Dq yes . 451.Dq yes .
413.It Cm ServerKeyBits 452.It Cm ServerKeyBits
414Defines the number of bits in the server key. The minimum value is 453Defines the number of bits in the server key.
415512, and the default is 768. 454The minimum value is 512, and the default is 768.
416.It Cm SkeyAuthentication 455.It Cm SkeyAuthentication
417Specifies whether 456Specifies whether
418.Xr skey 1 457.Xr skey 1
419authentication is allowed. The default is 458authentication is allowed.
459The default is
420.Dq yes . 460.Dq yes .
421Note that s/key authentication is enabled only if 461Note that s/key authentication is enabled only if
422.Cm PasswordAuthentication 462.Cm PasswordAuthentication
@@ -425,29 +465,34 @@ is allowed, too.
425Specifies whether 465Specifies whether
426.Nm 466.Nm
427should check file modes and ownership of the 467should check file modes and ownership of the
428user's files and home directory before accepting login. This 468user's files and home directory before accepting login.
429is normally desirable because novices sometimes accidentally leave their 469This is normally desirable because novices sometimes accidentally leave their
430directory or files world-writable. The default is 470directory or files world-writable.
471The default is
431.Dq yes . 472.Dq yes .
432.It Cm SyslogFacility 473.It Cm SyslogFacility
433Gives the facility code that is used when logging messages from 474Gives the facility code that is used when logging messages from
434.Nm sshd . 475.Nm sshd .
435The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, 476The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
436LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. 477LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
478The default is AUTH.
437.It Cm UseLogin 479.It Cm UseLogin
438Specifies whether 480Specifies whether
439.Xr login 1 481.Xr login 1
440is used. The default is 482is used.
483The default is
441.Dq no . 484.Dq no .
442.It Cm X11DisplayOffset 485.It Cm X11DisplayOffset
443Specifies the first display number available for 486Specifies the first display number available for
444.Nm sshd Ns 's 487.Nm sshd Ns 's
445X11 forwarding. This prevents 488X11 forwarding.
489This prevents
446.Nm 490.Nm
447from interfering with real X11 servers. 491from interfering with real X11 servers.
448The default is 10. 492The default is 10.
449.It Cm X11Forwarding 493.It Cm X11Forwarding
450Specifies whether X11 forwarding is permitted. The default is 494Specifies whether X11 forwarding is permitted.
495The default is
451.Dq no . 496.Dq no .
452Note that disabling X11 forwarding does not improve security in any 497Note that disabling X11 forwarding does not improve security in any
453way, as users can always install their own forwarders. 498way, as users can always install their own forwarders.
@@ -489,7 +534,8 @@ If
489exists, runs it; else if 534exists, runs it; else if
490.Pa /etc/sshrc 535.Pa /etc/sshrc
491exists, runs 536exists, runs
492it; otherwise runs xauth. The 537it; otherwise runs xauth.
538The
493.Dq rc 539.Dq rc
494files are given the X11 540files are given the X11
495authentication protocol and cookie in standard input. 541authentication protocol and cookie in standard input.
@@ -500,12 +546,15 @@ Runs user's shell or command.
500The 546The
501.Pa $HOME/.ssh/authorized_keys 547.Pa $HOME/.ssh/authorized_keys
502file lists the RSA keys that are 548file lists the RSA keys that are
503permitted for RSA authentication. Each line of the file contains one 549permitted for RSA authentication.
550Each line of the file contains one
504key (empty lines and lines starting with a 551key (empty lines and lines starting with a
505.Ql # 552.Ql #
506are ignored as 553are ignored as
507comments). Each line consists of the following fields, separated by 554comments).
508spaces: options, bits, exponent, modulus, comment. The options field 555Each line consists of the following fields, separated by
556spaces: options, bits, exponent, modulus, comment.
557The options field
509is optional; its presence is determined by whether the line starts 558is optional; its presence is determined by whether the line starts
510with a number or not (the option field never starts with a number). 559with a number or not (the option field never starts with a number).
511The bits, exponent, modulus and comment fields give the RSA key; the 560The bits, exponent, modulus and comment fields give the RSA key; the
@@ -513,47 +562,58 @@ comment field is not used for anything (but may be convenient for the
513user to identify the key). 562user to identify the key).
514.Pp 563.Pp
515Note that lines in this file are usually several hundred bytes long 564Note that lines in this file are usually several hundred bytes long
516(because of the size of the RSA key modulus). You don't want to type 565(because of the size of the RSA key modulus).
517them in; instead, copy the 566You don't want to type them in; instead, copy the
518.Pa identity.pub 567.Pa identity.pub
519file and edit it. 568file and edit it.
520.Pp 569.Pp
521The options (if present) consists of comma-separated option 570The options (if present) consists of comma-separated option
522specifications. No spaces are permitted, except within double quotes. 571specifications.
572No spaces are permitted, except within double quotes.
523The following option specifications are supported: 573The following option specifications are supported:
524.Bl -tag -width Ds 574.Bl -tag -width Ds
525.It Cm from="pattern-list" 575.It Cm from="pattern-list"
526Specifies that in addition to RSA authentication, the canonical name 576Specifies that in addition to RSA authentication, the canonical name
527of the remote host must be present in the comma-separated list of 577of the remote host must be present in the comma-separated list of
528patterns ('*' and '?' serve as wildcards). The list may also contain 578patterns
529patterns negated by prefixing them with '!'; if the canonical host 579.Pf ( Ql *
530name matches a negated pattern, the key is not accepted. The purpose 580and
581.Ql ?
582serve as wildcards).
583The list may also contain
584patterns negated by prefixing them with
585.Ql ! ;
586if the canonical host name matches a negated pattern, the key is not accepted.
587The purpose
531of this option is to optionally increase security: RSA authentication 588of this option is to optionally increase security: RSA authentication
532by itself does not trust the network or name servers or anything (but 589by itself does not trust the network or name servers or anything (but
533the key); however, if somebody somehow steals the key, the key 590the key); however, if somebody somehow steals the key, the key
534permits an intruder to log in from anywhere in the world. This 591permits an intruder to log in from anywhere in the world.
535additional option makes using a stolen key more difficult (name 592This additional option makes using a stolen key more difficult (name
536servers and/or routers would have to be compromised in addition to 593servers and/or routers would have to be compromised in addition to
537just the key). 594just the key).
538.It Cm command="command" 595.It Cm command="command"
539Specifies that the command is executed whenever this key is used for 596Specifies that the command is executed whenever this key is used for
540authentication. The command supplied by the user (if any) is ignored. 597authentication.
598The command supplied by the user (if any) is ignored.
541The command is run on a pty if the connection requests a pty; 599The command is run on a pty if the connection requests a pty;
542otherwise it is run without a tty. A quote may be included in the 600otherwise it is run without a tty.
543command by quoting it with a backslash. This option might be useful 601A quote may be included in the command by quoting it with a backslash.
544to restrict certain RSA keys to perform just a specific operation. An 602This option might be useful
545example might be a key that permits remote backups but nothing 603to restrict certain RSA keys to perform just a specific operation.
546else. Notice that the client may specify TCP/IP and/or X11 604An example might be a key that permits remote backups but nothing else.
605Notice that the client may specify TCP/IP and/or X11
547forwardings unless they are explicitly prohibited. 606forwardings unless they are explicitly prohibited.
548.It Cm environment="NAME=value" 607.It Cm environment="NAME=value"
549Specifies that the string is to be added to the environment when 608Specifies that the string is to be added to the environment when
550logging in using this key. Environment variables set this way 609logging in using this key.
551override other default environment values. Multiple options of this 610Environment variables set this way
552type are permitted. 611override other default environment values.
612Multiple options of this type are permitted.
553.It Cm no-port-forwarding 613.It Cm no-port-forwarding
554Forbids TCP/IP forwarding when this key is used for authentication. 614Forbids TCP/IP forwarding when this key is used for authentication.
555Any port forward requests by the client will return an error. This 615Any port forward requests by the client will return an error.
556might be used, e.g., in connection with the 616This might be used, e.g., in connection with the
557.Cm command 617.Cm command
558option. 618option.
559.It Cm no-X11-forwarding 619.It Cm no-X11-forwarding
@@ -576,19 +636,21 @@ The
576.Pa /etc/ssh_known_hosts 636.Pa /etc/ssh_known_hosts
577and 637and
578.Pa $HOME/.ssh/known_hosts 638.Pa $HOME/.ssh/known_hosts
579files contain host public keys for all known hosts. The global file should 639files contain host public keys for all known hosts.
580be prepared by the admistrator (optional), and the per-user file is 640The global file should
641be prepared by the administrator (optional), and the per-user file is
581maintained automatically: whenever the user connects an unknown host 642maintained automatically: whenever the user connects an unknown host
582its key is added to the per-user file. 643its key is added to the per-user file.
583.Pp 644.Pp
584Each line in these files contains the following fields: hostnames, 645Each line in these files contains the following fields: hostnames,
585bits, exponent, modulus, comment. The fields are separated by spaces. 646bits, exponent, modulus, comment.
647The fields are separated by spaces.
586.Pp 648.Pp
587Hostnames is a comma-separated list of patterns ('*' and '?' act as 649Hostnames is a comma-separated list of patterns ('*' and '?' act as
588wildcards); each pattern in turn is matched against the canonical host 650wildcards); each pattern in turn is matched against the canonical host
589name (when authenticating a client) or against the user-supplied 651name (when authenticating a client) or against the user-supplied
590name (when authenticating a server). A pattern may also be preceded 652name (when authenticating a server).
591by 653A pattern may also be preceded by
592.Ql ! 654.Ql !
593to indicate negation: if the host name matches a negated 655to indicate negation: if the host name matches a negated
594pattern, it is not accepted (by that line) even if it matched another 656pattern, it is not accepted (by that line) even if it matched another
@@ -604,10 +666,13 @@ Lines starting with
604and empty lines are ignored as comments. 666and empty lines are ignored as comments.
605.Pp 667.Pp
606When performing host authentication, authentication is accepted if any 668When performing host authentication, authentication is accepted if any
607matching line has the proper key. It is thus permissible (but not 669matching line has the proper key.
670It is thus permissible (but not
608recommended) to have several lines or different host keys for the same 671recommended) to have several lines or different host keys for the same
609names. This will inevitably happen when short forms of host names 672names.
610from different domains are put in the file. It is possible 673This will inevitably happen when short forms of host names
674from different domains are put in the file.
675It is possible
611that the files contain conflicting information; authentication is 676that the files contain conflicting information; authentication is
612accepted if valid information can be found from either file. 677accepted if valid information can be found from either file.
613.Pp 678.Pp
@@ -636,7 +701,9 @@ does not start if this file is group/world-accessible.
636.It Pa /etc/ssh_host_key.pub 701.It Pa /etc/ssh_host_key.pub
637Contains the public part of the host key. 702Contains the public part of the host key.
638This file should be world-readable but writable only by 703This file should be world-readable but writable only by
639root. Its contents should match the private part. This file is not 704root.
705Its contents should match the private part.
706This file is not
640really used for anything; it is only provided for the convenience of 707really used for anything; it is only provided for the convenience of
641the user so its contents can be copied to known hosts files. 708the user so its contents can be copied to known hosts files.
642These two files are created using 709These two files are created using
@@ -646,21 +713,22 @@ Contains the process ID of the
646.Nm 713.Nm
647listening for connections (if there are several daemons running 714listening for connections (if there are several daemons running
648concurrently for different ports, this contains the pid of the one 715concurrently for different ports, this contains the pid of the one
649started last). The contents of this file are not sensitive; it can be 716started last).
650world-readable. 717The contents of this file are not sensitive; it can be world-readable.
651.It Pa $HOME/.ssh/authorized_keys 718.It Pa $HOME/.ssh/authorized_keys
652Lists the RSA keys that can be used to log into the user's account. 719Lists the RSA keys that can be used to log into the user's account.
653This file must be readable by root (which may on some machines imply 720This file must be readable by root (which may on some machines imply
654it being world-readable if the user's home directory resides on an NFS 721it being world-readable if the user's home directory resides on an NFS
655volume). It is recommended that it not be accessible by others. The 722volume).
656format of this file is described above. 723It is recommended that it not be accessible by others.
724The format of this file is described above.
657.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts" 725.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
658These files are consulted when using rhosts with RSA host 726These files are consulted when using rhosts with RSA host
659authentication to check the public key of the host. The key must be 727authentication to check the public key of the host.
660listed in one of these files to be accepted. 728The key must be listed in one of these files to be accepted.
661The client uses the same files 729The client uses the same files
662to verify that the remote host is the one we intended to 730to verify that the remote host is the one we intended to connect.
663connect. These files should be writable only by root/the owner. 731These files should be writable only by root/the owner.
664.Pa /etc/ssh_known_hosts 732.Pa /etc/ssh_known_hosts
665should be world-readable, and 733should be world-readable, and
666.Pa $HOME/.ssh/known_hosts 734.Pa $HOME/.ssh/known_hosts
@@ -668,9 +736,11 @@ can but need not be world-readable.
668.It Pa /etc/nologin 736.It Pa /etc/nologin
669If this file exists, 737If this file exists,
670.Nm 738.Nm
671refuses to let anyone except root log in. The contents of the file 739refuses to let anyone except root log in.
740The contents of the file
672are displayed to anyone trying to log in, and non-root connections are 741are displayed to anyone trying to log in, and non-root connections are
673refused. The file should be world-readable. 742refused.
743The file should be world-readable.
674.It Pa /etc/hosts.allow, /etc/hosts.deny 744.It Pa /etc/hosts.allow, /etc/hosts.deny
675If compiled with 745If compiled with
676.Sy LIBWRAP 746.Sy LIBWRAP
@@ -678,13 +748,16 @@ support, tcp-wrappers access controls may be defined here as described in
678.Xr hosts_access 5 . 748.Xr hosts_access 5 .
679.It Pa $HOME/.rhosts 749.It Pa $HOME/.rhosts
680This file contains host-username pairs, separated by a space, one per 750This file contains host-username pairs, separated by a space, one per
681line. The given user on the corresponding host is permitted to log in 751line.
682without password. The same file is used by rlogind and rshd. 752The given user on the corresponding host is permitted to log in
753without password.
754The same file is used by rlogind and rshd.
683The file must 755The file must
684be writable only by the user; it is recommended that it not be 756be writable only by the user; it is recommended that it not be
685accessible by others. 757accessible by others.
686.Pp 758.Pp
687If is also possible to use netgroups in the file. Either host or user 759If is also possible to use netgroups in the file.
760Either host or user
688name may be of the form +@groupname to specify all hosts or all users 761name may be of the form +@groupname to specify all hosts or all users
689in the group. 762in the group.
690.It Pa $HOME/.shosts 763.It Pa $HOME/.shosts
@@ -696,21 +769,26 @@ not used by rlogin and rshd, so using this permits access using SSH only.
696.Pa /etc/hosts.equiv 769.Pa /etc/hosts.equiv
697This file is used during 770This file is used during
698.Pa .rhosts 771.Pa .rhosts
699authentication. In the 772authentication.
700simplest form, this file contains host names, one per line. Users on 773In the simplest form, this file contains host names, one per line.
774Users on
701those hosts are permitted to log in without a password, provided they 775those hosts are permitted to log in without a password, provided they
702have the same user name on both machines. The host name may also be 776have the same user name on both machines.
777The host name may also be
703followed by a user name; such users are permitted to log in as 778followed by a user name; such users are permitted to log in as
704.Em any 779.Em any
705user on this machine (except root). Additionally, the syntax 780user on this machine (except root).
781Additionally, the syntax
706.Dq +@group 782.Dq +@group
707can be used to specify netgroups. Negated entries start with 783can be used to specify netgroups.
784Negated entries start with
708.Ql \&- . 785.Ql \&- .
709.Pp 786.Pp
710If the client host/user is successfully matched in this file, login is 787If the client host/user is successfully matched in this file, login is
711automatically permitted provided the client and server user names are the 788automatically permitted provided the client and server user names are the
712same. Additionally, successful RSA host authentication is normally 789same.
713required. This file must be writable only by root; it is recommended 790Additionally, successful RSA host authentication is normally required.
791This file must be writable only by root; it is recommended
714that it be world-readable. 792that it be world-readable.
715.Pp 793.Pp
716.Sy "Warning: It is almost never a good idea to use user names in" 794.Sy "Warning: It is almost never a good idea to use user names in"
@@ -718,8 +796,9 @@ that it be world-readable.
718Beware that it really means that the named user(s) can log in as 796Beware that it really means that the named user(s) can log in as
719.Em anybody , 797.Em anybody ,
720which includes bin, daemon, adm, and other accounts that own critical 798which includes bin, daemon, adm, and other accounts that own critical
721binaries and directories. Using a user name practically grants the 799binaries and directories.
722user root access. The only valid use for user names that I can think 800Using a user name practically grants the user root access.
801The only valid use for user names that I can think
723of is in negative entries. 802of is in negative entries.
724.Pp 803.Pp
725Note that this warning also applies to rsh/rlogin. 804Note that this warning also applies to rsh/rlogin.
@@ -729,18 +808,20 @@ This is processed exactly as
729However, this file may be useful in environments that want to run both 808However, this file may be useful in environments that want to run both
730rsh/rlogin and ssh. 809rsh/rlogin and ssh.
731.It Pa $HOME/.ssh/environment 810.It Pa $HOME/.ssh/environment
732This file is read into the environment at login (if it exists). It 811This file is read into the environment at login (if it exists).
733can only contain empty lines, comment lines (that start with 812It can only contain empty lines, comment lines (that start with
734.Ql # ) , 813.Ql # ) ,
735and assignment lines of the form name=value. The file should be writable 814and assignment lines of the form name=value.
815The file should be writable
736only by the user; it need not be readable by anyone else. 816only by the user; it need not be readable by anyone else.
737.It Pa $HOME/.ssh/rc 817.It Pa $HOME/.ssh/rc
738If this file exists, it is run with /bin/sh after reading the 818If this file exists, it is run with /bin/sh after reading the
739environment files but before starting the user's shell or command. If 819environment files but before starting the user's shell or command.
740X11 spoofing is in use, this will receive the "proto cookie" pair in 820If X11 spoofing is in use, this will receive the "proto cookie" pair in
741standard input (and 821standard input (and
742.Ev DISPLAY 822.Ev DISPLAY
743in environment). This must call 823in environment).
824This must call
744.Xr xauth 1 825.Xr xauth 1
745in that case. 826in that case.
746.Pp 827.Pp
@@ -763,12 +844,13 @@ readable by anyone else.
763Like 844Like
764.Pa $HOME/.ssh/rc . 845.Pa $HOME/.ssh/rc .
765This can be used to specify 846This can be used to specify
766machine-specific login-time initializations globally. This file 847machine-specific login-time initializations globally.
767should be writable only by root, and should be world-readable. 848This file should be writable only by root, and should be world-readable.
768.Sh AUTHOR 849.Sh AUTHOR
769OpenSSH 850OpenSSH
770is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, 851is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen,
771but with bugs removed and newer features re-added. Rapidly after the 852but with bugs removed and newer features re-added.
853Rapidly after the
7721.2.12 release, newer versions of the original ssh bore successively 8541.2.12 release, newer versions of the original ssh bore successively
773more restrictive licenses, and thus demand for a free version was born. 855more restrictive licenses, and thus demand for a free version was born.
774This version of OpenSSH 856This version of OpenSSH
diff --git a/sshd.c b/sshd.c
index 98b6138ab..bf951212c 100644
--- a/sshd.c
+++ b/sshd.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$OpenBSD: sshd.c,v 1.92 2000/03/16 20:56:15 markus Exp $"); 14RCSID("$OpenBSD: sshd.c,v 1.94 2000/03/23 22:15:34 markus Exp $");
15 15
16#include "xmalloc.h" 16#include "xmalloc.h"
17#include "rsa.h" 17#include "rsa.h"
@@ -516,9 +516,6 @@ main(int ac, char **av)
516 unmounted if desired. */ 516 unmounted if desired. */
517 chdir("/"); 517 chdir("/");
518 518
519 /* Close connection cleanly after attack. */
520 cipher_attack_detected = packet_disconnect;
521
522 /* Start listening for a socket, unless started from inetd. */ 519 /* Start listening for a socket, unless started from inetd. */
523 if (inetd_flag) { 520 if (inetd_flag) {
524 int s1, s2; 521 int s1, s2;
@@ -1301,7 +1298,7 @@ do_authloop(struct passwd * pw)
1301{ 1298{
1302 int attempt = 0; 1299 int attempt = 0;
1303 unsigned int bits; 1300 unsigned int bits;
1304 BIGNUM *client_host_key_e, *client_host_key_n; 1301 RSA *client_host_key;
1305 BIGNUM *n; 1302 BIGNUM *n;
1306 char *client_user = NULL, *password = NULL; 1303 char *client_user = NULL, *password = NULL;
1307 char user[1024]; 1304 char user[1024];
@@ -1417,21 +1414,24 @@ do_authloop(struct passwd * pw)
1417 client_user = packet_get_string(&ulen); 1414 client_user = packet_get_string(&ulen);
1418 1415
1419 /* Get the client host key. */ 1416 /* Get the client host key. */
1420 client_host_key_e = BN_new(); 1417 client_host_key = RSA_new();
1421 client_host_key_n = BN_new(); 1418 if (client_host_key == NULL)
1419 fatal("RSA_new failed");
1420 client_host_key->e = BN_new();
1421 client_host_key->n = BN_new();
1422 if (client_host_key->e == NULL || client_host_key->n == NULL)
1423 fatal("BN_new failed");
1422 bits = packet_get_int(); 1424 bits = packet_get_int();
1423 packet_get_bignum(client_host_key_e, &elen); 1425 packet_get_bignum(client_host_key->e, &elen);
1424 packet_get_bignum(client_host_key_n, &nlen); 1426 packet_get_bignum(client_host_key->n, &nlen);
1425 1427
1426 if (bits != BN_num_bits(client_host_key_n)) 1428 if (bits != BN_num_bits(client_host_key->n))
1427 error("Warning: keysize mismatch for client_host_key: " 1429 error("Warning: keysize mismatch for client_host_key: "
1428 "actual %d, announced %d", BN_num_bits(client_host_key_n), bits); 1430 "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
1429 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); 1431 packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
1430 1432
1431 authenticated = auth_rhosts_rsa(pw, client_user, 1433 authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
1432 client_host_key_e, client_host_key_n); 1434 RSA_free(client_host_key);
1433 BN_clear_free(client_host_key_e);
1434 BN_clear_free(client_host_key_n);
1435 1435
1436 snprintf(user, sizeof user, " ruser %s", client_user); 1436 snprintf(user, sizeof user, " ruser %s", client_user);
1437 break; 1437 break;