diff options
author | Damien Miller <djm@mindrot.org> | 2010-08-05 13:04:50 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2010-08-05 13:04:50 +1000 |
commit | c158331f8c7e059c6c1d099bffc7f5fc6087ddbd (patch) | |
tree | f1998f0fb52e5fb666ee67064a424af45e941f6b | |
parent | 1da638895916bc061ff6aca9f373d48a9776810b (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-- | ChangeLog | 5 | ||||
-rw-r--r-- | auth.c | 4 | ||||
-rw-r--r-- | auth2-hostbased.c | 31 | ||||
-rw-r--r-- | authfile.c | 60 | ||||
-rw-r--r-- | authfile.h | 4 | ||||
-rw-r--r-- | ssh-keysign.8 | 7 | ||||
-rw-r--r-- | ssh-keysign.c | 4 | ||||
-rw-r--r-- | ssh.c | 24 |
8 files changed, 120 insertions, 19 deletions
@@ -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 | ||
13 | 20100903 | 18 | 20100903 |
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 |
@@ -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 | |||
141 | hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, | 141 | hostbased_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 */ | ||
697 | Key * | ||
698 | key_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 */ | ||
713 | Key * | ||
714 | key_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 | ||
18 | int key_save_private(Key *, const char *, const char *, const char *); | 18 | int key_save_private(Key *, const char *, const char *, const char *); |
19 | Key *key_load_cert(const char *); | ||
19 | Key *key_load_public(const char *, char **); | 20 | Key *key_load_public(const char *, char **); |
20 | Key *key_load_public_type(int, const char *, char **); | 21 | Key *key_load_public_type(int, const char *, char **); |
21 | Key *key_load_private(const char *, const char *, char **); | 22 | Key *key_load_private(const char *, const char *, char **); |
23 | Key *key_load_private_cert(int, const char *, const char *, int *); | ||
22 | Key *key_load_private_type(int, const char *, const char *, char **, int *); | 24 | Key *key_load_private_type(int, const char *, const char *, char **, int *); |
23 | Key *key_load_private_pem(int, int, const char *, char **); | 25 | Key *key_load_private_pem(int, int, const char *, char **); |
24 | int key_perm_ok(int, const char *); | 26 | int 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. | |||
68 | Since they are readable only by root, | 68 | Since they are readable only by root, |
69 | .Nm | 69 | .Nm |
70 | must be set-uid root if host-based authentication is used. | 70 | must 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 | ||
72 | If these files exist they are assumed to contain public certificate | ||
73 | information 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 | } |
@@ -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 | } |