diff options
-rw-r--r-- | auth-options.c | 27 | ||||
-rw-r--r-- | auth-options.h | 4 | ||||
-rw-r--r-- | auth2-pubkey.c | 18 | ||||
-rw-r--r-- | sshd.8 | 18 |
4 files changed, 44 insertions, 23 deletions
diff --git a/auth-options.c b/auth-options.c index b399b91e3..57b49f7fd 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-options.c,v 1.71 2016/03/07 19:02:43 djm Exp $ */ | 1 | /* $OpenBSD: auth-options.c,v 1.72 2016/11/30 02:57:40 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 |
@@ -601,7 +601,7 @@ parse_option_list(struct sshbuf *oblob, struct passwd *pw, | |||
601 | * options so this must be called after auth_parse_options(). | 601 | * options so this must be called after auth_parse_options(). |
602 | */ | 602 | */ |
603 | int | 603 | int |
604 | auth_cert_options(struct sshkey *k, struct passwd *pw) | 604 | auth_cert_options(struct sshkey *k, struct passwd *pw, const char **reason) |
605 | { | 605 | { |
606 | int cert_no_port_forwarding_flag = 1; | 606 | int cert_no_port_forwarding_flag = 1; |
607 | int cert_no_agent_forwarding_flag = 1; | 607 | int cert_no_agent_forwarding_flag = 1; |
@@ -611,6 +611,8 @@ auth_cert_options(struct sshkey *k, struct passwd *pw) | |||
611 | char *cert_forced_command = NULL; | 611 | char *cert_forced_command = NULL; |
612 | int cert_source_address_done = 0; | 612 | int cert_source_address_done = 0; |
613 | 613 | ||
614 | *reason = "invalid certificate options"; | ||
615 | |||
614 | /* Separate options and extensions for v01 certs */ | 616 | /* Separate options and extensions for v01 certs */ |
615 | if (parse_option_list(k->cert->critical, pw, | 617 | if (parse_option_list(k->cert->critical, pw, |
616 | OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, | 618 | OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, |
@@ -632,11 +634,24 @@ auth_cert_options(struct sshkey *k, struct passwd *pw) | |||
632 | no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; | 634 | no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; |
633 | no_pty_flag |= cert_no_pty_flag; | 635 | no_pty_flag |= cert_no_pty_flag; |
634 | no_user_rc |= cert_no_user_rc; | 636 | no_user_rc |= cert_no_user_rc; |
635 | /* CA-specified forced command supersedes key option */ | 637 | /* |
636 | if (cert_forced_command != NULL) { | 638 | * Only permit both CA and key option forced-command if they match. |
637 | free(forced_command); | 639 | * Otherwise refuse the certificate. |
640 | */ | ||
641 | if (cert_forced_command != NULL && forced_command != NULL) { | ||
642 | if (strcmp(forced_command, cert_forced_command) == 0) { | ||
643 | free(forced_command); | ||
644 | forced_command = cert_forced_command; | ||
645 | } else { | ||
646 | *reason = "certificate and key options forced command " | ||
647 | "do not match"; | ||
648 | free(cert_forced_command); | ||
649 | return -1; | ||
650 | } | ||
651 | } else if (cert_forced_command != NULL) | ||
638 | forced_command = cert_forced_command; | 652 | forced_command = cert_forced_command; |
639 | } | 653 | /* success */ |
654 | *reason = NULL; | ||
640 | return 0; | 655 | return 0; |
641 | } | 656 | } |
642 | 657 | ||
diff --git a/auth-options.h b/auth-options.h index 34852e5c0..52cbb42aa 100644 --- a/auth-options.h +++ b/auth-options.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-options.h,v 1.21 2015/01/14 10:30:34 markus Exp $ */ | 1 | /* $OpenBSD: auth-options.h,v 1.22 2016/11/30 02:57:40 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -35,6 +35,6 @@ extern char *authorized_principals; | |||
35 | 35 | ||
36 | int auth_parse_options(struct passwd *, char *, char *, u_long); | 36 | int auth_parse_options(struct passwd *, char *, char *, u_long); |
37 | void auth_clear_options(void); | 37 | void auth_clear_options(void); |
38 | int auth_cert_options(struct sshkey *, struct passwd *); | 38 | int auth_cert_options(struct sshkey *, struct passwd *, const char **); |
39 | 39 | ||
40 | #endif | 40 | #endif |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 375d91cbd..20f3309e1 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.59 2016/09/21 17:44:20 djm Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.60 2016/11/30 02:57:40 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -757,17 +757,17 @@ static int | |||
757 | check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | 757 | check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) |
758 | { | 758 | { |
759 | char line[SSH_MAX_PUBKEY_BYTES]; | 759 | char line[SSH_MAX_PUBKEY_BYTES]; |
760 | const char *reason; | ||
761 | int found_key = 0; | 760 | int found_key = 0; |
762 | u_long linenum = 0; | 761 | u_long linenum = 0; |
763 | Key *found; | 762 | Key *found; |
764 | char *fp; | ||
765 | 763 | ||
766 | found_key = 0; | 764 | found_key = 0; |
767 | 765 | ||
768 | found = NULL; | 766 | found = NULL; |
769 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 767 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
770 | char *cp, *key_options = NULL; | 768 | char *cp, *key_options = NULL, *fp = NULL; |
769 | const char *reason = NULL; | ||
770 | |||
771 | if (found != NULL) | 771 | if (found != NULL) |
772 | key_free(found); | 772 | key_free(found); |
773 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); | 773 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); |
@@ -832,10 +832,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | |||
832 | authorized_principals == NULL ? pw->pw_name : NULL, | 832 | authorized_principals == NULL ? pw->pw_name : NULL, |
833 | &reason) != 0) | 833 | &reason) != 0) |
834 | goto fail_reason; | 834 | goto fail_reason; |
835 | if (auth_cert_options(key, pw) != 0) { | 835 | if (auth_cert_options(key, pw, &reason) != 0) |
836 | free(fp); | 836 | goto fail_reason; |
837 | continue; | ||
838 | } | ||
839 | verbose("Accepted certificate ID \"%s\" (serial %llu) " | 837 | verbose("Accepted certificate ID \"%s\" (serial %llu) " |
840 | "signed by %s CA %s via %s", key->cert->key_id, | 838 | "signed by %s CA %s via %s", key->cert->key_id, |
841 | (unsigned long long)key->cert->serial, | 839 | (unsigned long long)key->cert->serial, |
@@ -913,8 +911,8 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
913 | if (key_cert_check_authority(key, 0, 1, | 911 | if (key_cert_check_authority(key, 0, 1, |
914 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) | 912 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) |
915 | goto fail_reason; | 913 | goto fail_reason; |
916 | if (auth_cert_options(key, pw) != 0) | 914 | if (auth_cert_options(key, pw, &reason) != 0) |
917 | goto out; | 915 | goto fail_reason; |
918 | 916 | ||
919 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " | 917 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " |
920 | "%s CA %s via %s", key->cert->key_id, | 918 | "%s CA %s via %s", key->cert->key_id, |
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd.8,v 1.286 2016/08/19 03:18:06 djm Exp $ | 36 | .\" $OpenBSD: sshd.8,v 1.287 2016/11/30 02:57:40 djm Exp $ |
37 | .Dd $Mdocdate: August 19 2016 $ | 37 | .Dd $Mdocdate: November 30 2016 $ |
38 | .Dt SSHD 8 | 38 | .Dt SSHD 8 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -481,19 +481,27 @@ If an 8-bit clean channel is required, | |||
481 | one must not request a pty or should specify | 481 | one must not request a pty or should specify |
482 | .Cm no-pty . | 482 | .Cm no-pty . |
483 | A quote may be included in the command by quoting it with a backslash. | 483 | A quote may be included in the command by quoting it with a backslash. |
484 | .Pp | ||
484 | This option might be useful | 485 | This option might be useful |
485 | to restrict certain public keys to perform just a specific operation. | 486 | to restrict certain public keys to perform just a specific operation. |
486 | An example might be a key that permits remote backups but nothing else. | 487 | An example might be a key that permits remote backups but nothing else. |
487 | Note that the client may specify TCP and/or X11 | 488 | Note that the client may specify TCP and/or X11 |
488 | forwarding unless they are explicitly prohibited. | 489 | forwarding unless they are explicitly prohibited, e.g. using the |
490 | .Cm restrict | ||
491 | key option. | ||
492 | .Pp | ||
489 | The command originally supplied by the client is available in the | 493 | The command originally supplied by the client is available in the |
490 | .Ev SSH_ORIGINAL_COMMAND | 494 | .Ev SSH_ORIGINAL_COMMAND |
491 | environment variable. | 495 | environment variable. |
492 | Note that this option applies to shell, command or subsystem execution. | 496 | Note that this option applies to shell, command or subsystem execution. |
493 | Also note that this command may be superseded by either a | 497 | Also note that this command may be superseded by a |
494 | .Xr sshd_config 5 | 498 | .Xr sshd_config 5 |
495 | .Cm ForceCommand | 499 | .Cm ForceCommand |
496 | directive or a command embedded in a certificate. | 500 | directive. |
501 | .Pp | ||
502 | If a command is specified and a forced-command is embedded in a certificate | ||
503 | used for authentication, then the certificate will be accepted only if the | ||
504 | two commands are identical. | ||
497 | .It Cm environment="NAME=value" | 505 | .It Cm environment="NAME=value" |
498 | Specifies that the string is to be added to the environment when | 506 | Specifies that the string is to be added to the environment when |
499 | logging in using this key. | 507 | logging in using this key. |