=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/auth-options.c,v retrieving revision 1.71 retrieving revision 1.72 diff -u -r1.71 -r1.72 --- src/usr.bin/ssh/auth-options.c 2016/03/07 19:02:43 1.71 +++ src/usr.bin/ssh/auth-options.c 2016/11/30 02:57:40 1.72 @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.71 2016/03/07 19:02:43 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.72 2016/11/30 02:57:40 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -598,7 +598,7 @@ * options so this must be called after auth_parse_options(). */ int -auth_cert_options(struct sshkey *k, struct passwd *pw) +auth_cert_options(struct sshkey *k, struct passwd *pw, const char **reason) { int cert_no_port_forwarding_flag = 1; int cert_no_agent_forwarding_flag = 1; @@ -608,6 +608,8 @@ char *cert_forced_command = NULL; int cert_source_address_done = 0; + *reason = "invalid certificate options"; + /* Separate options and extensions for v01 certs */ if (parse_option_list(k->cert->critical, pw, OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, @@ -629,11 +631,24 @@ no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; no_pty_flag |= cert_no_pty_flag; no_user_rc |= cert_no_user_rc; - /* CA-specified forced command supersedes key option */ - if (cert_forced_command != NULL) { - free(forced_command); + /* + * Only permit both CA and key option forced-command if they match. + * Otherwise refuse the certificate. + */ + if (cert_forced_command != NULL && forced_command != NULL) { + if (strcmp(forced_command, cert_forced_command) == 0) { + free(forced_command); + forced_command = cert_forced_command; + } else { + *reason = "certificate and key options forced command " + "do not match"; + free(cert_forced_command); + return -1; + } + } else if (cert_forced_command != NULL) forced_command = cert_forced_command; - } + /* success */ + *reason = NULL; return 0; }