diff options
author | Colin Watson <cjwatson@debian.org> | 2010-03-31 10:46:28 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2010-03-31 10:46:28 +0100 |
commit | efd3d4522636ae029488c2e9730b60c88e257d2e (patch) | |
tree | 31e02ac3f16090ce8c53448677356b2b7f423683 /auth2-pubkey.c | |
parent | bbec4db36d464ea1d464a707625125f9fd5c7b5e (diff) | |
parent | d1a87e462e1db89f19cd960588d0c6b287cb5ccc (diff) |
* New upstream release (LP: #535029).
- After a transition period of about 10 years, this release disables SSH
protocol 1 by default. Clients and servers that need to use the
legacy protocol must explicitly enable it in ssh_config / sshd_config
or on the command-line.
- Remove the libsectok/OpenSC-based smartcard code and add support for
PKCS#11 tokens. This support is enabled by default in the Debian
packaging, since it now doesn't involve additional library
dependencies (closes: #231472, LP: #16918).
- Add support for certificate authentication of users and hosts using a
new, minimal OpenSSH certificate format (closes: #482806).
- Added a 'netcat mode' to ssh(1): "ssh -W host:port ...".
- Add the ability to revoke keys in sshd(8) and ssh(1). (For the Debian
package, this overlaps with the key blacklisting facility added in
openssh 1:4.7p1-9, but with different file formats and slightly
different scopes; for the moment, I've roughly merged the two.)
- Various multiplexing improvements, including support for requesting
port-forwardings via the multiplex protocol (closes: #360151).
- Allow setting an explicit umask on the sftp-server(8) commandline to
override whatever default the user has (closes: #496843).
- Many sftp client improvements, including tab-completion, more options,
and recursive transfer support for get/put (LP: #33378). The old
mget/mput commands never worked properly and have been removed
(closes: #270399, #428082).
- Do not prompt for a passphrase if we fail to open a keyfile, and log
the reason why the open failed to debug (closes: #431538).
- Prevent sftp from crashing when given a "-" without a command. Also,
allow whitespace to follow a "-" (closes: #531561).
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r-- | auth2-pubkey.c | 87 |
1 files changed, 82 insertions, 5 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 8cb477662..ae0638825 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.19 2008/07/03 21:46:58 otto Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -32,6 +32,8 @@ | |||
32 | #include <pwd.h> | 32 | #include <pwd.h> |
33 | #include <stdio.h> | 33 | #include <stdio.h> |
34 | #include <stdarg.h> | 34 | #include <stdarg.h> |
35 | #include <string.h> | ||
36 | #include <time.h> | ||
35 | #include <unistd.h> | 37 | #include <unistd.h> |
36 | 38 | ||
37 | #include "xmalloc.h" | 39 | #include "xmalloc.h" |
@@ -54,6 +56,7 @@ | |||
54 | #endif | 56 | #endif |
55 | #include "monitor_wrap.h" | 57 | #include "monitor_wrap.h" |
56 | #include "misc.h" | 58 | #include "misc.h" |
59 | #include "authfile.h" | ||
57 | 60 | ||
58 | /* import */ | 61 | /* import */ |
59 | extern ServerOptions options; | 62 | extern ServerOptions options; |
@@ -178,6 +181,7 @@ static int | |||
178 | user_key_allowed2(struct passwd *pw, Key *key, char *file) | 181 | user_key_allowed2(struct passwd *pw, Key *key, char *file) |
179 | { | 182 | { |
180 | char line[SSH_MAX_PUBKEY_BYTES]; | 183 | char line[SSH_MAX_PUBKEY_BYTES]; |
184 | const char *reason; | ||
181 | int found_key = 0; | 185 | int found_key = 0; |
182 | FILE *f; | 186 | FILE *f; |
183 | u_long linenum = 0; | 187 | u_long linenum = 0; |
@@ -196,11 +200,13 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) | |||
196 | } | 200 | } |
197 | 201 | ||
198 | found_key = 0; | 202 | found_key = 0; |
199 | found = key_new(key->type); | 203 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); |
200 | 204 | ||
201 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 205 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
202 | char *cp, *key_options = NULL; | 206 | char *cp, *key_options = NULL; |
203 | 207 | ||
208 | auth_clear_options(); | ||
209 | |||
204 | /* Skip leading whitespace, empty and comment lines. */ | 210 | /* Skip leading whitespace, empty and comment lines. */ |
205 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) | 211 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) |
206 | ; | 212 | ; |
@@ -227,8 +233,32 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) | |||
227 | continue; | 233 | continue; |
228 | } | 234 | } |
229 | } | 235 | } |
230 | if (key_equal(found, key) && | 236 | if (auth_parse_options(pw, key_options, file, linenum) != 1) |
231 | auth_parse_options(pw, key_options, file, linenum) == 1) { | 237 | continue; |
238 | if (key->type == KEY_RSA_CERT || key->type == KEY_DSA_CERT) { | ||
239 | if (!key_is_cert_authority) | ||
240 | continue; | ||
241 | if (!key_equal(found, key->cert->signature_key)) | ||
242 | continue; | ||
243 | debug("matching CA found: file %s, line %lu", | ||
244 | file, linenum); | ||
245 | fp = key_fingerprint(found, SSH_FP_MD5, | ||
246 | SSH_FP_HEX); | ||
247 | verbose("Found matching %s CA: %s", | ||
248 | key_type(found), fp); | ||
249 | xfree(fp); | ||
250 | if (key_cert_check_authority(key, 0, 0, pw->pw_name, | ||
251 | &reason) != 0) { | ||
252 | error("%s", reason); | ||
253 | auth_debug_add("%s", reason); | ||
254 | continue; | ||
255 | } | ||
256 | if (auth_cert_constraints(&key->cert->constraints, | ||
257 | pw) != 0) | ||
258 | continue; | ||
259 | found_key = 1; | ||
260 | break; | ||
261 | } else if (!key_is_cert_authority && key_equal(found, key)) { | ||
232 | found_key = 1; | 262 | found_key = 1; |
233 | debug("matching key found: file %s, line %lu", | 263 | debug("matching key found: file %s, line %lu", |
234 | file, linenum); | 264 | file, linenum); |
@@ -247,6 +277,47 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) | |||
247 | return found_key; | 277 | return found_key; |
248 | } | 278 | } |
249 | 279 | ||
280 | /* Authenticate a certificate key against TrustedUserCAKeys */ | ||
281 | static int | ||
282 | user_cert_trusted_ca(struct passwd *pw, Key *key) | ||
283 | { | ||
284 | char *key_fp, *ca_fp; | ||
285 | const char *reason; | ||
286 | int ret = 0; | ||
287 | |||
288 | if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) | ||
289 | return 0; | ||
290 | |||
291 | key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | ||
292 | ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | ||
293 | |||
294 | if (key_in_file(key->cert->signature_key, | ||
295 | options.trusted_user_ca_keys, 1) != 1) { | ||
296 | debug2("%s: CA %s %s is not listed in %s", __func__, | ||
297 | key_type(key->cert->signature_key), ca_fp, | ||
298 | options.trusted_user_ca_keys); | ||
299 | goto out; | ||
300 | } | ||
301 | if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) { | ||
302 | error("%s", reason); | ||
303 | auth_debug_add("%s", reason); | ||
304 | goto out; | ||
305 | } | ||
306 | if (auth_cert_constraints(&key->cert->constraints, pw) != 0) | ||
307 | goto out; | ||
308 | |||
309 | verbose("%s certificate %s allowed by trusted %s key %s", | ||
310 | key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp); | ||
311 | ret = 1; | ||
312 | |||
313 | out: | ||
314 | if (key_fp != NULL) | ||
315 | xfree(key_fp); | ||
316 | if (ca_fp != NULL) | ||
317 | xfree(ca_fp); | ||
318 | return ret; | ||
319 | } | ||
320 | |||
250 | /* check whether given key is in .ssh/authorized_keys* */ | 321 | /* check whether given key is in .ssh/authorized_keys* */ |
251 | int | 322 | int |
252 | user_key_allowed(struct passwd *pw, Key *key) | 323 | user_key_allowed(struct passwd *pw, Key *key) |
@@ -254,9 +325,15 @@ user_key_allowed(struct passwd *pw, Key *key) | |||
254 | int success; | 325 | int success; |
255 | char *file; | 326 | char *file; |
256 | 327 | ||
257 | if (reject_blacklisted_key(key, 0) == 1) | 328 | if (auth_key_is_revoked(key, 0)) |
329 | return 0; | ||
330 | if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) | ||
258 | return 0; | 331 | return 0; |
259 | 332 | ||
333 | success = user_cert_trusted_ca(pw, key); | ||
334 | if (success) | ||
335 | return success; | ||
336 | |||
260 | file = authorized_keys_file(pw); | 337 | file = authorized_keys_file(pw); |
261 | success = user_key_allowed2(pw, key, file); | 338 | success = user_key_allowed2(pw, key, file); |
262 | xfree(file); | 339 | xfree(file); |