summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-08-05 13:04:50 +1000
committerDamien Miller <djm@mindrot.org>2010-08-05 13:04:50 +1000
commitc158331f8c7e059c6c1d099bffc7f5fc6087ddbd (patch)
treef1998f0fb52e5fb666ee67064a424af45e941f6b
parent1da638895916bc061ff6aca9f373d48a9776810b (diff)
- djm@cvs.openbsd.org 2010/08/04 05:42:47
[auth.c auth2-hostbased.c authfile.c authfile.h ssh-keysign.8] [ssh-keysign.c ssh.c] enable certificates for hostbased authentication, from Iain Morgan; "looks ok" markus@
-rw-r--r--ChangeLog5
-rw-r--r--auth.c4
-rw-r--r--auth2-hostbased.c31
-rw-r--r--authfile.c60
-rw-r--r--authfile.h4
-rw-r--r--ssh-keysign.87
-rw-r--r--ssh-keysign.c4
-rw-r--r--ssh.c24
8 files changed, 120 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 73954735a..7125eaa1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,11 @@
9 [PROTOCOL.certkeys ssh-keygen.c] 9 [PROTOCOL.certkeys ssh-keygen.c]
10 tighten the rules for certificate encoding by requiring that options 10 tighten the rules for certificate encoding by requiring that options
11 appear in lexical order and make our ssh-keygen comply. ok markus@ 11 appear in lexical order and make our ssh-keygen comply. ok markus@
12 - djm@cvs.openbsd.org 2010/08/04 05:42:47
13 [auth.c auth2-hostbased.c authfile.c authfile.h ssh-keysign.8]
14 [ssh-keysign.c ssh.c]
15 enable certificates for hostbased authentication, from Iain Morgan;
16 "looks ok" markus@
12 17
1320100903 1820100903
14 - (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from 19 - (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from
diff --git a/auth.c b/auth.c
index d1727a4a9..a27667f42 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.88 2010/06/22 04:49:47 djm Exp $ */ 1/* $OpenBSD: auth.c,v 1.89 2010/08/04 05:42:47 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -385,7 +385,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
385 HostStatus host_status; 385 HostStatus host_status;
386 386
387 /* Check if we know the host and its host key. */ 387 /* Check if we know the host and its host key. */
388 found = key_new(key->type); 388 found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
389 host_status = check_host_in_hostfile(sysfile, host, key, found, NULL); 389 host_status = check_host_in_hostfile(sysfile, host, key, found, NULL);
390 390
391 if (host_status != HOST_OK && userfile != NULL) { 391 if (host_status != HOST_OK && userfile != NULL) {
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 721646520..cdf442f97 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-hostbased.c,v 1.13 2010/03/04 10:36:03 djm Exp $ */ 1/* $OpenBSD: auth2-hostbased.c,v 1.14 2010/08/04 05:42:47 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -141,9 +141,10 @@ int
141hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, 141hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
142 Key *key) 142 Key *key)
143{ 143{
144 const char *resolvedname, *ipaddr, *lookup; 144 const char *resolvedname, *ipaddr, *lookup, *reason;
145 HostStatus host_status; 145 HostStatus host_status;
146 int len; 146 int len;
147 char *fp;
147 148
148 if (auth_key_is_revoked(key)) 149 if (auth_key_is_revoked(key))
149 return 0; 150 return 0;
@@ -174,16 +175,40 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
174 } 175 }
175 debug2("userauth_hostbased: access allowed by auth_rhosts2"); 176 debug2("userauth_hostbased: access allowed by auth_rhosts2");
176 177
178 if (key_is_cert(key) &&
179 key_cert_check_authority(key, 1, 0, lookup, &reason)) {
180 error("%s", reason);
181 auth_debug_add("%s", reason);
182 return 0;
183 }
184
177 host_status = check_key_in_hostfiles(pw, key, lookup, 185 host_status = check_key_in_hostfiles(pw, key, lookup,
178 _PATH_SSH_SYSTEM_HOSTFILE, 186 _PATH_SSH_SYSTEM_HOSTFILE,
179 options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE); 187 options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
180 188
181 /* backward compat if no key has been found. */ 189 /* backward compat if no key has been found. */
182 if (host_status == HOST_NEW) 190 if (host_status == HOST_NEW) {
183 host_status = check_key_in_hostfiles(pw, key, lookup, 191 host_status = check_key_in_hostfiles(pw, key, lookup,
184 _PATH_SSH_SYSTEM_HOSTFILE2, 192 _PATH_SSH_SYSTEM_HOSTFILE2,
185 options.ignore_user_known_hosts ? NULL : 193 options.ignore_user_known_hosts ? NULL :
186 _PATH_SSH_USER_HOSTFILE2); 194 _PATH_SSH_USER_HOSTFILE2);
195 }
196
197 if (host_status == HOST_OK) {
198 if (key_is_cert(key)) {
199 fp = key_fingerprint(key->cert->signature_key,
200 SSH_FP_MD5, SSH_FP_HEX);
201 verbose("Accepted certificate ID \"%s\" signed by "
202 "%s CA %s from %s@%s", key->cert->key_id,
203 key_type(key->cert->signature_key), fp,
204 cuser, lookup);
205 } else {
206 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
207 verbose("Accepted %s public key %s from %s@%s",
208 key_type(key), fp, cuser, lookup);
209 }
210 xfree(fp);
211 }
187 212
188 return (host_status == HOST_OK); 213 return (host_status == HOST_OK);
189} 214}
diff --git a/authfile.c b/authfile.c
index 224c6aa80..6bf41db9a 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.81 2010/08/04 05:42:47 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -693,6 +693,64 @@ key_load_public(const char *filename, char **commentp)
693 return NULL; 693 return NULL;
694} 694}
695 695
696/* Load the certificate associated with the named private key */
697Key *
698key_load_cert(const char *filename)
699{
700 Key *pub;
701 char file[MAXPATHLEN];
702
703 pub = key_new(KEY_UNSPEC);
704 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
705 (strlcat(file, "-cert.pub", sizeof file) < sizeof(file)) &&
706 (key_try_load_public(pub, file, NULL) == 1))
707 return pub;
708 key_free(pub);
709 return NULL;
710}
711
712/* Load private key and certificate */
713Key *
714key_load_private_cert(int type, const char *filename, const char *passphrase,
715 int *perm_ok)
716{
717 Key *key, *pub;
718
719 switch (type) {
720 case KEY_RSA:
721 case KEY_DSA:
722 break;
723 default:
724 error("%s: unsupported key type", __func__);
725 return NULL;
726 }
727
728 if ((key = key_load_private_type(type, filename,
729 passphrase, NULL, perm_ok)) == NULL)
730 return NULL;
731
732 if ((pub = key_load_cert(filename)) == NULL) {
733 key_free(key);
734 return NULL;
735 }
736
737 /* Make sure the private key matches the certificate */
738 if (key_equal_public(key, pub) == 0) {
739 error("%s: certificate does not match private key %s",
740 __func__, filename);
741 } else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) {
742 error("%s: key_to_certified failed", __func__);
743 } else {
744 key_cert_copy(pub, key);
745 key_free(pub);
746 return key;
747 }
748
749 key_free(key);
750 key_free(pub);
751 return NULL;
752}
753
696/* 754/*
697 * Returns 1 if the specified "key" is listed in the file "filename", 755 * Returns 1 if the specified "key" is listed in the file "filename",
698 * 0 if the key is not listed or -1 on error. 756 * 0 if the key is not listed or -1 on error.
diff --git a/authfile.h b/authfile.h
index 6dfa478e7..6745dc062 100644
--- a/authfile.h
+++ b/authfile.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.h,v 1.14 2010/03/04 10:36:03 djm Exp $ */ 1/* $OpenBSD: authfile.h,v 1.15 2010/08/04 05:42:47 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,9 +16,11 @@
16#define AUTHFILE_H 16#define AUTHFILE_H
17 17
18int key_save_private(Key *, const char *, const char *, const char *); 18int key_save_private(Key *, const char *, const char *, const char *);
19Key *key_load_cert(const char *);
19Key *key_load_public(const char *, char **); 20Key *key_load_public(const char *, char **);
20Key *key_load_public_type(int, const char *, char **); 21Key *key_load_public_type(int, const char *, char **);
21Key *key_load_private(const char *, const char *, char **); 22Key *key_load_private(const char *, const char *, char **);
23Key *key_load_private_cert(int, const char *, const char *, int *);
22Key *key_load_private_type(int, const char *, const char *, char **, int *); 24Key *key_load_private_type(int, const char *, const char *, char **, int *);
23Key *key_load_private_pem(int, int, const char *, char **); 25Key *key_load_private_pem(int, int, const char *, char **);
24int key_perm_ok(int, const char *); 26int key_perm_ok(int, const char *);
diff --git a/ssh-keysign.8 b/ssh-keysign.8
index 3ba54b935..46c0ee9cd 100644
--- a/ssh-keysign.8
+++ b/ssh-keysign.8
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keysign.8,v 1.9 2007/05/31 19:20:16 jmc Exp $ 1.\" $OpenBSD: ssh-keysign.8,v 1.10 2010/08/04 05:42:47 djm Exp $
2.\" 2.\"
3.\" Copyright (c) 2002 Markus Friedl. All rights reserved. 3.\" Copyright (c) 2002 Markus Friedl. All rights reserved.
4.\" 4.\"
@@ -22,7 +22,7 @@
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\" 24.\"
25.Dd $Mdocdate: May 31 2007 $ 25.Dd $Mdocdate: August 4 2010 $
26.Dt SSH-KEYSIGN 8 26.Dt SSH-KEYSIGN 8
27.Os 27.Os
28.Sh NAME 28.Sh NAME
@@ -68,6 +68,9 @@ accessible to others.
68Since they are readable only by root, 68Since they are readable only by root,
69.Nm 69.Nm
70must be set-uid root if host-based authentication is used. 70must be set-uid root if host-based authentication is used.
71.It Pa /etc/ssh/ssh_host_dsa_key-cert.pub, /etc/ssh/ssh_host_rsa_key-cert.pub
72If these files exist they are assumed to contain public certificate
73information corresponding with the private keys above.
71.El 74.El
72.Sh SEE ALSO 75.Sh SEE ALSO
73.Xr ssh 1 , 76.Xr ssh 1 ,
diff --git a/ssh-keysign.c b/ssh-keysign.c
index 0fdcebbd2..2f6ac99ab 100644
--- a/ssh-keysign.c
+++ b/ssh-keysign.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keysign.c,v 1.30 2010/01/13 01:20:20 dtucker Exp $ */ 1/* $OpenBSD: ssh-keysign.c,v 1.31 2010/08/04 05:42:47 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -232,7 +232,7 @@ main(int argc, char **argv)
232 found = 0; 232 found = 0;
233 for (i = 0; i < 2; i++) { 233 for (i = 0; i < 2; i++) {
234 if (keys[i] != NULL && 234 if (keys[i] != NULL &&
235 key_equal(key, keys[i])) { 235 key_equal_public(key, keys[i])) {
236 found = 1; 236 found = 1;
237 break; 237 break;
238 } 238 }
diff --git a/ssh.c b/ssh.c
index 249be2db8..ab37c205d 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.344 2010/07/19 09:15:12 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.345 2010/08/04 05:42:47 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -774,26 +774,34 @@ main(int ac, char **av)
774 sensitive_data.external_keysign = 0; 774 sensitive_data.external_keysign = 0;
775 if (options.rhosts_rsa_authentication || 775 if (options.rhosts_rsa_authentication ||
776 options.hostbased_authentication) { 776 options.hostbased_authentication) {
777 sensitive_data.nkeys = 3; 777 sensitive_data.nkeys = 5;
778 sensitive_data.keys = xcalloc(sensitive_data.nkeys, 778 sensitive_data.keys = xcalloc(sensitive_data.nkeys,
779 sizeof(Key)); 779 sizeof(Key));
780 780
781 PRIV_START; 781 PRIV_START;
782 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, 782 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
783 _PATH_HOST_KEY_FILE, "", NULL, NULL); 783 _PATH_HOST_KEY_FILE, "", NULL, NULL);
784 sensitive_data.keys[1] = key_load_private_type(KEY_DSA, 784 sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
785 _PATH_HOST_DSA_KEY_FILE, "", NULL);
786 sensitive_data.keys[2] = key_load_private_cert(KEY_RSA,
787 _PATH_HOST_RSA_KEY_FILE, "", NULL);
788 sensitive_data.keys[3] = key_load_private_type(KEY_DSA,
785 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); 789 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
786 sensitive_data.keys[2] = key_load_private_type(KEY_RSA, 790 sensitive_data.keys[4] = key_load_private_type(KEY_RSA,
787 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); 791 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
788 PRIV_END; 792 PRIV_END;
789 793
790 if (options.hostbased_authentication == 1 && 794 if (options.hostbased_authentication == 1 &&
791 sensitive_data.keys[0] == NULL && 795 sensitive_data.keys[0] == NULL &&
792 sensitive_data.keys[1] == NULL && 796 sensitive_data.keys[3] == NULL &&
793 sensitive_data.keys[2] == NULL) { 797 sensitive_data.keys[4] == NULL) {
794 sensitive_data.keys[1] = key_load_public( 798 sensitive_data.keys[1] = key_load_cert(
799 _PATH_HOST_DSA_KEY_FILE);
800 sensitive_data.keys[2] = key_load_cert(
801 _PATH_HOST_RSA_KEY_FILE);
802 sensitive_data.keys[3] = key_load_public(
795 _PATH_HOST_DSA_KEY_FILE, NULL); 803 _PATH_HOST_DSA_KEY_FILE, NULL);
796 sensitive_data.keys[2] = key_load_public( 804 sensitive_data.keys[4] = key_load_public(
797 _PATH_HOST_RSA_KEY_FILE, NULL); 805 _PATH_HOST_RSA_KEY_FILE, NULL);
798 sensitive_data.external_keysign = 1; 806 sensitive_data.external_keysign = 1;
799 } 807 }