summaryrefslogtreecommitdiff
path: root/auth-options.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2016-11-30 02:57:40 +0000
committerDamien Miller <djm@mindrot.org>2016-11-30 19:44:01 +1100
commitfd6dcef2030d23c43f986d26979f84619c10589d (patch)
treea9b9d64866a656d5e187f7d63b61e1c1bede5e8f /auth-options.c
parent7fc4766ac78abae81ee75b22b7550720bfa28a33 (diff)
upstream commit
When a forced-command appears in both a certificate and an authorized keys/principals command= restriction, refuse to accept the certificate unless they are identical. The previous (documented) behaviour of having the certificate forced- command override the other could be a bit confused and more error-prone. Pointed out by Jann Horn of Project Zero; ok dtucker@ Upstream-ID: 79d811b6eb6bbe1221bf146dde6928f92d2cd05f
Diffstat (limited to 'auth-options.c')
-rw-r--r--auth-options.c27
1 files changed, 21 insertions, 6 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 */
603int 603int
604auth_cert_options(struct sshkey *k, struct passwd *pw) 604auth_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