diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | README.Ylonen | 4 | ||||
-rw-r--r-- | auth-krb4.c | 2 | ||||
-rw-r--r-- | auth-rh-rsa.c | 49 | ||||
-rw-r--r-- | auth-rsa.c | 37 | ||||
-rw-r--r-- | cipher.c | 16 | ||||
-rw-r--r-- | cipher.h | 8 | ||||
-rw-r--r-- | hostfile.c | 202 | ||||
-rw-r--r-- | hostfile.h | 22 | ||||
-rw-r--r-- | key.c | 301 | ||||
-rw-r--r-- | key.h | 23 | ||||
-rw-r--r-- | match.c | 61 | ||||
-rw-r--r-- | match.h | 18 | ||||
-rw-r--r-- | scp.1 | 29 | ||||
-rw-r--r-- | ssh-add.1 | 33 | ||||
-rw-r--r-- | ssh-agent.1 | 52 | ||||
-rw-r--r-- | ssh-keygen.1 | 62 | ||||
-rw-r--r-- | ssh.1 | 36 | ||||
-rw-r--r-- | ssh.c | 13 | ||||
-rw-r--r-- | ssh.h | 36 | ||||
-rw-r--r-- | sshconnect.c | 72 | ||||
-rw-r--r-- | sshd.8 | 388 | ||||
-rw-r--r-- | sshd.c | 30 |
24 files changed, 965 insertions, 545 deletions
@@ -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 | ||
6 | 20000324 | 20 | 20000324 |
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 | ||
32 | TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) | 32 | TARGETS=ssh sshd ssh-add ssh-keygen ssh-agent scp $(EXTRA_TARGETS) |
33 | 33 | ||
34 | LIBOBJS= 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 | 34 | LIBOBJS= 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 | ||
36 | SSHOBJS= ssh.o sshconnect.o log-client.o readconf.o clientloop.o | 36 | SSHOBJS= 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 | |||
1 | Ssh (Secure Shell) is a program to log into another computer over a | 5 | Ssh (Secure Shell) is a program to log into another computer over a |
2 | network, to execute commands in a remote machine, and to move files | 6 | network, to execute commands in a remote machine, and to move files |
3 | from one machine to another. It provides strong authentication and | 7 | from 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 | |||
139 | krb4_init(uid_t uid) | 139 | krb4_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" |
18 | RCSID("$Id: auth-rh-rsa.c,v 1.7 1999/11/25 00:54:57 damien Exp $"); | 18 | RCSID("$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 | ||
31 | int | 45 | int |
32 | auth_rhosts_rsa(struct passwd *pw, const char *client_user, | 46 | auth_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" |
19 | RCSID("$Id: auth-rsa.c,v 1.13 2000/03/09 10:27:50 damien Exp $"); | 19 | RCSID("$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 | ||
68 | int | 69 | int |
69 | auth_rsa_challenge_dialog(BIGNUM *e, BIGNUM *n) | 70 | auth_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."); |
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$Id: cipher.c,v 1.13 2000/03/09 10:27:50 damien Exp $"); | 15 | RCSID("$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 | ||
113 | void (*cipher_attack_detected) (const char *fmt,...) = fatal; | ||
114 | |||
115 | static inline void | ||
116 | detect_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, |
@@ -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 | |||
96 | cipher_decrypt(CipherContext * context, unsigned char *dest, | 96 | cipher_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 | */ | ||
103 | extern 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" |
17 | RCSID("$OpenBSD: hostfile.c,v 1.13 2000/02/18 10:20:20 markus Exp $"); | 17 | RCSID("$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 | ||
30 | int | 41 | int |
31 | auth_rsa_read_bignum(char **cpp, BIGNUM * value) | 42 | hostfile_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 | |||
72 | int | ||
73 | auth_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 | |||
113 | int | 70 | int |
114 | match_hostname(const char *host, const char *pattern, unsigned int len) | 71 | auth_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. */ | 81 | int |
150 | if (match_pattern(host, sub)) { | 82 | hostfile_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 | ||
172 | HostStatus | 103 | HostStatus |
173 | check_host_in_hostfile(const char *filename, const char *host, | 104 | check_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 | ||
262 | int | 189 | int |
263 | add_host_to_hostfile(const char *filename, const char *host, | 190 | add_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 | */ | ||
10 | typedef enum { | ||
11 | HOST_OK, HOST_NEW, HOST_CHANGED | ||
12 | } HostStatus; | ||
13 | HostStatus | ||
14 | check_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 | */ | ||
20 | int add_host_to_hostfile(const char *filename, const char *host, Key *key); | ||
21 | |||
22 | #endif | ||
@@ -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 | |||
53 | Key * | ||
54 | key_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 | } | ||
86 | void | ||
87 | key_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 | } | ||
106 | int | ||
107 | key_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 | */ | ||
137 | char * | ||
138 | key_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 | */ | ||
192 | int | ||
193 | read_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 | } | ||
228 | int | ||
229 | write_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 | } | ||
240 | int | ||
241 | key_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 | } | ||
271 | int | ||
272 | key_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 | } | ||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef KEY_H | ||
2 | #define KEY_H | ||
3 | |||
4 | typedef struct Key Key; | ||
5 | enum types { | ||
6 | KEY_RSA, | ||
7 | KEY_DSA, | ||
8 | KEY_EMPTY | ||
9 | }; | ||
10 | struct Key { | ||
11 | int type; | ||
12 | RSA *rsa; | ||
13 | DSA *dsa; | ||
14 | }; | ||
15 | |||
16 | Key *key_new(int type); | ||
17 | void key_free(Key *k); | ||
18 | int key_equal(Key *a, Key *b); | ||
19 | char *key_fingerprint(Key *k); | ||
20 | int key_write(Key *key, FILE *f); | ||
21 | int key_read(Key *key, unsigned int bits, char **cpp); | ||
22 | |||
23 | #endif | ||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$Id: match.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); | 17 | RCSID("$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 | |||
91 | int | ||
92 | match_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 | */ | ||
8 | int 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 | */ | ||
16 | int match_hostname(const char *host, const char *pattern, unsigned int len); | ||
17 | |||
18 | #endif | ||
@@ -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 |
41 | copies files between hosts on a network. It uses | 41 | copies files between hosts on a network. |
42 | It uses | ||
42 | .Xr ssh 1 | 43 | .Xr ssh 1 |
43 | for data transfer, and uses the same authentication and provides the | 44 | for data transfer, and uses the same authentication and provides the |
44 | same security as | 45 | same security as |
@@ -50,18 +51,19 @@ will ask for passwords or passphrases if they are needed for | |||
50 | authentication. | 51 | authentication. |
51 | .Pp | 52 | .Pp |
52 | Any file name may contain a host and user specification to indicate | 53 | Any file name may contain a host and user specification to indicate |
53 | that the file is to be copied to/from that host. Copies between two | 54 | that the file is to be copied to/from that host. |
54 | remote hosts are permitted. | 55 | Copies between two remote hosts are permitted. |
55 | .Pp | 56 | .Pp |
56 | The options are as follows: | 57 | The 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 |
59 | Selects the cipher to use for encrypting the data transfer. This | 60 | Selects the cipher to use for encrypting the data transfer. |
60 | option is directly passed to | 61 | This 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 |
63 | Selects the file from which the identity (private key) for RSA | 64 | Selects the file from which the identity (private key) for RSA |
64 | authentication is read. This option is directly passed to | 65 | authentication is read. |
66 | This option is directly passed to | ||
65 | .Xr ssh 1 . | 67 | .Xr ssh 1 . |
66 | .It Fl p | 68 | .It Fl p |
67 | Preserves modification times, access times, and modes from the | 69 | Preserves modification times, access times, and modes from the |
@@ -69,25 +71,28 @@ original file. | |||
69 | .It Fl r | 71 | .It Fl r |
70 | Recursively copy entire directories. | 72 | Recursively copy entire directories. |
71 | .It Fl v | 73 | .It Fl v |
72 | Verbose mode. Causes | 74 | Verbose mode. |
75 | Causes | ||
73 | .Nm | 76 | .Nm |
74 | and | 77 | and |
75 | .Xr ssh 1 | 78 | .Xr ssh 1 |
76 | to print debugging messages about their progress. This is helpful in | 79 | to print debugging messages about their progress. |
80 | This is helpful in | ||
77 | debugging connection, authentication, and configuration problems. | 81 | debugging connection, authentication, and configuration problems. |
78 | .It Fl B | 82 | .It Fl B |
79 | Selects batch mode (prevents asking for passwords or passphrases). | 83 | Selects batch mode (prevents asking for passwords or passphrases). |
80 | .It Fl q | 84 | .It Fl q |
81 | Disables the progress meter. | 85 | Disables the progress meter. |
82 | .It Fl C | 86 | .It Fl C |
83 | Compression enable. Passes the | 87 | Compression enable. |
88 | Passes the | ||
84 | .Fl C | 89 | .Fl C |
85 | flag to | 90 | flag to |
86 | .Xr ssh 1 | 91 | .Xr ssh 1 |
87 | to enable compression. | 92 | to enable compression. |
88 | .It Fl P Ar port | 93 | .It Fl P Ar port |
89 | Specifies the port to connect to on the remote host. Note that this | 94 | Specifies the port to connect to on the remote host. |
90 | option is written with a capital | 95 | Note that this option is written with a capital |
91 | .Sq P , | 96 | .Sq P , |
92 | because | 97 | because |
93 | .Fl p | 98 | .Fl p |
@@ -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 . |
28 | When run without arguments, it adds the file | 28 | When run without arguments, it adds the file |
29 | .Pa $HOME/.ssh/identity . | 29 | .Pa $HOME/.ssh/identity . |
30 | Alternative file names can be given on the | 30 | Alternative file names can be given on the command line. |
31 | command line. If any file requires a passphrase, | 31 | If any file requires a passphrase, |
32 | .Nm | 32 | .Nm |
33 | asks for the passphrase from the user. | 33 | asks for the passphrase from the user. |
34 | The Passphrase it is read from the user's tty. | 34 | The Passphrase it is read from the user's tty. |
35 | .Pp | 35 | .Pp |
36 | The authentication agent must be running and must be an ancestor of | 36 | The authentication agent must be running and must be an ancestor of |
37 | the current process for | 37 | the 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 |
55 | Contains the RSA authentication identity of the user. This file | 55 | Contains the RSA authentication identity of the user. |
56 | should not be readable by anyone but the user. | 56 | This file should not be readable by anyone but the user. |
57 | Note that | 57 | Note that |
58 | .Nm | 58 | .Nm |
59 | ignores this file if it is accessible by others. | 59 | ignores this file if it is accessible by others. |
60 | It is possible to | 60 | It is possible to |
61 | specify a passphrase when generating the key; that passphrase will be | 61 | specify a passphrase when generating the key; that passphrase will be |
62 | used to encrypt the private part of this file. This is the | 62 | used to encrypt the private part of this file. |
63 | default file added by | 63 | This is the default file added by |
64 | .Nm | 64 | .Nm |
65 | when no other files have been specified. | 65 | when no other files have been specified. |
66 | .Pp | 66 | .Pp |
@@ -70,7 +70,8 @@ when no other files have been specified. | |||
70 | If | 70 | If |
71 | .Nm | 71 | .Nm |
72 | needs a passphrase, it will read the passphrase from the current | 72 | needs a passphrase, it will read the passphrase from the current |
73 | terminal if it was run from a terminal. If | 73 | terminal if it was run from a terminal. |
74 | If | ||
74 | .Nm | 75 | .Nm |
75 | does not have a terminal associated with it but | 76 | does 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 |
79 | are set, it will execute the program specified by | 80 | are set, it will execute the program specified by |
80 | .Ev SSH_ASKPASS | 81 | .Ev SSH_ASKPASS |
81 | and open an X11 window to read the passphrase. This is particularly | 82 | and open an X11 window to read the passphrase. |
82 | useful when calling | 83 | This is particularly useful when calling |
83 | .Nm | 84 | .Nm |
84 | from a | 85 | from a |
85 | .Pa .Xsession | 86 | .Pa .Xsession |
86 | or related script. (Note that on some machines it | 87 | or related script. |
88 | (Note that on some machines it | ||
87 | may be necessary to redirect the input from | 89 | may be necessary to redirect the input from |
88 | .Pa /dev/null | 90 | .Pa /dev/null |
89 | to make this work.) | 91 | to make this work.) |
@@ -92,9 +94,10 @@ Tatu Ylonen <ylo@cs.hut.fi> | |||
92 | .Pp | 94 | .Pp |
93 | OpenSSH | 95 | OpenSSH |
94 | is a derivative of the original (free) ssh 1.2.12 release, but with bugs | 96 | is a derivative of the original (free) ssh 1.2.12 release, but with bugs |
95 | removed and newer features re-added. Rapidly after the 1.2.12 release, | 97 | removed and newer features re-added. |
96 | newer versions bore successively more restrictive licenses. This version | 98 | Rapidly after the 1.2.12 release, |
97 | of OpenSSH | 99 | newer versions bore successively more restrictive licenses. |
100 | This version of OpenSSH | ||
98 | .Bl -bullet | 101 | .Bl -bullet |
99 | .It | 102 | .It |
100 | has all components of a restrictive nature (i.e., patents, see | 103 | has 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 |
30 | is a program to hold authentication private keys. The | 30 | is a program to hold authentication private keys. |
31 | idea is that | 31 | The idea is that |
32 | .Nm | 32 | .Nm |
33 | is started in the beginning of an X-session or a login session, and | 33 | is started in the beginning of an X-session or a login session, and |
34 | all other windows or programs are started as clients to the ssh-agent | 34 | all other windows or programs are started as clients to the ssh-agent |
35 | program. Through use of environment variables the agent can be located | 35 | program. |
36 | Through use of environment variables the agent can be located | ||
36 | and automatically used for RSA authentication when logging in to other | 37 | and automatically used for RSA authentication when logging in to other |
37 | machines using | 38 | machines using |
38 | .Xr ssh 1 . | 39 | .Xr ssh 1 . |
@@ -60,30 +61,34 @@ environment variable). | |||
60 | If a commandline is given, this is executed as a subprocess of the agent. | 61 | If a commandline is given, this is executed as a subprocess of the agent. |
61 | When the command dies, so does the agent. | 62 | When the command dies, so does the agent. |
62 | .Pp | 63 | .Pp |
63 | The agent initially does not have any private keys. Keys are added | 64 | The agent initially does not have any private keys. |
64 | using | 65 | Keys are added using |
65 | .Xr ssh-add 1 . | 66 | .Xr ssh-add 1 . |
66 | When executed without arguments, | 67 | When executed without arguments, |
67 | .Xr ssh-add 1 | 68 | .Xr ssh-add 1 |
68 | adds the | 69 | adds the |
69 | .Pa $HOME/.ssh/identity | 70 | .Pa $HOME/.ssh/identity |
70 | file. If the identity has a passphrase, | 71 | file. |
72 | If the identity has a passphrase, | ||
71 | .Xr ssh-add 1 | 73 | .Xr ssh-add 1 |
72 | asks for the passphrase (using a small X11 application if running | 74 | asks for the passphrase (using a small X11 application if running |
73 | under X11, or from the terminal if running without X). It then sends | 75 | under X11, or from the terminal if running without X). |
74 | the identity to the agent. Several identities can be stored in the | 76 | It then sends the identity to the agent. |
77 | Several identities can be stored in the | ||
75 | agent; the agent can automatically use any of these identities. | 78 | agent; the agent can automatically use any of these identities. |
76 | .Ic ssh-add -l | 79 | .Ic ssh-add -l |
77 | displays the identities currently held by the agent. | 80 | displays the identities currently held by the agent. |
78 | .Pp | 81 | .Pp |
79 | The idea is that the agent is run in the user's local PC, laptop, or | 82 | The idea is that the agent is run in the user's local PC, laptop, or |
80 | terminal. Authentication data need not be stored on any other | 83 | terminal. |
84 | Authentication data need not be stored on any other | ||
81 | machine, and authentication passphrases never go over the network. | 85 | machine, and authentication passphrases never go over the network. |
82 | However, the connection to the agent is forwarded over SSH | 86 | However, the connection to the agent is forwarded over SSH |
83 | remote logins, and the user can thus use the privileges given by the | 87 | remote logins, and the user can thus use the privileges given by the |
84 | identities anywhere in the network in a secure way. | 88 | identities anywhere in the network in a secure way. |
85 | .Pp | 89 | .Pp |
86 | There are two main ways to get an agent setup: Either you let the agent | 90 | There are two main ways to get an agent setup: |
91 | Either you let the agent | ||
87 | start a new subcommand into which some environment variables are exported, or | 92 | start a new subcommand into which some environment variables are exported, or |
88 | you let the agent print the needed shell commands (either | 93 | you 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 | |||
99 | and the name of this socket is stored in the | 104 | and the name of this socket is stored in the |
100 | .Ev SSH_AUTH_SOCK | 105 | .Ev SSH_AUTH_SOCK |
101 | environment | 106 | environment |
102 | variable. The socket is made accessible only to the current user. | 107 | variable. |
108 | The socket is made accessible only to the current user. | ||
103 | This method is easily abused by root or another instance of the same | 109 | This method is easily abused by root or another instance of the same |
104 | user. | 110 | user. |
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 |
115 | Contains the RSA authentication identity of the user. This file | 121 | Contains the RSA authentication identity of the user. |
116 | should not be readable by anyone but the user. It is possible to | 122 | This file should not be readable by anyone but the user. |
123 | It is possible to | ||
117 | specify a passphrase when generating the key; that passphrase will be | 124 | specify a passphrase when generating the key; that passphrase will be |
118 | used to encrypt the private part of this file. This file | 125 | used to encrypt the private part of this file. |
119 | is not used by | 126 | This file is not used by |
120 | .Nm | 127 | .Nm |
121 | but is normally added to the agent using | 128 | but is normally added to the agent using |
122 | .Xr ssh-add 1 | 129 | .Xr ssh-add 1 |
123 | at login time. | 130 | at login time. |
124 | .It Pa /tmp/ssh-XXXX/agent.<pid> , | 131 | .It Pa /tmp/ssh-XXXX/agent.<pid> , |
125 | Unix-domain sockets used to contain the connection to the | 132 | Unix-domain sockets used to contain the connection to the |
126 | authentication agent. These sockets should only be readable by the | 133 | authentication agent. |
127 | owner. The sockets should get automatically removed when the agent | 134 | These sockets should only be readable by the owner. |
128 | exits. | 135 | The sockets should get automatically removed when the agent exits. |
129 | .Sh AUTHOR | 136 | .Sh AUTHOR |
130 | Tatu Ylonen <ylo@cs.hut.fi> | 137 | Tatu Ylonen <ylo@cs.hut.fi> |
131 | .Pp | 138 | .Pp |
132 | OpenSSH | 139 | OpenSSH |
133 | is a derivative of the original (free) ssh 1.2.12 release, but with bugs | 140 | is a derivative of the original (free) ssh 1.2.12 release, but with bugs |
134 | removed and newer features re-added. Rapidly after the 1.2.12 release, | 141 | removed and newer features re-added. |
135 | newer versions bore successively more restrictive licenses. This version | 142 | Rapidly after the 1.2.12 release, |
136 | of OpenSSH | 143 | newer versions bore successively more restrictive licenses. |
144 | This version of OpenSSH | ||
137 | .Bl -bullet | 145 | .Bl -bullet |
138 | .It | 146 | .It |
139 | has all components of a restrictive nature (i.e., patents, see | 147 | has 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 | |||
48 | Additionally, the system administrator may use this to generate host keys. | 48 | Additionally, the system administrator may use this to generate host keys. |
49 | .Pp | 49 | .Pp |
50 | Normally this program generates the key and asks for a file in which | 50 | Normally this program generates the key and asks for a file in which |
51 | to store the private key. The public key is stored in a file with the | 51 | to store the private key. |
52 | same name but | 52 | The public key is stored in a file with the same name but |
53 | .Dq .pub | 53 | .Dq .pub |
54 | appended. The program also asks for a | 54 | appended. |
55 | passphrase. The passphrase may be empty to indicate no passphrase | 55 | The program also asks for a passphrase. |
56 | The 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 |
57 | arbitrary length. Good passphrases are 10-30 characters long and are | 58 | arbitrary length. |
59 | Good passphrases are 10-30 characters long and are | ||
58 | not simple sentences or otherwise easily guessable (English | 60 | not simple sentences or otherwise easily guessable (English |
59 | prose has only 1-2 bits of entropy per word, and provides very bad | 61 | prose has only 1-2 bits of entropy per word, and provides very bad |
60 | passphrases). The passphrase can be changed later by using the | 62 | passphrases). |
63 | The passphrase can be changed later by using the | ||
61 | .Fl p | 64 | .Fl p |
62 | option. | 65 | option. |
63 | .Pp | 66 | .Pp |
64 | There is no way to recover a lost passphrase. If the passphrase is | 67 | There is no way to recover a lost passphrase. |
68 | If the passphrase is | ||
65 | lost or forgotten, you will have to generate a new key and copy the | 69 | lost or forgotten, you will have to generate a new key and copy the |
66 | corresponding public key to other machines. | 70 | corresponding public key to other machines. |
67 | .Pp | 71 | .Pp |
68 | There is also a comment field in the key file that is only for | 72 | There is also a comment field in the key file that is only for |
69 | convenience to the user to help identify the key. The comment can | 73 | convenience to the user to help identify the key. |
70 | tell what the key is for, or whatever is useful. The comment is | 74 | The comment can tell what the key is for, or whatever is useful. |
71 | initialized to | 75 | The comment is initialized to |
72 | .Dq user@host | 76 | .Dq user@host |
73 | when the key is created, but can be changed using the | 77 | when the key is created, but can be changed using the |
74 | .Fl c | 78 | .Fl c |
@@ -77,10 +81,11 @@ option. | |||
77 | The options are as follows: | 81 | The 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 |
80 | Specifies the number of bits in the key to create. Minimum is 512 | 84 | Specifies the number of bits in the key to create. |
81 | bits. Generally 1024 bits is considered sufficient, and key sizes | 85 | Minimum is 512 bits. |
82 | above that no longer improve security but make things slower. The | 86 | Generally 1024 bits is considered sufficient, and key sizes |
83 | default is 1024 bits. | 87 | above that no longer improve security but make things slower. |
88 | The default is 1024 bits. | ||
84 | .It Fl c | 89 | .It Fl c |
85 | Requests changing the comment in the private and public key files. | 90 | Requests changing the comment in the private and public key files. |
86 | The program will prompt for the file containing the private keys, for | 91 | The program will prompt for the file containing the private keys, for |
@@ -91,7 +96,8 @@ Specifies the filename of the key file. | |||
91 | Show fingerprint of specified private or public key file. | 96 | Show fingerprint of specified private or public key file. |
92 | .It Fl p | 97 | .It Fl p |
93 | Requests changing the passphrase of a private key file instead of | 98 | Requests changing the passphrase of a private key file instead of |
94 | creating a new private key. The program will prompt for the file | 99 | creating a new private key. |
100 | The program will prompt for the file | ||
95 | containing the private key, for the old passphrase, and twice for the | 101 | containing the private key, for the old passphrase, and twice for the |
96 | new passphrase. | 102 | new 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 |
113 | Contains the RSA authentication identity of the user. This file | 119 | Contains the RSA authentication identity of the user. |
114 | should not be readable by anyone but the user. It is possible to | 120 | This file should not be readable by anyone but the user. |
121 | It is possible to | ||
115 | specify a passphrase when generating the key; that passphrase will be | 122 | specify a passphrase when generating the key; that passphrase will be |
116 | used to encrypt the private part of this file using 3DES. This file | 123 | used to encrypt the private part of this file using 3DES. |
117 | is not automatically accessed by | 124 | This file is not automatically accessed by |
118 | .Nm | 125 | .Nm |
119 | but it is offered as the default file for the private key. | 126 | but 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 |
121 | Contains the public key for authentication. The contents of this file | 128 | Contains the public key for authentication. |
122 | should be added to | 129 | The contents of this file should be added to |
123 | .Pa $HOME/.ssh/authorized_keys | 130 | .Pa $HOME/.ssh/authorized_keys |
124 | on all machines | 131 | on all machines |
125 | where you wish to log in using RSA authentication. There is no | 132 | where you wish to log in using RSA authentication. |
126 | need to keep the contents of this file secret. | 133 | There is no need to keep the contents of this file secret. |
127 | .Sh AUTHOR | 134 | .Sh AUTHOR |
128 | Tatu Ylonen <ylo@cs.hut.fi> | 135 | Tatu Ylonen <ylo@cs.hut.fi> |
129 | .Pp | 136 | .Pp |
130 | OpenSSH | 137 | OpenSSH |
131 | is a derivative of the original (free) ssh 1.2.12 release, but with bugs | 138 | is a derivative of the original (free) ssh 1.2.12 release, but with bugs |
132 | removed and newer features re-added. Rapidly after the 1.2.12 release, | 139 | removed and newer features re-added. |
133 | newer versions bore successively more restrictive licenses. This version | 140 | Rapidly after the 1.2.12 release, |
134 | of OpenSSH | 141 | newer versions bore successively more restrictive licenses. |
142 | This version of OpenSSH | ||
135 | .Bl -bullet | 143 | .Bl -bullet |
136 | .It | 144 | .It |
137 | has all components of a restrictive nature (i.e., patents, see | 145 | has all components of a restrictive nature (i.e., patents, see |
@@ -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 |
290 | Disables forwarding of the authentication agent connection. This may | 290 | Disables forwarding of the authentication agent connection. |
291 | also be specified on a per-host basis in the configuration file. | 291 | This 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 |
293 | Selects the cipher to use for encrypting the session. | 293 | Selects the cipher to use for encrypting the session. |
294 | .Ar 3des | 294 | .Ar 3des |
@@ -342,8 +342,8 @@ It is possible to have multiple | |||
342 | options (and multiple identities specified in | 342 | options (and multiple identities specified in |
343 | configuration files). | 343 | configuration files). |
344 | .It Fl k | 344 | .It Fl k |
345 | Disables forwarding of Kerberos tickets and AFS tokens. This may | 345 | Disables forwarding of Kerberos tickets and AFS tokens. |
346 | also be specified on a per-host basis in the configuration file. | 346 | This 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 |
348 | Specifies the user to log in as on the remote machine. | 348 | Specifies the user to log in as on the remote machine. |
349 | This also may be specified on a per-host basis in the configuration file. | 349 | This 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. | |||
390 | Only fatal errors are displayed. | 390 | Only fatal errors are displayed. |
391 | .It Fl t | 391 | .It Fl t |
392 | Force pseudo-tty allocation. | 392 | Force pseudo-tty allocation. |
393 | This can be used to execute arbitary | 393 | This can be used to execute arbitrary |
394 | screen-based programs on a remote machine, which can be very useful, | 394 | screen-based programs on a remote machine, which can be very useful, |
395 | e.g., when implementing menu services. | 395 | e.g., when implementing menu services. |
396 | .It Fl v | 396 | .It Fl v |
@@ -514,8 +514,8 @@ The host is the | |||
514 | argument given on the command line (i.e., the name is not converted to | 514 | argument given on the command line (i.e., the name is not converted to |
515 | a canonicalized host name before matching). | 515 | a canonicalized host name before matching). |
516 | .It Cm AFSTokenPassing | 516 | .It Cm AFSTokenPassing |
517 | Specifies whether to pass AFS tokens to remote host. The argument to | 517 | Specifies whether to pass AFS tokens to remote host. |
518 | this keyword must be | 518 | The argument to this keyword must be |
519 | .Dq yes | 519 | .Dq yes |
520 | or | 520 | or |
521 | .Dq no . | 521 | .Dq no . |
@@ -534,7 +534,8 @@ If this flag is set to | |||
534 | .Dq yes , | 534 | .Dq yes , |
535 | ssh will additionally check the host ip address in the | 535 | ssh will additionally check the host ip address in the |
536 | .Pa known_hosts | 536 | .Pa known_hosts |
537 | file. This allows ssh to detect if a host key changed due to DNS spoofing. | 537 | file. |
538 | This allows ssh to detect if a host key changed due to DNS spoofing. | ||
538 | If the option is set to | 539 | If the option is set to |
539 | .Dq no , | 540 | .Dq no , |
540 | the check will not be executed. | 541 | the check will not be executed. |
@@ -645,7 +646,7 @@ If they are sent, death of the connection or crash of one | |||
645 | of the machines will be properly noticed. | 646 | of the machines will be properly noticed. |
646 | However, this means that | 647 | However, this means that |
647 | connections will die if the route is down temporarily, and some people | 648 | connections will die if the route is down temporarily, and some people |
648 | find it annoying. | 649 | find it annoying. |
649 | .Pp | 650 | .Pp |
650 | The default is | 651 | The 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 |
658 | in both the server and the client configuration files. | 659 | in both the server and the client configuration files. |
659 | .It Cm KerberosAuthentication | 660 | .It Cm KerberosAuthentication |
660 | Specifies whether Kerberos authentication will be used. The argument to | 661 | Specifies whether Kerberos authentication will be used. |
661 | this keyword must be | 662 | The argument to this keyword must be |
662 | .Dq yes | 663 | .Dq yes |
663 | or | 664 | or |
664 | .Dq no . | 665 | .Dq no . |
665 | .It Cm KerberosTgtPassing | 666 | .It Cm KerberosTgtPassing |
666 | Specifies whether a Kerberos TGT will be forwarded to the server. This | 667 | Specifies whether a Kerberos TGT will be forwarded to the server. |
667 | will only work if the Kerberos server is actually an AFS kaserver. The | 668 | This will only work if the Kerberos server is actually an AFS kaserver. |
668 | argument to this keyword must be | 669 | The argument to this keyword must be |
669 | .Dq yes | 670 | .Dq yes |
670 | or | 671 | or |
671 | .Dq no . | 672 | .Dq no . |
@@ -684,8 +685,9 @@ The possible values are: | |||
684 | QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. | 685 | QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG. |
685 | The default is INFO. | 686 | The default is INFO. |
686 | .It Cm NumberOfPasswordPrompts | 687 | .It Cm NumberOfPasswordPrompts |
687 | Specifies the number of password prompts before giving up. The | 688 | Specifies the number of password prompts before giving up. |
688 | argument to this keyword must be an integer. Default is 3. | 689 | The argument to this keyword must be an integer. |
690 | Default is 3. | ||
689 | .It Cm PasswordAuthentication | 691 | .It Cm PasswordAuthentication |
690 | Specifies whether to use password authentication. | 692 | Specifies whether to use password authentication. |
691 | The argument to this keyword must be | 693 | The argument to this keyword must be |
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: ssh.c,v 1.21 2000/03/09 10:27:52 damien Exp $"); | 14 | RCSID("$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(); |
@@ -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 | */ |
340 | int | 340 | int |
341 | auth_rhosts_rsa(struct passwd * pw, const char *client_user, | 341 | auth_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 | */ | ||
396 | int 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 | */ | ||
404 | typedef enum { | ||
405 | HOST_OK, HOST_NEW, HOST_CHANGED | ||
406 | } HostStatus; | ||
407 | HostStatus | ||
408 | check_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 | */ | ||
415 | int | ||
416 | add_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 | */ |
424 | int auth_rsa_challenge_dialog(BIGNUM * e, BIGNUM * n); | 394 | int 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" |
11 | RCSID("$OpenBSD: sshconnect.c,v 1.57 2000/03/16 20:56:14 markus Exp $"); | 11 | RCSID("$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. */ |
35 | unsigned char session_id[16]; | 40 | unsigned char session_id[16]; |
@@ -1073,9 +1078,9 @@ read_yes_or_no(const char *prompt, int defval) | |||
1073 | */ | 1078 | */ |
1074 | 1079 | ||
1075 | void | 1080 | void |
1076 | check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) | 1081 | check_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 | } |
1276 | void | ||
1277 | check_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 | } |
@@ -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 . |
34 | Together these programs replace rlogin and rsh programs, and | 34 | Together these programs replace rlogin and rsh programs, and |
35 | provide secure encrypted communications between two untrusted hosts | 35 | provide secure encrypted communications between two untrusted hosts |
36 | over an insecure network. The programs are intended to be as easy to | 36 | over an insecure network. |
37 | The programs are intended to be as easy to | ||
37 | install and use as possible. | 38 | install and use as possible. |
38 | .Pp | 39 | .Pp |
39 | .Nm | 40 | .Nm |
40 | is the daemon that listens for connections from clients. It is | 41 | is the daemon that listens for connections from clients. |
41 | normally started at boot from | 42 | It is normally started at boot from |
42 | .Pa /etc/rc . | 43 | .Pa /etc/rc . |
43 | It forks a new | 44 | It forks a new |
44 | daemon for each incoming connection. The forked daemons handle | 45 | daemon for each incoming connection. |
46 | The forked daemons handle | ||
45 | key exchange, encryption, authentication, command execution, | 47 | key exchange, encryption, authentication, command execution, |
46 | and data exchange. | 48 | and data exchange. |
47 | .Pp | 49 | .Pp |
48 | .Nm | 50 | .Nm |
49 | works as follows. Each host has a host-specific RSA key | 51 | works as follows. |
50 | (normally 1024 bits) used to identify the host. Additionally, when | 52 | Each host has a host-specific RSA key |
53 | (normally 1024 bits) used to identify the host. | ||
54 | Additionally, when | ||
51 | the daemon starts, it generates a server RSA key (normally 768 bits). | 55 | the daemon starts, it generates a server RSA key (normally 768 bits). |
52 | This key is normally regenerated every hour if it has been used, and | 56 | This key is normally regenerated every hour if it has been used, and |
53 | is never stored on disk. | 57 | is never stored on disk. |
54 | .Pp | 58 | .Pp |
55 | Whenever a client connects the daemon, the daemon sends its host | 59 | Whenever a client connects the daemon, the daemon sends its host |
56 | and server public keys to the client. The client compares the | 60 | and server public keys to the client. |
61 | The client compares the | ||
57 | host key against its own database to verify that it has not changed. | 62 | host key against its own database to verify that it has not changed. |
58 | The client then generates a 256 bit random number. It encrypts this | 63 | The client then generates a 256 bit random number. |
64 | It encrypts this | ||
59 | random number using both the host key and the server key, and sends | 65 | random number using both the host key and the server key, and sends |
60 | the encrypted number to the server. Both sides then start to use this | 66 | the encrypted number to the server. |
67 | Both sides then start to use this | ||
61 | random number as a session key which is used to encrypt all further | 68 | random number as a session key which is used to encrypt all further |
62 | communications in the session. The rest of the session is encrypted | 69 | communications in the session. |
70 | The rest of the session is encrypted | ||
63 | using a conventional cipher, currently Blowfish and 3DES, with 3DES | 71 | using a conventional cipher, currently Blowfish and 3DES, with 3DES |
64 | being is used by default. The client selects the encryption algorithm | 72 | being is used by default. |
73 | The client selects the encryption algorithm | ||
65 | to use from those offered by the server. | 74 | to use from those offered by the server. |
66 | .Pp | 75 | .Pp |
67 | Next, the server and the client enter an authentication dialog. The | 76 | Next, the server and the client enter an authentication dialog. |
68 | client tries to authenticate itself using | 77 | The client tries to authenticate itself using |
69 | .Pa .rhosts | 78 | .Pa .rhosts |
70 | authentication, | 79 | authentication, |
71 | .Pa .rhosts | 80 | .Pa .rhosts |
@@ -75,7 +84,8 @@ based authentication. | |||
75 | .Pp | 84 | .Pp |
76 | Rhosts authentication is normally disabled | 85 | Rhosts authentication is normally disabled |
77 | because it is fundamentally insecure, but can be enabled in the server | 86 | because it is fundamentally insecure, but can be enabled in the server |
78 | configuration file if desired. System security is not improved unless | 87 | configuration file if desired. |
88 | System 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 | |||
88 | into that machine). | 98 | into that machine). |
89 | .Pp | 99 | .Pp |
90 | If the client successfully authenticates itself, a dialog for | 100 | If the client successfully authenticates itself, a dialog for |
91 | preparing the session is entered. At this time the client may request | 101 | preparing the session is entered. |
102 | At this time the client may request | ||
92 | things like allocating a pseudo-tty, forwarding X11 connections, | 103 | things like allocating a pseudo-tty, forwarding X11 connections, |
93 | forwarding TCP/IP connections, or forwarding the authentication agent | 104 | forwarding TCP/IP connections, or forwarding the authentication agent |
94 | connection over the secure channel. | 105 | connection over the secure channel. |
95 | .Pp | 106 | .Pp |
96 | Finally, the client either requests a shell or execution of a command. | 107 | Finally, the client either requests a shell or execution of a command. |
97 | The sides then enter session mode. In this mode, either side may send | 108 | The sides then enter session mode. |
109 | In this mode, either side may send | ||
98 | data at any time, and such data is forwarded to/from the shell or | 110 | data at any time, and such data is forwarded to/from the shell or |
99 | command on the server side, and the user terminal in the client side. | 111 | command 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 |
106 | can be configured using command-line options or a configuration | 118 | can be configured using command-line options or a configuration |
107 | file. Command-line options override values specified in the | 119 | file. |
120 | Command-line options override values specified in the | ||
108 | configuration file. | 121 | configuration file. |
109 | .Pp | 122 | .Pp |
110 | .Nm | 123 | .Nm |
@@ -117,20 +130,23 @@ The options are as follows: | |||
117 | Specifies the number of bits in the server key (default 768). | 130 | Specifies the number of bits in the server key (default 768). |
118 | .Pp | 131 | .Pp |
119 | .It Fl d | 132 | .It Fl d |
120 | Debug mode. The server sends verbose debug output to the system | 133 | Debug mode. |
121 | log, and does not put itself in the background. The server also will | 134 | The server sends verbose debug output to the system |
122 | not fork and will only process one connection. This option is only | 135 | log, and does not put itself in the background. |
123 | intended for debugging for the server. | 136 | The server also will not fork and will only process one connection. |
137 | This option is only intended for debugging for the server. | ||
124 | .It Fl f Ar configuration_file | 138 | .It Fl f Ar configuration_file |
125 | Specifies the name of the configuration file. The default is | 139 | Specifies the name of the configuration file. |
140 | The default is | ||
126 | .Pa /etc/sshd_config . | 141 | .Pa /etc/sshd_config . |
127 | .Nm | 142 | .Nm |
128 | refuses to start if there is no configuration file. | 143 | refuses to start if there is no configuration file. |
129 | .It Fl g Ar login_grace_time | 144 | .It Fl g Ar login_grace_time |
130 | Gives the grace time for clients to authenticate themselves (default | 145 | Gives the grace time for clients to authenticate themselves (default |
131 | 300 seconds). If the client fails to authenticate the user within | 146 | 300 seconds). |
132 | this many seconds, the server disconnects and exits. A value of zero | 147 | If the client fails to authenticate the user within |
133 | indicates no limit. | 148 | this many seconds, the server disconnects and exits. |
149 | A value of zero indicates no limit. | ||
134 | .It Fl h Ar host_key_file | 150 | .It Fl h Ar host_key_file |
135 | Specifies the file from which the host key is read (default | 151 | Specifies 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 |
146 | is normally not run | 162 | is normally not run |
147 | from inetd because it needs to generate the server key before it can | 163 | from inetd because it needs to generate the server key before it can |
148 | respond to the client, and this may take tens of seconds. Clients | 164 | respond to the client, and this may take tens of seconds. |
149 | would have to wait too long if the key was regenerated every time. | 165 | Clients would have to wait too long if the key was regenerated every time. |
150 | However, with small key sizes (e.g., 512) using | 166 | However, with small key sizes (e.g., 512) using |
151 | .Nm | 167 | .Nm |
152 | from inetd may | 168 | from inetd may |
153 | be feasible. | 169 | be feasible. |
154 | .It Fl k Ar key_gen_time | 170 | .It Fl k Ar key_gen_time |
155 | Specifies how often the server key is regenerated (default 3600 | 171 | Specifies how often the server key is regenerated (default 3600 |
156 | seconds, or one hour). The motivation for regenerating the key fairly | 172 | seconds, or one hour). |
173 | The motivation for regenerating the key fairly | ||
157 | often is that the key is not stored anywhere, and after about an hour, | 174 | often is that the key is not stored anywhere, and after about an hour, |
158 | it becomes impossible to recover the key for decrypting intercepted | 175 | it becomes impossible to recover the key for decrypting intercepted |
159 | communications even if the machine is cracked into or physically | 176 | communications even if the machine is cracked into or physically |
160 | seized. A value of zero indicates that the key will never be regenerated. | 177 | seized. |
178 | A value of zero indicates that the key will never be regenerated. | ||
161 | .It Fl p Ar port | 179 | .It Fl p Ar port |
162 | Specifies the port on which the server listens for connections | 180 | Specifies the port on which the server listens for connections |
163 | (default 22). | 181 | (default 22). |
164 | .It Fl q | 182 | .It Fl q |
165 | Quiet mode. Nothing is sent to the system log. Normally the beginning, | 183 | Quiet mode. |
184 | Nothing is sent to the system log. | ||
185 | Normally the beginning, | ||
166 | authentication, and termination of each connection is logged. | 186 | authentication, and termination of each connection is logged. |
167 | .It Fl Q | 187 | .It Fl Q |
168 | Do not print an error message if RSA support is missing. | 188 | Do 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 |
191 | on the command line). The file | 211 | on the command line). |
192 | contains keyword-value pairs, one per line. Lines starting with | 212 | The file contains keyword-value pairs, one per line. |
213 | Lines starting with | ||
193 | .Ql # | 214 | .Ql # |
194 | and empty lines are interpreted as comments. | 215 | and empty lines are interpreted as comments. |
195 | .Pp | 216 | .Pp |
196 | The following keywords are possible. | 217 | The following keywords are possible. |
197 | .Bl -tag -width Ds | 218 | .Bl -tag -width Ds |
198 | .It Cm AFSTokenPassing | 219 | .It Cm AFSTokenPassing |
199 | Specifies whether an AFS token may be forwarded to the server. Default is | 220 | Specifies whether an AFS token may be forwarded to the server. |
221 | Default is | ||
200 | .Dq yes . | 222 | .Dq yes . |
201 | .It Cm AllowGroups | 223 | .It Cm AllowGroups |
202 | This keyword can be followed by a number of group names, separated | 224 | This keyword can be followed by a number of group names, separated |
203 | by spaces. If specified, login is allowed only for users whose primary | 225 | by spaces. |
226 | If specified, login is allowed only for users whose primary | ||
204 | group matches one of the patterns. | 227 | group matches one of the patterns. |
205 | .Ql \&* | 228 | .Ql \&* |
206 | and | 229 | and |
207 | .Ql ? | 230 | .Ql ? |
208 | can be used as | 231 | can be used as |
209 | wildcards in the patterns. Only group names are valid, a numerical group | 232 | wildcards in the patterns. |
210 | id isn't recognized. By default login is allowed regardless of | 233 | Only group names are valid, a numerical group ID isn't recognized. |
211 | the primary group. | 234 | By default login is allowed regardless of the primary group. |
212 | .Pp | 235 | .Pp |
213 | .It Cm AllowUsers | 236 | .It Cm AllowUsers |
214 | This keyword can be followed by a number of user names, separated | 237 | This keyword can be followed by a number of user names, separated |
215 | by spaces. If specified, login is allowed only for users names that | 238 | by spaces. |
239 | If specified, login is allowed only for users names that | ||
216 | match one of the patterns. | 240 | match one of the patterns. |
217 | .Ql \&* | 241 | .Ql \&* |
218 | and | 242 | and |
219 | .Ql ? | 243 | .Ql ? |
220 | can be used as | 244 | can be used as |
221 | wildcards in the patterns. Only user names are valid, a numerical user | 245 | wildcards in the patterns. |
222 | id isn't recognized. By default login is allowed regardless of | 246 | Only user names are valid, a numerical user ID isn't recognized. |
223 | the user name. | 247 | By default login is allowed regardless of the user name. |
224 | .Pp | 248 | .Pp |
225 | .It Cm CheckMail | 249 | .It Cm CheckMail |
226 | Specifies whether | 250 | Specifies whether |
@@ -230,27 +254,27 @@ The default is | |||
230 | .Dq no . | 254 | .Dq no . |
231 | .It Cm DenyGroups | 255 | .It Cm DenyGroups |
232 | This keyword can be followed by a number of group names, separated | 256 | This keyword can be followed by a number of group names, separated |
233 | by spaces. Users whose primary group matches one of the patterns | 257 | by spaces. |
258 | Users whose primary group matches one of the patterns | ||
234 | aren't allowed to log in. | 259 | aren't allowed to log in. |
235 | .Ql \&* | 260 | .Ql \&* |
236 | and | 261 | and |
237 | .Ql ? | 262 | .Ql ? |
238 | can be used as | 263 | can be used as |
239 | wildcards in the patterns. Only group names are valid, a numerical group | 264 | wildcards in the patterns. |
240 | id isn't recognized. By default login is allowed regardless of | 265 | Only group names are valid, a numerical group ID isn't recognized. |
241 | the primary group. | 266 | By default login is allowed regardless of the primary group. |
242 | .Pp | 267 | .Pp |
243 | .It Cm DenyUsers | 268 | .It Cm DenyUsers |
244 | This keyword can be followed by a number of user names, separated | 269 | This keyword can be followed by a number of user names, separated |
245 | by spaces. Login is disallowed for user names that match | 270 | by spaces. |
246 | one of the patterns. | 271 | Login is disallowed for user names that match one of the patterns. |
247 | .Ql \&* | 272 | .Ql \&* |
248 | and | 273 | and |
249 | .Ql ? | 274 | .Ql ? |
250 | can be used as | 275 | can be used as wildcards in the patterns. |
251 | wildcards in the patterns. Only user names are valid, a numerical user | 276 | Only user names are valid, a numerical user ID isn't recognized. |
252 | id isn't recognized. By default login is allowed regardless of | 277 | By default login is allowed regardless of the user name. |
253 | the user name. | ||
254 | .It Cm HostKey | 278 | .It Cm HostKey |
255 | Specifies the file containing the private host key (default | 279 | Specifies 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 |
267 | and | 291 | and |
268 | .Pa /etc/shosts.equiv | 292 | .Pa /etc/shosts.equiv |
269 | are still used. The default is | 293 | are still used. |
294 | The default is | ||
270 | .Dq yes . | 295 | .Dq yes . |
271 | .It Cm IgnoreUserKnownHosts | 296 | .It Cm IgnoreUserKnownHosts |
272 | Specifies whether | 297 | Specifies whether |
@@ -279,10 +304,13 @@ The default is | |||
279 | .Dq no . | 304 | .Dq no . |
280 | .It Cm KeepAlive | 305 | .It Cm KeepAlive |
281 | Specifies whether the system should send keepalive messages to the | 306 | Specifies whether the system should send keepalive messages to the |
282 | other side. If they are sent, death of the connection or crash of one | 307 | other side. |
283 | of the machines will be properly noticed. However, this means that | 308 | If they are sent, death of the connection or crash of one |
309 | of the machines will be properly noticed. | ||
310 | However, this means that | ||
284 | connections will die if the route is down temporarily, and some people | 311 | connections will die if the route is down temporarily, and some people |
285 | find it annoying. On the other hand, if keepalives are not send, | 312 | find it annoying. |
313 | On the other hand, if keepalives are not send, | ||
286 | sessions may hang indefinitely on the server, leaving | 314 | sessions may hang indefinitely on the server, leaving |
287 | .Dq ghost | 315 | .Dq ghost |
288 | users and consuming server resources. | 316 | users and consuming server resources. |
@@ -290,25 +318,27 @@ users and consuming server resources. | |||
290 | The default is | 318 | The 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 |
293 | if the network goes down or the client host reboots. This avoids | 321 | if the network goes down or the client host reboots. |
294 | infinitely hanging sessions. | 322 | This avoids infinitely hanging sessions. |
295 | .Pp | 323 | .Pp |
296 | To disable keepalives, the value should be set to | 324 | To disable keepalives, the value should be set to |
297 | .Dq no | 325 | .Dq no |
298 | in both the server and the client configuration files. | 326 | in both the server and the client configuration files. |
299 | .It Cm KerberosAuthentication | 327 | .It Cm KerberosAuthentication |
300 | Specifies whether Kerberos authentication is allowed. This can | 328 | Specifies whether Kerberos authentication is allowed. |
301 | be in the form of a Kerberos ticket, or if | 329 | This can be in the form of a Kerberos ticket, or if |
302 | .Cm PasswordAuthentication | 330 | .Cm PasswordAuthentication |
303 | is yes, the password provided by the user will be validated through | 331 | is yes, the password provided by the user will be validated through |
304 | the Kerberos KDC. Default is | 332 | the Kerberos KDC. |
333 | Default is | ||
305 | .Dq yes . | 334 | .Dq yes . |
306 | .It Cm KerberosOrLocalPasswd | 335 | .It Cm KerberosOrLocalPasswd |
307 | If set then if password authentication through Kerberos fails then | 336 | If set then if password authentication through Kerberos fails then |
308 | the password will be validated via any additional local mechanism | 337 | the password will be validated via any additional local mechanism |
309 | such as | 338 | such as |
310 | .Pa /etc/passwd | 339 | .Pa /etc/passwd |
311 | or SecurID. Default is | 340 | or SecurID. |
341 | Default is | ||
312 | .Dq yes . | 342 | .Dq yes . |
313 | .It Cm KerberosTgtPassing | 343 | .It Cm KerberosTgtPassing |
314 | Specifies whether a Kerberos TGT may be forwarded to the server. | 344 | Specifies whether a Kerberos TGT may be forwarded to the server. |
@@ -317,15 +347,18 @@ Default is | |||
317 | as this only works when the Kerberos KDC is actually an AFS kaserver. | 347 | as this only works when the Kerberos KDC is actually an AFS kaserver. |
318 | .It Cm KerberosTicketCleanup | 348 | .It Cm KerberosTicketCleanup |
319 | Specifies whether to automatically destroy the user's ticket cache | 349 | Specifies whether to automatically destroy the user's ticket cache |
320 | file on logout. Default is | 350 | file on logout. |
351 | Default is | ||
321 | .Dq yes . | 352 | .Dq yes . |
322 | .It Cm KeyRegenerationInterval | 353 | .It Cm KeyRegenerationInterval |
323 | The server key is automatically regenerated after this many seconds | 354 | The 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). |
356 | The purpose of regeneration is to prevent | ||
325 | decrypting captured sessions by later breaking into the machine and | 357 | decrypting captured sessions by later breaking into the machine and |
326 | stealing the keys. The key is never stored anywhere. If the value is | 358 | stealing the keys. |
327 | 0, the key is never regenerated. The default is 3600 | 359 | The key is never stored anywhere. |
328 | (seconds). | 360 | If the value is 0, the key is never regenerated. |
361 | The default is 3600 (seconds). | ||
329 | .It Cm ListenAddress | 362 | .It Cm ListenAddress |
330 | Specifies what local address | 363 | Specifies what local address |
331 | .Nm | 364 | .Nm |
@@ -337,7 +370,8 @@ Additionally, the | |||
337 | options must precede this option. | 370 | options must precede this option. |
338 | .It Cm LoginGraceTime | 371 | .It Cm LoginGraceTime |
339 | The server disconnects after this time if the user has not | 372 | The server disconnects after this time if the user has not |
340 | successfully logged in. If the value is 0, there is no time limit. | 373 | successfully logged in. |
374 | If the value is 0, there is no time limit. | ||
341 | The default is 600 (seconds). | 375 | The default is 600 (seconds). |
342 | .It Cm LogLevel | 376 | .It Cm LogLevel |
343 | Gives the verbosity level that is used when logging messages from | 377 | Gives 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 |
355 | When password authentication is allowed, it specifies whether the | 389 | When password authentication is allowed, it specifies whether the |
356 | server allows login to accounts with empty password strings. The default | 390 | server allows login to accounts with empty password strings. |
357 | is | 391 | The default is |
358 | .Dq no . | 392 | .Dq no . |
359 | .It Cm PermitRootLogin | 393 | .It Cm PermitRootLogin |
360 | Specifies whether the root can log in using | 394 | Specifies whether the root can log in using |
@@ -379,24 +413,27 @@ normally not allowed). | |||
379 | .It Cm Port | 413 | .It Cm Port |
380 | Specifies the port number that | 414 | Specifies the port number that |
381 | .Nm | 415 | .Nm |
382 | listens on. The default is 22. | 416 | listens on. |
417 | The default is 22. | ||
383 | Multiple options of this type are permitted. | 418 | Multiple options of this type are permitted. |
384 | .It Cm PrintMotd | 419 | .It Cm PrintMotd |
385 | Specifies whether | 420 | Specifies whether |
386 | .Nm | 421 | .Nm |
387 | should print | 422 | should print |
388 | .Pa /etc/motd | 423 | .Pa /etc/motd |
389 | when a user logs in interactively. (On some systems it is also | 424 | when a user logs in interactively. |
390 | printed by the shell, | 425 | (On some systems it is also printed by the shell, |
391 | .Pa /etc/profile , | 426 | .Pa /etc/profile , |
392 | or equivalent.) The default is | 427 | or equivalent.) |
428 | The default is | ||
393 | .Dq yes . | 429 | .Dq yes . |
394 | .It Cm RandomSeed | 430 | .It Cm RandomSeed |
395 | Obsolete. Random number generation uses other techniques. | 431 | Obsolete. |
432 | Random number generation uses other techniques. | ||
396 | .It Cm RhostsAuthentication | 433 | .It Cm RhostsAuthentication |
397 | Specifies whether authentication using rhosts or /etc/hosts.equiv | 434 | Specifies whether authentication using rhosts or /etc/hosts.equiv |
398 | files is sufficient. Normally, this method should not be permitted | 435 | files is sufficient. |
399 | because it is insecure. | 436 | Normally, this method should not be permitted because it is insecure. |
400 | .Cm RhostsRSAAuthentication | 437 | .Cm RhostsRSAAuthentication |
401 | should be used | 438 | should be used |
402 | instead, because it performs RSA-based host authentication in addition | 439 | instead, 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 |
407 | Specifies whether rhosts or /etc/hosts.equiv authentication together | 444 | Specifies whether rhosts or /etc/hosts.equiv authentication together |
408 | with successful RSA host authentication is allowed. The default is | 445 | with successful RSA host authentication is allowed. |
446 | The default is | ||
409 | .Dq no . | 447 | .Dq no . |
410 | .It Cm RSAAuthentication | 448 | .It Cm RSAAuthentication |
411 | Specifies whether pure RSA authentication is allowed. The default is | 449 | Specifies whether pure RSA authentication is allowed. |
450 | The default is | ||
412 | .Dq yes . | 451 | .Dq yes . |
413 | .It Cm ServerKeyBits | 452 | .It Cm ServerKeyBits |
414 | Defines the number of bits in the server key. The minimum value is | 453 | Defines the number of bits in the server key. |
415 | 512, and the default is 768. | 454 | The minimum value is 512, and the default is 768. |
416 | .It Cm SkeyAuthentication | 455 | .It Cm SkeyAuthentication |
417 | Specifies whether | 456 | Specifies whether |
418 | .Xr skey 1 | 457 | .Xr skey 1 |
419 | authentication is allowed. The default is | 458 | authentication is allowed. |
459 | The default is | ||
420 | .Dq yes . | 460 | .Dq yes . |
421 | Note that s/key authentication is enabled only if | 461 | Note that s/key authentication is enabled only if |
422 | .Cm PasswordAuthentication | 462 | .Cm PasswordAuthentication |
@@ -425,29 +465,34 @@ is allowed, too. | |||
425 | Specifies whether | 465 | Specifies whether |
426 | .Nm | 466 | .Nm |
427 | should check file modes and ownership of the | 467 | should check file modes and ownership of the |
428 | user's files and home directory before accepting login. This | 468 | user's files and home directory before accepting login. |
429 | is normally desirable because novices sometimes accidentally leave their | 469 | This is normally desirable because novices sometimes accidentally leave their |
430 | directory or files world-writable. The default is | 470 | directory or files world-writable. |
471 | The default is | ||
431 | .Dq yes . | 472 | .Dq yes . |
432 | .It Cm SyslogFacility | 473 | .It Cm SyslogFacility |
433 | Gives the facility code that is used when logging messages from | 474 | Gives the facility code that is used when logging messages from |
434 | .Nm sshd . | 475 | .Nm sshd . |
435 | The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, | 476 | The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, |
436 | LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. | 477 | LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. |
478 | The default is AUTH. | ||
437 | .It Cm UseLogin | 479 | .It Cm UseLogin |
438 | Specifies whether | 480 | Specifies whether |
439 | .Xr login 1 | 481 | .Xr login 1 |
440 | is used. The default is | 482 | is used. |
483 | The default is | ||
441 | .Dq no . | 484 | .Dq no . |
442 | .It Cm X11DisplayOffset | 485 | .It Cm X11DisplayOffset |
443 | Specifies the first display number available for | 486 | Specifies the first display number available for |
444 | .Nm sshd Ns 's | 487 | .Nm sshd Ns 's |
445 | X11 forwarding. This prevents | 488 | X11 forwarding. |
489 | This prevents | ||
446 | .Nm | 490 | .Nm |
447 | from interfering with real X11 servers. | 491 | from interfering with real X11 servers. |
448 | The default is 10. | 492 | The default is 10. |
449 | .It Cm X11Forwarding | 493 | .It Cm X11Forwarding |
450 | Specifies whether X11 forwarding is permitted. The default is | 494 | Specifies whether X11 forwarding is permitted. |
495 | The default is | ||
451 | .Dq no . | 496 | .Dq no . |
452 | Note that disabling X11 forwarding does not improve security in any | 497 | Note that disabling X11 forwarding does not improve security in any |
453 | way, as users can always install their own forwarders. | 498 | way, as users can always install their own forwarders. |
@@ -489,7 +534,8 @@ If | |||
489 | exists, runs it; else if | 534 | exists, runs it; else if |
490 | .Pa /etc/sshrc | 535 | .Pa /etc/sshrc |
491 | exists, runs | 536 | exists, runs |
492 | it; otherwise runs xauth. The | 537 | it; otherwise runs xauth. |
538 | The | ||
493 | .Dq rc | 539 | .Dq rc |
494 | files are given the X11 | 540 | files are given the X11 |
495 | authentication protocol and cookie in standard input. | 541 | authentication protocol and cookie in standard input. |
@@ -500,12 +546,15 @@ Runs user's shell or command. | |||
500 | The | 546 | The |
501 | .Pa $HOME/.ssh/authorized_keys | 547 | .Pa $HOME/.ssh/authorized_keys |
502 | file lists the RSA keys that are | 548 | file lists the RSA keys that are |
503 | permitted for RSA authentication. Each line of the file contains one | 549 | permitted for RSA authentication. |
550 | Each line of the file contains one | ||
504 | key (empty lines and lines starting with a | 551 | key (empty lines and lines starting with a |
505 | .Ql # | 552 | .Ql # |
506 | are ignored as | 553 | are ignored as |
507 | comments). Each line consists of the following fields, separated by | 554 | comments). |
508 | spaces: options, bits, exponent, modulus, comment. The options field | 555 | Each line consists of the following fields, separated by |
556 | spaces: options, bits, exponent, modulus, comment. | ||
557 | The options field | ||
509 | is optional; its presence is determined by whether the line starts | 558 | is optional; its presence is determined by whether the line starts |
510 | with a number or not (the option field never starts with a number). | 559 | with a number or not (the option field never starts with a number). |
511 | The bits, exponent, modulus and comment fields give the RSA key; the | 560 | The 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 | |||
513 | user to identify the key). | 562 | user to identify the key). |
514 | .Pp | 563 | .Pp |
515 | Note that lines in this file are usually several hundred bytes long | 564 | Note 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). |
517 | them in; instead, copy the | 566 | You don't want to type them in; instead, copy the |
518 | .Pa identity.pub | 567 | .Pa identity.pub |
519 | file and edit it. | 568 | file and edit it. |
520 | .Pp | 569 | .Pp |
521 | The options (if present) consists of comma-separated option | 570 | The options (if present) consists of comma-separated option |
522 | specifications. No spaces are permitted, except within double quotes. | 571 | specifications. |
572 | No spaces are permitted, except within double quotes. | ||
523 | The following option specifications are supported: | 573 | The 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" |
526 | Specifies that in addition to RSA authentication, the canonical name | 576 | Specifies that in addition to RSA authentication, the canonical name |
527 | of the remote host must be present in the comma-separated list of | 577 | of the remote host must be present in the comma-separated list of |
528 | patterns ('*' and '?' serve as wildcards). The list may also contain | 578 | patterns |
529 | patterns negated by prefixing them with '!'; if the canonical host | 579 | .Pf ( Ql * |
530 | name matches a negated pattern, the key is not accepted. The purpose | 580 | and |
581 | .Ql ? | ||
582 | serve as wildcards). | ||
583 | The list may also contain | ||
584 | patterns negated by prefixing them with | ||
585 | .Ql ! ; | ||
586 | if the canonical host name matches a negated pattern, the key is not accepted. | ||
587 | The purpose | ||
531 | of this option is to optionally increase security: RSA authentication | 588 | of this option is to optionally increase security: RSA authentication |
532 | by itself does not trust the network or name servers or anything (but | 589 | by itself does not trust the network or name servers or anything (but |
533 | the key); however, if somebody somehow steals the key, the key | 590 | the key); however, if somebody somehow steals the key, the key |
534 | permits an intruder to log in from anywhere in the world. This | 591 | permits an intruder to log in from anywhere in the world. |
535 | additional option makes using a stolen key more difficult (name | 592 | This additional option makes using a stolen key more difficult (name |
536 | servers and/or routers would have to be compromised in addition to | 593 | servers and/or routers would have to be compromised in addition to |
537 | just the key). | 594 | just the key). |
538 | .It Cm command="command" | 595 | .It Cm command="command" |
539 | Specifies that the command is executed whenever this key is used for | 596 | Specifies that the command is executed whenever this key is used for |
540 | authentication. The command supplied by the user (if any) is ignored. | 597 | authentication. |
598 | The command supplied by the user (if any) is ignored. | ||
541 | The command is run on a pty if the connection requests a pty; | 599 | The command is run on a pty if the connection requests a pty; |
542 | otherwise it is run without a tty. A quote may be included in the | 600 | otherwise it is run without a tty. |
543 | command by quoting it with a backslash. This option might be useful | 601 | A quote may be included in the command by quoting it with a backslash. |
544 | to restrict certain RSA keys to perform just a specific operation. An | 602 | This option might be useful |
545 | example might be a key that permits remote backups but nothing | 603 | to restrict certain RSA keys to perform just a specific operation. |
546 | else. Notice that the client may specify TCP/IP and/or X11 | 604 | An example might be a key that permits remote backups but nothing else. |
605 | Notice that the client may specify TCP/IP and/or X11 | ||
547 | forwardings unless they are explicitly prohibited. | 606 | forwardings unless they are explicitly prohibited. |
548 | .It Cm environment="NAME=value" | 607 | .It Cm environment="NAME=value" |
549 | Specifies that the string is to be added to the environment when | 608 | Specifies that the string is to be added to the environment when |
550 | logging in using this key. Environment variables set this way | 609 | logging in using this key. |
551 | override other default environment values. Multiple options of this | 610 | Environment variables set this way |
552 | type are permitted. | 611 | override other default environment values. |
612 | Multiple options of this type are permitted. | ||
553 | .It Cm no-port-forwarding | 613 | .It Cm no-port-forwarding |
554 | Forbids TCP/IP forwarding when this key is used for authentication. | 614 | Forbids TCP/IP forwarding when this key is used for authentication. |
555 | Any port forward requests by the client will return an error. This | 615 | Any port forward requests by the client will return an error. |
556 | might be used, e.g., in connection with the | 616 | This might be used, e.g., in connection with the |
557 | .Cm command | 617 | .Cm command |
558 | option. | 618 | option. |
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 |
577 | and | 637 | and |
578 | .Pa $HOME/.ssh/known_hosts | 638 | .Pa $HOME/.ssh/known_hosts |
579 | files contain host public keys for all known hosts. The global file should | 639 | files contain host public keys for all known hosts. |
580 | be prepared by the admistrator (optional), and the per-user file is | 640 | The global file should |
641 | be prepared by the administrator (optional), and the per-user file is | ||
581 | maintained automatically: whenever the user connects an unknown host | 642 | maintained automatically: whenever the user connects an unknown host |
582 | its key is added to the per-user file. | 643 | its key is added to the per-user file. |
583 | .Pp | 644 | .Pp |
584 | Each line in these files contains the following fields: hostnames, | 645 | Each line in these files contains the following fields: hostnames, |
585 | bits, exponent, modulus, comment. The fields are separated by spaces. | 646 | bits, exponent, modulus, comment. |
647 | The fields are separated by spaces. | ||
586 | .Pp | 648 | .Pp |
587 | Hostnames is a comma-separated list of patterns ('*' and '?' act as | 649 | Hostnames is a comma-separated list of patterns ('*' and '?' act as |
588 | wildcards); each pattern in turn is matched against the canonical host | 650 | wildcards); each pattern in turn is matched against the canonical host |
589 | name (when authenticating a client) or against the user-supplied | 651 | name (when authenticating a client) or against the user-supplied |
590 | name (when authenticating a server). A pattern may also be preceded | 652 | name (when authenticating a server). |
591 | by | 653 | A pattern may also be preceded by |
592 | .Ql ! | 654 | .Ql ! |
593 | to indicate negation: if the host name matches a negated | 655 | to indicate negation: if the host name matches a negated |
594 | pattern, it is not accepted (by that line) even if it matched another | 656 | pattern, it is not accepted (by that line) even if it matched another |
@@ -604,10 +666,13 @@ Lines starting with | |||
604 | and empty lines are ignored as comments. | 666 | and empty lines are ignored as comments. |
605 | .Pp | 667 | .Pp |
606 | When performing host authentication, authentication is accepted if any | 668 | When performing host authentication, authentication is accepted if any |
607 | matching line has the proper key. It is thus permissible (but not | 669 | matching line has the proper key. |
670 | It is thus permissible (but not | ||
608 | recommended) to have several lines or different host keys for the same | 671 | recommended) to have several lines or different host keys for the same |
609 | names. This will inevitably happen when short forms of host names | 672 | names. |
610 | from different domains are put in the file. It is possible | 673 | This will inevitably happen when short forms of host names |
674 | from different domains are put in the file. | ||
675 | It is possible | ||
611 | that the files contain conflicting information; authentication is | 676 | that the files contain conflicting information; authentication is |
612 | accepted if valid information can be found from either file. | 677 | accepted 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 |
637 | Contains the public part of the host key. | 702 | Contains the public part of the host key. |
638 | This file should be world-readable but writable only by | 703 | This file should be world-readable but writable only by |
639 | root. Its contents should match the private part. This file is not | 704 | root. |
705 | Its contents should match the private part. | ||
706 | This file is not | ||
640 | really used for anything; it is only provided for the convenience of | 707 | really used for anything; it is only provided for the convenience of |
641 | the user so its contents can be copied to known hosts files. | 708 | the user so its contents can be copied to known hosts files. |
642 | These two files are created using | 709 | These two files are created using |
@@ -646,21 +713,22 @@ Contains the process ID of the | |||
646 | .Nm | 713 | .Nm |
647 | listening for connections (if there are several daemons running | 714 | listening for connections (if there are several daemons running |
648 | concurrently for different ports, this contains the pid of the one | 715 | concurrently for different ports, this contains the pid of the one |
649 | started last). The contents of this file are not sensitive; it can be | 716 | started last). |
650 | world-readable. | 717 | The 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 |
652 | Lists the RSA keys that can be used to log into the user's account. | 719 | Lists the RSA keys that can be used to log into the user's account. |
653 | This file must be readable by root (which may on some machines imply | 720 | This file must be readable by root (which may on some machines imply |
654 | it being world-readable if the user's home directory resides on an NFS | 721 | it being world-readable if the user's home directory resides on an NFS |
655 | volume). It is recommended that it not be accessible by others. The | 722 | volume). |
656 | format of this file is described above. | 723 | It is recommended that it not be accessible by others. |
724 | The 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" |
658 | These files are consulted when using rhosts with RSA host | 726 | These files are consulted when using rhosts with RSA host |
659 | authentication to check the public key of the host. The key must be | 727 | authentication to check the public key of the host. |
660 | listed in one of these files to be accepted. | 728 | The key must be listed in one of these files to be accepted. |
661 | The client uses the same files | 729 | The client uses the same files |
662 | to verify that the remote host is the one we intended to | 730 | to verify that the remote host is the one we intended to connect. |
663 | connect. These files should be writable only by root/the owner. | 731 | These files should be writable only by root/the owner. |
664 | .Pa /etc/ssh_known_hosts | 732 | .Pa /etc/ssh_known_hosts |
665 | should be world-readable, and | 733 | should 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 |
669 | If this file exists, | 737 | If this file exists, |
670 | .Nm | 738 | .Nm |
671 | refuses to let anyone except root log in. The contents of the file | 739 | refuses to let anyone except root log in. |
740 | The contents of the file | ||
672 | are displayed to anyone trying to log in, and non-root connections are | 741 | are displayed to anyone trying to log in, and non-root connections are |
673 | refused. The file should be world-readable. | 742 | refused. |
743 | The file should be world-readable. | ||
674 | .It Pa /etc/hosts.allow, /etc/hosts.deny | 744 | .It Pa /etc/hosts.allow, /etc/hosts.deny |
675 | If compiled with | 745 | If 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 |
680 | This file contains host-username pairs, separated by a space, one per | 750 | This file contains host-username pairs, separated by a space, one per |
681 | line. The given user on the corresponding host is permitted to log in | 751 | line. |
682 | without password. The same file is used by rlogind and rshd. | 752 | The given user on the corresponding host is permitted to log in |
753 | without password. | ||
754 | The same file is used by rlogind and rshd. | ||
683 | The file must | 755 | The file must |
684 | be writable only by the user; it is recommended that it not be | 756 | be writable only by the user; it is recommended that it not be |
685 | accessible by others. | 757 | accessible by others. |
686 | .Pp | 758 | .Pp |
687 | If is also possible to use netgroups in the file. Either host or user | 759 | If is also possible to use netgroups in the file. |
760 | Either host or user | ||
688 | name may be of the form +@groupname to specify all hosts or all users | 761 | name may be of the form +@groupname to specify all hosts or all users |
689 | in the group. | 762 | in 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 |
697 | This file is used during | 770 | This file is used during |
698 | .Pa .rhosts | 771 | .Pa .rhosts |
699 | authentication. In the | 772 | authentication. |
700 | simplest form, this file contains host names, one per line. Users on | 773 | In the simplest form, this file contains host names, one per line. |
774 | Users on | ||
701 | those hosts are permitted to log in without a password, provided they | 775 | those hosts are permitted to log in without a password, provided they |
702 | have the same user name on both machines. The host name may also be | 776 | have the same user name on both machines. |
777 | The host name may also be | ||
703 | followed by a user name; such users are permitted to log in as | 778 | followed by a user name; such users are permitted to log in as |
704 | .Em any | 779 | .Em any |
705 | user on this machine (except root). Additionally, the syntax | 780 | user on this machine (except root). |
781 | Additionally, the syntax | ||
706 | .Dq +@group | 782 | .Dq +@group |
707 | can be used to specify netgroups. Negated entries start with | 783 | can be used to specify netgroups. |
784 | Negated entries start with | ||
708 | .Ql \&- . | 785 | .Ql \&- . |
709 | .Pp | 786 | .Pp |
710 | If the client host/user is successfully matched in this file, login is | 787 | If the client host/user is successfully matched in this file, login is |
711 | automatically permitted provided the client and server user names are the | 788 | automatically permitted provided the client and server user names are the |
712 | same. Additionally, successful RSA host authentication is normally | 789 | same. |
713 | required. This file must be writable only by root; it is recommended | 790 | Additionally, successful RSA host authentication is normally required. |
791 | This file must be writable only by root; it is recommended | ||
714 | that it be world-readable. | 792 | that 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. | |||
718 | Beware that it really means that the named user(s) can log in as | 796 | Beware that it really means that the named user(s) can log in as |
719 | .Em anybody , | 797 | .Em anybody , |
720 | which includes bin, daemon, adm, and other accounts that own critical | 798 | which includes bin, daemon, adm, and other accounts that own critical |
721 | binaries and directories. Using a user name practically grants the | 799 | binaries and directories. |
722 | user root access. The only valid use for user names that I can think | 800 | Using a user name practically grants the user root access. |
801 | The only valid use for user names that I can think | ||
723 | of is in negative entries. | 802 | of is in negative entries. |
724 | .Pp | 803 | .Pp |
725 | Note that this warning also applies to rsh/rlogin. | 804 | Note that this warning also applies to rsh/rlogin. |
@@ -729,18 +808,20 @@ This is processed exactly as | |||
729 | However, this file may be useful in environments that want to run both | 808 | However, this file may be useful in environments that want to run both |
730 | rsh/rlogin and ssh. | 809 | rsh/rlogin and ssh. |
731 | .It Pa $HOME/.ssh/environment | 810 | .It Pa $HOME/.ssh/environment |
732 | This file is read into the environment at login (if it exists). It | 811 | This file is read into the environment at login (if it exists). |
733 | can only contain empty lines, comment lines (that start with | 812 | It can only contain empty lines, comment lines (that start with |
734 | .Ql # ) , | 813 | .Ql # ) , |
735 | and assignment lines of the form name=value. The file should be writable | 814 | and assignment lines of the form name=value. |
815 | The file should be writable | ||
736 | only by the user; it need not be readable by anyone else. | 816 | only by the user; it need not be readable by anyone else. |
737 | .It Pa $HOME/.ssh/rc | 817 | .It Pa $HOME/.ssh/rc |
738 | If this file exists, it is run with /bin/sh after reading the | 818 | If this file exists, it is run with /bin/sh after reading the |
739 | environment files but before starting the user's shell or command. If | 819 | environment files but before starting the user's shell or command. |
740 | X11 spoofing is in use, this will receive the "proto cookie" pair in | 820 | If X11 spoofing is in use, this will receive the "proto cookie" pair in |
741 | standard input (and | 821 | standard input (and |
742 | .Ev DISPLAY | 822 | .Ev DISPLAY |
743 | in environment). This must call | 823 | in environment). |
824 | This must call | ||
744 | .Xr xauth 1 | 825 | .Xr xauth 1 |
745 | in that case. | 826 | in that case. |
746 | .Pp | 827 | .Pp |
@@ -763,12 +844,13 @@ readable by anyone else. | |||
763 | Like | 844 | Like |
764 | .Pa $HOME/.ssh/rc . | 845 | .Pa $HOME/.ssh/rc . |
765 | This can be used to specify | 846 | This can be used to specify |
766 | machine-specific login-time initializations globally. This file | 847 | machine-specific login-time initializations globally. |
767 | should be writable only by root, and should be world-readable. | 848 | This file should be writable only by root, and should be world-readable. |
768 | .Sh AUTHOR | 849 | .Sh AUTHOR |
769 | OpenSSH | 850 | OpenSSH |
770 | is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, | 851 | is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, |
771 | but with bugs removed and newer features re-added. Rapidly after the | 852 | but with bugs removed and newer features re-added. |
853 | Rapidly after the | ||
772 | 1.2.12 release, newer versions of the original ssh bore successively | 854 | 1.2.12 release, newer versions of the original ssh bore successively |
773 | more restrictive licenses, and thus demand for a free version was born. | 855 | more restrictive licenses, and thus demand for a free version was born. |
774 | This version of OpenSSH | 856 | This version of OpenSSH |
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$OpenBSD: sshd.c,v 1.92 2000/03/16 20:56:15 markus Exp $"); | 14 | RCSID("$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; |