mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-12-25 19:32:09 +00:00
- djm@cvs.openbsd.org 2010/03/04 10:36:03
[auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c] [authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h] [ssh-keygen.c ssh.1 sshconnect.c sshd_config.5] Add a TrustedUserCAKeys option to sshd_config to specify CA keys that are trusted to authenticate users (in addition than doing it per-user in authorized_keys). Add a RevokedKeys option to sshd_config and a @revoked marker to known_hosts to allow keys to me revoked and banned for user or host authentication. feedback and ok markus@
This commit is contained in:
parent
2befbad9b3
commit
1aed65eb27
13
ChangeLog
13
ChangeLog
@ -22,6 +22,19 @@
|
||||
[key.c]
|
||||
use buffer_get_string_ptr_ret() where we are checking the return
|
||||
value explicitly instead of the fatal()-causing buffer_get_string_ptr()
|
||||
- djm@cvs.openbsd.org 2010/03/04 10:36:03
|
||||
[auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c]
|
||||
[authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h]
|
||||
[ssh-keygen.c ssh.1 sshconnect.c sshd_config.5]
|
||||
Add a TrustedUserCAKeys option to sshd_config to specify CA keys that
|
||||
are trusted to authenticate users (in addition than doing it per-user
|
||||
in authorized_keys).
|
||||
|
||||
Add a RevokedKeys option to sshd_config and a @revoked marker to
|
||||
known_hosts to allow keys to me revoked and banned for user or host
|
||||
authentication.
|
||||
|
||||
feedback and ok markus@
|
||||
|
||||
20100303
|
||||
- (djm) [PROTOCOL.certkeys] Add RCS Ident
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-rh-rsa.c,v 1.42 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/* $OpenBSD: auth-rh-rsa.c,v 1.43 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -44,6 +44,9 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
|
||||
{
|
||||
HostStatus host_status;
|
||||
|
||||
if (auth_key_is_revoked(client_host_key))
|
||||
return 0;
|
||||
|
||||
/* Check if we would accept it using rhosts authentication. */
|
||||
if (!auth_rhosts(pw, cuser))
|
||||
return 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-rsa.c,v 1.73 2008/07/02 12:03:51 dtucker Exp $ */
|
||||
/* $OpenBSD: auth-rsa.c,v 1.74 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -94,6 +94,9 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
|
||||
MD5_CTX md;
|
||||
int len;
|
||||
|
||||
if (auth_key_is_revoked(key))
|
||||
return 0;
|
||||
|
||||
/* don't allow short keys */
|
||||
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
|
||||
error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
|
||||
|
31
auth.c
31
auth.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.c,v 1.84 2010/02/09 06:18:46 djm Exp $ */
|
||||
/* $OpenBSD: auth.c,v 1.85 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -69,6 +69,7 @@
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "authfile.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
/* import */
|
||||
@ -582,6 +583,34 @@ getpwnamallow(const char *user)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
|
||||
int
|
||||
auth_key_is_revoked(Key *key)
|
||||
{
|
||||
char *key_fp;
|
||||
|
||||
if (options.revoked_keys_file == NULL)
|
||||
return 0;
|
||||
|
||||
switch (key_in_file(key, options.revoked_keys_file, 0)) {
|
||||
case 0:
|
||||
/* key not revoked */
|
||||
return 0;
|
||||
case -1:
|
||||
/* Error opening revoked_keys_file: refuse all keys */
|
||||
error("Revoked keys file is unreadable: refusing public key "
|
||||
"authentication");
|
||||
return 1;
|
||||
case 1:
|
||||
/* Key revoked */
|
||||
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
error("%s key %s is revoked", key_type(key), key_fp);
|
||||
xfree(key_fp);
|
||||
return 1;
|
||||
}
|
||||
fatal("key_in_file returned junk");
|
||||
}
|
||||
|
||||
void
|
||||
auth_debug_add(const char *fmt,...)
|
||||
{
|
||||
|
3
auth.h
3
auth.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.h,v 1.64 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: auth.h,v 1.65 2010/03/04 10:36:03 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -171,6 +171,7 @@ char *authorized_keys_file(struct passwd *);
|
||||
char *authorized_keys_file2(struct passwd *);
|
||||
|
||||
FILE *auth_openkeyfile(const char *, struct passwd *, int);
|
||||
int auth_key_is_revoked(Key *);
|
||||
|
||||
HostStatus
|
||||
check_key_in_hostfiles(struct passwd *, Key *, const char *,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-hostbased.c,v 1.12 2008/07/17 08:51:07 djm Exp $ */
|
||||
/* $OpenBSD: auth2-hostbased.c,v 1.13 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -145,6 +145,9 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
|
||||
HostStatus host_status;
|
||||
int len;
|
||||
|
||||
if (auth_key_is_revoked(key))
|
||||
return 0;
|
||||
|
||||
resolvedname = get_canonical_hostname(options.use_dns);
|
||||
ipaddr = get_remote_ipaddr();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.20 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -56,6 +56,7 @@
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "misc.h"
|
||||
#include "authfile.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
@ -276,6 +277,47 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
||||
return found_key;
|
||||
}
|
||||
|
||||
/* Authenticate a certificate key against TrustedUserCAKeys */
|
||||
static int
|
||||
user_cert_trusted_ca(struct passwd *pw, Key *key)
|
||||
{
|
||||
char *key_fp, *ca_fp;
|
||||
const char *reason;
|
||||
int ret = 0;
|
||||
|
||||
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
||||
return 0;
|
||||
|
||||
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
|
||||
if (key_in_file(key->cert->signature_key,
|
||||
options.trusted_user_ca_keys, 1) != 1) {
|
||||
debug2("%s: CA %s %s is not listed in %s", __func__,
|
||||
key_type(key->cert->signature_key), ca_fp,
|
||||
options.trusted_user_ca_keys);
|
||||
goto out;
|
||||
}
|
||||
if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) {
|
||||
error("%s", reason);
|
||||
auth_debug_add("%s", reason);
|
||||
goto out;
|
||||
}
|
||||
if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
|
||||
goto out;
|
||||
|
||||
verbose("%s certificate %s allowed by trusted %s key %s",
|
||||
key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp);
|
||||
ret = 1;
|
||||
|
||||
out:
|
||||
if (key_fp != NULL)
|
||||
xfree(key_fp);
|
||||
if (ca_fp != NULL)
|
||||
xfree(ca_fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* check whether given key is in .ssh/authorized_keys* */
|
||||
int
|
||||
user_key_allowed(struct passwd *pw, Key *key)
|
||||
@ -283,6 +325,15 @@ user_key_allowed(struct passwd *pw, Key *key)
|
||||
int success;
|
||||
char *file;
|
||||
|
||||
if (auth_key_is_revoked(key))
|
||||
return 0;
|
||||
if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
|
||||
return 0;
|
||||
|
||||
success = user_cert_trusted_ca(pw, key);
|
||||
if (success)
|
||||
return success;
|
||||
|
||||
file = authorized_keys_file(pw);
|
||||
success = user_key_allowed2(pw, key, file);
|
||||
xfree(file);
|
||||
|
64
authfile.c
64
authfile.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfile.c,v 1.79 2010/01/12 00:16:47 dtucker Exp $ */
|
||||
/* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -692,3 +692,65 @@ key_load_public(const char *filename, char **commentp)
|
||||
key_free(pub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if the specified "key" is listed in the file "filename",
|
||||
* 0 if the key is not listed or -1 on error.
|
||||
* If strict_type is set then the key type must match exactly,
|
||||
* otherwise a comparison that ignores certficiate data is performed.
|
||||
*/
|
||||
int
|
||||
key_in_file(Key *key, const char *filename, int strict_type)
|
||||
{
|
||||
FILE *f;
|
||||
char line[SSH_MAX_PUBKEY_BYTES];
|
||||
char *cp;
|
||||
u_long linenum = 0;
|
||||
int ret = 0;
|
||||
Key *pub;
|
||||
int (*key_compare)(const Key *, const Key *) = strict_type ?
|
||||
key_equal : key_equal_public;
|
||||
|
||||
if ((f = fopen(filename, "r")) == NULL) {
|
||||
if (errno == ENOENT) {
|
||||
debug("%s: keyfile \"%s\" missing", __func__, filename);
|
||||
return 0;
|
||||
} else {
|
||||
error("%s: could not open keyfile \"%s\": %s", __func__,
|
||||
filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (read_keyfile_line(f, filename, line, sizeof(line),
|
||||
&linenum) != -1) {
|
||||
cp = line;
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
|
||||
;
|
||||
|
||||
/* Skip comments and empty lines */
|
||||
switch (*cp) {
|
||||
case '#':
|
||||
case '\n':
|
||||
case '\0':
|
||||
continue;
|
||||
}
|
||||
|
||||
pub = key_new(KEY_UNSPEC);
|
||||
if (key_read(pub, &cp) != 1) {
|
||||
key_free(pub);
|
||||
continue;
|
||||
}
|
||||
if (key_compare(key, pub)) {
|
||||
ret = 1;
|
||||
key_free(pub);
|
||||
break;
|
||||
}
|
||||
key_free(pub);
|
||||
}
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfile.h,v 1.13 2006/04/25 08:02:27 dtucker Exp $ */
|
||||
/* $OpenBSD: authfile.h,v 1.14 2010/03/04 10:36:03 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -22,5 +22,6 @@ Key *key_load_private(const char *, const char *, char **);
|
||||
Key *key_load_private_type(int, const char *, const char *, char **, int *);
|
||||
Key *key_load_private_pem(int, int, const char *, char **);
|
||||
int key_perm_ok(int, const char *);
|
||||
int key_in_file(Key *, const char *, int);
|
||||
|
||||
#endif
|
||||
|
102
hostfile.c
102
hostfile.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: hostfile.c,v 1.47 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -183,6 +183,41 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
|
||||
return 1;
|
||||
}
|
||||
|
||||
static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA }
|
||||
check_markers(char **cpp)
|
||||
{
|
||||
char marker[32], *sp, *cp = *cpp;
|
||||
int ret = MRK_NONE;
|
||||
|
||||
while (*cp == '@') {
|
||||
/* Only one marker is allowed */
|
||||
if (ret != MRK_NONE)
|
||||
return MRK_ERROR;
|
||||
/* Markers are terminated by whitespace */
|
||||
if ((sp = strchr(cp, ' ')) == NULL &&
|
||||
(sp = strchr(cp, '\t')) == NULL)
|
||||
return MRK_ERROR;
|
||||
/* Extract marker for comparison */
|
||||
if (sp <= cp + 1 || sp >= cp + sizeof(marker))
|
||||
return MRK_ERROR;
|
||||
memcpy(marker, cp, sp - cp);
|
||||
marker[sp - cp] = '\0';
|
||||
if (strcmp(marker, CA_MARKER) == 0)
|
||||
ret = MRK_CA;
|
||||
else if (strcmp(marker, REVOKE_MARKER) == 0)
|
||||
ret = MRK_REVOKE;
|
||||
else
|
||||
return MRK_ERROR;
|
||||
|
||||
/* Skip past marker and any whitespace that follows it */
|
||||
cp = sp;
|
||||
for (; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
}
|
||||
*cpp = cp;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the given host (which must be in all lowercase) is already
|
||||
* in the list of our known hosts. Returns HOST_OK if the host is known and
|
||||
@ -195,17 +230,21 @@ hostfile_check_key(int bits, const Key *key, const char *host, const char *filen
|
||||
|
||||
static HostStatus
|
||||
check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
const char *host, const Key *key, int keytype, Key *found, int *numret)
|
||||
const char *host, const Key *key, int keytype, Key *found,
|
||||
int want_revocation, int *numret)
|
||||
{
|
||||
FILE *f;
|
||||
char line[8192];
|
||||
int linenum = 0, want_cert = key_is_cert(key);
|
||||
int want, have, linenum = 0, want_cert = key_is_cert(key);
|
||||
u_int kbits;
|
||||
char *cp, *cp2, *hashed_host;
|
||||
HostStatus end_return;
|
||||
|
||||
debug3("check_host_in_hostfile: host %s filename %s", host, filename);
|
||||
|
||||
if (want_revocation && (key == NULL || keytype != 0 || found != NULL))
|
||||
fatal("%s: invalid arguments", __func__);
|
||||
|
||||
/* Open the file containing the list of known hosts. */
|
||||
f = fopen(filename, "r");
|
||||
if (!f)
|
||||
@ -229,21 +268,18 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
if (!*cp || *cp == '#' || *cp == '\n')
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Ignore CA keys when looking for raw keys.
|
||||
* Ignore raw keys when looking for CA keys.
|
||||
*/
|
||||
if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 &&
|
||||
(cp[sizeof(CA_MARKER) - 1] == ' ' ||
|
||||
cp[sizeof(CA_MARKER) - 1] == '\t')) {
|
||||
if (want_cert) {
|
||||
/* Skip the marker and following whitespace */
|
||||
cp += sizeof(CA_MARKER);
|
||||
for (; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
} else
|
||||
continue;
|
||||
} else if (want_cert)
|
||||
if (want_revocation)
|
||||
want = MRK_REVOKE;
|
||||
else if (want_cert)
|
||||
want = MRK_CA;
|
||||
else
|
||||
want = MRK_NONE;
|
||||
|
||||
if ((have = check_markers(&cp)) == MRK_ERROR) {
|
||||
verbose("%s: invalid marker at %s:%d",
|
||||
__func__, filename, linenum);
|
||||
continue;
|
||||
} else if (want != have)
|
||||
continue;
|
||||
|
||||
/* Find the end of the host name portion. */
|
||||
@ -267,6 +303,9 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
/* Got a match. Skip host name. */
|
||||
cp = cp2;
|
||||
|
||||
if (want_revocation)
|
||||
found = key_new(KEY_UNSPEC);
|
||||
|
||||
/*
|
||||
* Extract the key from the line. This will skip any leading
|
||||
* whitespace. Ignore badly formatted lines.
|
||||
@ -289,6 +328,24 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
|
||||
if (!hostfile_check_key(kbits, found, host, filename, linenum))
|
||||
continue;
|
||||
|
||||
if (want_revocation) {
|
||||
if (key_is_cert(key) &&
|
||||
key_equal_public(key->cert->signature_key, found)) {
|
||||
verbose("check_host_in_hostfile: revoked CA "
|
||||
"line %d", linenum);
|
||||
key_free(found);
|
||||
return HOST_REVOKED;
|
||||
}
|
||||
if (key_equal_public(key, found)) {
|
||||
verbose("check_host_in_hostfile: revoked key "
|
||||
"line %d", linenum);
|
||||
key_free(found);
|
||||
return HOST_REVOKED;
|
||||
}
|
||||
key_free(found);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if the current key is the same as the given key. */
|
||||
if (want_cert && key_equal(key->cert->signature_key, found)) {
|
||||
/* Found CA cert for key */
|
||||
@ -325,8 +382,11 @@ check_host_in_hostfile(const char *filename, const char *host, const Key *key,
|
||||
{
|
||||
if (key == NULL)
|
||||
fatal("no key to look up");
|
||||
return (check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
|
||||
found, numret));
|
||||
if (check_host_in_hostfile_by_key_or_type(filename, host,
|
||||
key, 0, NULL, 1, NULL) == HOST_REVOKED)
|
||||
return HOST_REVOKED;
|
||||
return check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
|
||||
found, 0, numret);
|
||||
}
|
||||
|
||||
int
|
||||
@ -334,7 +394,7 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
|
||||
int keytype, Key *found, int *numret)
|
||||
{
|
||||
return (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
|
||||
keytype, found, numret) == HOST_FOUND);
|
||||
keytype, found, 0, numret) == HOST_FOUND);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: hostfile.h,v 1.17 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.h,v 1.18 2010/03/04 10:36:03 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -15,7 +15,7 @@
|
||||
#define HOSTFILE_H
|
||||
|
||||
typedef enum {
|
||||
HOST_OK, HOST_NEW, HOST_CHANGED, HOST_FOUND
|
||||
HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND
|
||||
} HostStatus;
|
||||
|
||||
int hostfile_read_key(char **, u_int *, Key *);
|
||||
@ -29,6 +29,7 @@ int lookup_key_in_hostfile_by_type(const char *, const char *,
|
||||
#define HASH_DELIM '|'
|
||||
|
||||
#define CA_MARKER "@cert-authority"
|
||||
#define REVOKE_MARKER "@revoked"
|
||||
|
||||
char *host_hash(const char *, const char *, u_int);
|
||||
|
||||
|
19
servconf.c
19
servconf.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.c,v 1.203 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.204 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -129,6 +129,8 @@ initialize_server_options(ServerOptions *options)
|
||||
options->adm_forced_command = NULL;
|
||||
options->chroot_directory = NULL;
|
||||
options->zero_knowledge_password_authentication = -1;
|
||||
options->revoked_keys_file = NULL;
|
||||
options->trusted_user_ca_keys = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -308,6 +310,7 @@ typedef enum {
|
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
sRevokedKeys, sTrustedUserCAKeys,
|
||||
sDeprecated, sUnsupported
|
||||
} ServerOpCodes;
|
||||
|
||||
@ -427,6 +430,8 @@ static struct {
|
||||
{ "forcecommand", sForceCommand, SSHCFG_ALL },
|
||||
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
|
||||
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
|
||||
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
|
||||
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
|
||||
{ NULL, sBadOption, 0 }
|
||||
};
|
||||
|
||||
@ -1323,6 +1328,14 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
*charptr = xstrdup(arg);
|
||||
break;
|
||||
|
||||
case sTrustedUserCAKeys:
|
||||
charptr = &options->trusted_user_ca_keys;
|
||||
goto parse_filename;
|
||||
|
||||
case sRevokedKeys:
|
||||
charptr = &options->revoked_keys_file;
|
||||
goto parse_filename;
|
||||
|
||||
case sDeprecated:
|
||||
logit("%s line %d: Deprecated option %s",
|
||||
filename, linenum, arg);
|
||||
@ -1437,6 +1450,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
return;
|
||||
M_CP_STROPT(adm_forced_command);
|
||||
M_CP_STROPT(chroot_directory);
|
||||
M_CP_STROPT(trusted_user_ca_keys);
|
||||
M_CP_STROPT(revoked_keys_file);
|
||||
}
|
||||
|
||||
#undef M_CP_INTOPT
|
||||
@ -1656,6 +1671,8 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
|
||||
dump_cfg_string(sForceCommand, o->adm_forced_command);
|
||||
dump_cfg_string(sChrootDirectory, o->chroot_directory);
|
||||
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
|
||||
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
|
||||
|
||||
/* string arguments requiring a lookup */
|
||||
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.h,v 1.91 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.92 2010/03/04 10:36:03 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -154,6 +154,8 @@ typedef struct {
|
||||
int num_permitted_opens;
|
||||
|
||||
char *chroot_directory;
|
||||
char *revoked_keys_file;
|
||||
char *trusted_user_ca_keys;
|
||||
} ServerOptions;
|
||||
|
||||
void initialize_server_options(ServerOptions *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-keygen.c,v 1.180 2010/03/02 23:20:57 djm Exp $ */
|
||||
/* $OpenBSD: ssh-keygen.c,v 1.181 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
20
ssh.1
20
ssh.1
@ -34,8 +34,8 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.296 2010/02/26 22:09:28 jmc Exp $
|
||||
.Dd $Mdocdate: February 26 2010 $
|
||||
.\" $OpenBSD: ssh.1,v 1.297 2010/03/04 10:36:03 djm Exp $
|
||||
.Dd $Mdocdate: March 4 2010 $
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1121,6 +1121,22 @@ See the
|
||||
section of
|
||||
.Xr ssh-keygen 1
|
||||
for more details.
|
||||
.Pp
|
||||
Keys may be also be marked as revoked using the
|
||||
.Dq @revoked
|
||||
marker.
|
||||
Revoked keys will always trigger a warning when encountered and the host
|
||||
that presented them will be treated as untrusted.
|
||||
For example:
|
||||
.Pp
|
||||
.Dl @revoked * ssh-rsa AAAAB5W...
|
||||
.Pp
|
||||
Revoking a key revokes it for direct use and as a certification authority.
|
||||
Do not use both the
|
||||
.Dq @cert-authority and
|
||||
.Dq @revoked
|
||||
markers on the same line.
|
||||
.Pp
|
||||
.Sh SSH-BASED VIRTUAL PRIVATE NETWORKS
|
||||
.Nm
|
||||
contains support for Virtual Private Network (VPN) tunnelling
|
||||
|
24
sshconnect.c
24
sshconnect.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sshconnect.c,v 1.219 2010/02/26 20:29:54 djm Exp $ */
|
||||
/* $OpenBSD: sshconnect.c,v 1.220 2010/03/04 10:36:03 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -859,6 +859,25 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
||||
logit("Warning: Permanently added '%.200s' (%s) to the "
|
||||
"list of known hosts.", hostp, type);
|
||||
break;
|
||||
case HOST_REVOKED:
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: REVOKED HOST KEY DETECTED! @");
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("The %s host key for %s is marked as revoked.", type, host);
|
||||
error("This could mean that a stolen key is being used to");
|
||||
error("impersonate this host.");
|
||||
|
||||
/*
|
||||
* If strict host key checking is in use, the user will have
|
||||
* to edit the key manually and we can only abort.
|
||||
*/
|
||||
if (options.strict_host_key_checking) {
|
||||
error("%s host key for %.200s was revoked and you have "
|
||||
"requested strict checking.", type, host);
|
||||
goto fail;
|
||||
}
|
||||
goto continue_unsafe;
|
||||
|
||||
case HOST_CHANGED:
|
||||
if (want_cert) {
|
||||
/*
|
||||
@ -908,6 +927,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
continue_unsafe:
|
||||
/*
|
||||
* If strict host key checking has not been requested, allow
|
||||
* the connection but without MITM-able authentication or
|
||||
@ -1007,7 +1027,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (want_cert) {
|
||||
if (want_cert && host_status != HOST_REVOKED) {
|
||||
/*
|
||||
* No matching certificate. Downgrade cert to raw key and
|
||||
* search normally.
|
||||
|
@ -34,8 +34,8 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.117 2010/02/26 20:29:54 djm Exp $
|
||||
.Dd $Mdocdate: February 26 2010 $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.118 2010/03/04 10:36:03 djm Exp $
|
||||
.Dd $Mdocdate: March 4 2010 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -814,6 +814,11 @@ Specifies whether public key authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm RevokedKeys
|
||||
Specifies a list of revoked public keys.
|
||||
Keys listed in this file will be refused for public key authentication.
|
||||
Note that if this file is not readable, then public key authentication will
|
||||
be refused for all users.
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||
with successful RSA host authentication is allowed.
|
||||
@ -889,6 +894,22 @@ This avoids infinitely hanging sessions.
|
||||
.Pp
|
||||
To disable TCP keepalive messages, the value should be set to
|
||||
.Dq no .
|
||||
.It Cm TrustedUserCAKeys
|
||||
Specifies a file containing public keys of certificate authorities that are
|
||||
trusted sign user certificates for authentication.
|
||||
Keys are listed one per line, empty lines and comments starting with
|
||||
.Ql #
|
||||
are allowed.
|
||||
If a certificate is presented for authentication and has its signing CA key
|
||||
listed in this file, then it may be used for authentication for any user
|
||||
listed in the certificate's principals list.
|
||||
Note that certificates that lack a list of principals will not be permitted
|
||||
for authentication using
|
||||
.Cm TrustedUserCAKeys .
|
||||
For more details in certificates, please see the
|
||||
.Sx CERTIFICATES
|
||||
section in
|
||||
.Xr ssh-keygen 1 .
|
||||
.It Cm UseDNS
|
||||
Specifies whether
|
||||
.Xr sshd 8
|
||||
|
Loading…
Reference in New Issue
Block a user