summaryrefslogtreecommitdiff
path: root/usr.bin/ssh/auth-options.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/ssh/auth-options.c')
-rw-r--r--usr.bin/ssh/auth-options.c150
1 files changed, 149 insertions, 1 deletions
diff --git a/usr.bin/ssh/auth-options.c b/usr.bin/ssh/auth-options.c
index 941c6be9f01..e765b5ad684 100644
--- a/usr.bin/ssh/auth-options.c
+++ b/usr.bin/ssh/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.45 2010/02/26 20:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -42,6 +42,7 @@ int no_agent_forwarding_flag = 0;
int no_x11_forwarding_flag = 0;
int no_pty_flag = 0;
int no_user_rc = 0;
+int key_is_cert_authority = 0;
/* "command=" option. */
char *forced_command = NULL;
@@ -62,6 +63,7 @@ auth_clear_options(void)
no_pty_flag = 0;
no_x11_forwarding_flag = 0;
no_user_rc = 0;
+ key_is_cert_authority = 0;
while (custom_environment) {
struct envstring *ce = custom_environment;
custom_environment = ce->next;
@@ -94,6 +96,12 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
return 1;
while (*opts && *opts != ' ' && *opts != '\t') {
+ cp = "cert-authority";
+ if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+ key_is_cert_authority = 1;
+ opts += strlen(cp);
+ goto next_option;
+ }
cp = "no-port-forwarding";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
auth_debug_add("Port forwarding disabled.");
@@ -372,3 +380,143 @@ bad_option:
/* deny access */
return 0;
}
+
+/*
+ * Set options from certificate constraints. These supersede user key options
+ * so this must be called after auth_parse_options().
+ */
+int
+auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
+{
+ u_char *name = NULL, *data_blob = NULL;
+ u_int len;
+ Buffer c, data;
+ int ret = -1;
+
+ int cert_no_port_forwarding_flag = 1;
+ int cert_no_agent_forwarding_flag = 1;
+ int cert_no_x11_forwarding_flag = 1;
+ int cert_no_pty_flag = 1;
+ int cert_no_user_rc = 1;
+ char *cert_forced_command = NULL;
+ int cert_source_address_done = 0;
+
+ buffer_init(&data);
+
+ /* Make copy to avoid altering original */
+ buffer_init(&c);
+ buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig));
+
+ while (buffer_len(&c) > 0) {
+ if ((name = buffer_get_string_ret(&c, NULL)) == NULL ||
+ (data_blob = buffer_get_string_ret(&c, &len)) == NULL) {
+ error("Certificate constraints corrupt");
+ goto out;
+ }
+ buffer_append(&data, data_blob, len);
+ debug3("found certificate constraint \"%.100s\" len %u",
+ name, len);
+ if (strcmp(name, "permit-X11-forwarding") == 0)
+ cert_no_x11_forwarding_flag = 0;
+ else if (strcmp(name, "permit-agent-forwarding") == 0)
+ cert_no_agent_forwarding_flag = 0;
+ else if (strcmp(name, "permit-port-forwarding") == 0)
+ cert_no_port_forwarding_flag = 0;
+ else if (strcmp(name, "permit-pty") == 0)
+ cert_no_pty_flag = 0;
+ else if (strcmp(name, "permit-user-rc") == 0)
+ cert_no_user_rc = 0;
+ else if (strcmp(name, "force-command") == 0) {
+ char *command = buffer_get_string_ret(&data, NULL);
+
+ if (command == NULL) {
+ error("Certificate constraint \"%s\" corrupt",
+ name);
+ goto out;
+ }
+ if (cert_forced_command != NULL) {
+ error("Certificate has multiple "
+ "forced-command constraints");
+ xfree(command);
+ goto out;
+ }
+ cert_forced_command = command;
+ } else if (strcmp(name, "source-address") == 0) {
+ char *allowed = buffer_get_string_ret(&data, NULL);
+ const char *remote_ip = get_remote_ipaddr();
+
+ if (allowed == NULL) {
+ error("Certificate constraint \"%s\" corrupt",
+ name);
+ goto out;
+ }
+ if (cert_source_address_done++) {
+ error("Certificate has multiple "
+ "source-address constraints");
+ xfree(allowed);
+ goto out;
+ }
+ switch (addr_match_cidr_list(remote_ip, allowed)) {
+ case 1:
+ /* accepted */
+ xfree(allowed);
+ break;
+ case 0:
+ /* no match */
+ logit("Authentication tried for %.100s with "
+ "valid certificate but not from a "
+ "permitted host (ip=%.200s).",
+ pw->pw_name, remote_ip);
+ auth_debug_add("Your address '%.200s' is not "
+ "permitted to use this certificate for "
+ "login.", remote_ip);
+ xfree(allowed);
+ goto out;
+ case -1:
+ error("Certificate source-address contents "
+ "invalid");
+ xfree(allowed);
+ goto out;
+ }
+ } else {
+ error("Certificate constraint \"%s\" is not supported",
+ name);
+ goto out;
+ }
+
+ if (buffer_len(&data) != 0) {
+ error("Certificate constraint \"%s\" corrupt "
+ "(extra data)", name);
+ goto out;
+ }
+ buffer_clear(&data);
+ xfree(name);
+ xfree(data_blob);
+ name = data_blob = NULL;
+ }
+
+ /* successfully parsed all constraints */
+ ret = 0;
+
+ no_port_forwarding_flag |= cert_no_port_forwarding_flag;
+ no_agent_forwarding_flag |= cert_no_agent_forwarding_flag;
+ 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) {
+ if (forced_command != NULL)
+ xfree(forced_command);
+ forced_command = cert_forced_command;
+ }
+
+ out:
+ if (name != NULL)
+ xfree(name);
+ if (data_blob != NULL)
+ xfree(data_blob);
+ buffer_free(&data);
+ buffer_free(&c);
+ return ret;
+}
+