diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | PROTOCOL.certkeys | 35 | ||||
-rw-r--r-- | auth-options.c | 282 | ||||
-rw-r--r-- | ssh-keygen.c | 94 |
4 files changed, 267 insertions, 152 deletions
@@ -33,6 +33,14 @@ | |||
33 | [auth2-pubkey.c] | 33 | [auth2-pubkey.c] |
34 | fix logspam when key options (from="..." especially) deny non-matching | 34 | fix logspam when key options (from="..." especially) deny non-matching |
35 | keys; reported by henning@ also bz#1765; ok markus@ dtucker@ | 35 | keys; reported by henning@ also bz#1765; ok markus@ dtucker@ |
36 | - djm@cvs.openbsd.org 2010/05/20 23:46:02 | ||
37 | [PROTOCOL.certkeys auth-options.c ssh-keygen.c] | ||
38 | Move the permit-* options to the non-critical "extensions" field for v01 | ||
39 | certificates. The logic is that if another implementation fails to | ||
40 | implement them then the connection just loses features rather than fails | ||
41 | outright. | ||
42 | |||
43 | ok markus@ | ||
36 | 44 | ||
37 | 20100511 | 45 | 20100511 |
38 | - (dtucker) [Makefile.in] Bug #1770: Link libopenbsd-compat twice to solve | 46 | - (dtucker) [Makefile.in] Bug #1770: Link libopenbsd-compat twice to solve |
diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys index 0fa5748f3..81b02a078 100644 --- a/PROTOCOL.certkeys +++ b/PROTOCOL.certkeys | |||
@@ -131,7 +131,7 @@ must refuse to authorise a key that has an unrecognised option. | |||
131 | 131 | ||
132 | extensions is a set of zero or more optional extensions. These extensions | 132 | extensions is a set of zero or more optional extensions. These extensions |
133 | are not critical, and an implementation that encounters one that it does | 133 | are not critical, and an implementation that encounters one that it does |
134 | not recognise may safely ignore it. No extensions are defined at present. | 134 | not recognise may safely ignore it. |
135 | 135 | ||
136 | The reserved field is currently unused and is ignored in this version of | 136 | The reserved field is currently unused and is ignored in this version of |
137 | the protocol. | 137 | the protocol. |
@@ -172,6 +172,28 @@ force-command string Specifies a command that is executed | |||
172 | ssh command-line) whenever this key is | 172 | ssh command-line) whenever this key is |
173 | used for authentication. | 173 | used for authentication. |
174 | 174 | ||
175 | source-address string Comma-separated list of source addresses | ||
176 | from which this certificate is accepted | ||
177 | for authentication. Addresses are | ||
178 | specified in CIDR format (nn.nn.nn.nn/nn | ||
179 | or hhhh::hhhh/nn). | ||
180 | If this option is not present then | ||
181 | certificates may be presented from any | ||
182 | source address. | ||
183 | |||
184 | Extensions | ||
185 | ---------- | ||
186 | |||
187 | The extensions section of the certificate specifies zero or more | ||
188 | non-critical certificate extensions. The encoding of extensions in this | ||
189 | field is identical to that of the critical options. If an implementation | ||
190 | does not recognise an extension, then it should ignore it. | ||
191 | |||
192 | The supported extensions and the contents and structure of their data | ||
193 | fields are: | ||
194 | |||
195 | Name Format Description | ||
196 | ----------------------------------------------------------------------------- | ||
175 | permit-X11-forwarding empty Flag indicating that X11 forwarding | 197 | permit-X11-forwarding empty Flag indicating that X11 forwarding |
176 | should be permitted. X11 forwarding will | 198 | should be permitted. X11 forwarding will |
177 | be refused if this option is absent. | 199 | be refused if this option is absent. |
@@ -196,13 +218,4 @@ permit-user-rc empty Flag indicating that execution of | |||
196 | of this script will not be permitted if | 218 | of this script will not be permitted if |
197 | this option is not present. | 219 | this option is not present. |
198 | 220 | ||
199 | source-address string Comma-separated list of source addresses | 221 | $OpenBSD: PROTOCOL.certkeys,v 1.6 2010/05/20 23:46:02 djm Exp $ |
200 | from which this certificate is accepted | ||
201 | for authentication. Addresses are | ||
202 | specified in CIDR format (nn.nn.nn.nn/nn | ||
203 | or hhhh::hhhh/nn). | ||
204 | If this option is not present then | ||
205 | certificates may be presented from any | ||
206 | source address. | ||
207 | |||
208 | $OpenBSD: PROTOCOL.certkeys,v 1.5 2010/05/01 02:50:50 djm Exp $ | ||
diff --git a/auth-options.c b/auth-options.c index 57a67ec79..a7040247f 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-options.c,v 1.51 2010/05/07 11:30:29 djm Exp $ */ | 1 | /* $OpenBSD: auth-options.c,v 1.52 2010/05/20 23:46:02 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 |
@@ -417,32 +417,31 @@ bad_option: | |||
417 | return 0; | 417 | return 0; |
418 | } | 418 | } |
419 | 419 | ||
420 | /* | 420 | #define OPTIONS_CRITICAL 1 |
421 | * Set options from critical certificate options. These supersede user key | 421 | #define OPTIONS_EXTENSIONS 2 |
422 | * options so this must be called after auth_parse_options(). | 422 | static int |
423 | */ | 423 | parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, |
424 | int | 424 | u_int which, int crit, |
425 | auth_cert_options(Key *k, struct passwd *pw) | 425 | int *cert_no_port_forwarding_flag, |
426 | int *cert_no_agent_forwarding_flag, | ||
427 | int *cert_no_x11_forwarding_flag, | ||
428 | int *cert_no_pty_flag, | ||
429 | int *cert_no_user_rc, | ||
430 | char **cert_forced_command, | ||
431 | int *cert_source_address_done) | ||
426 | { | 432 | { |
433 | char *command, *allowed; | ||
434 | const char *remote_ip; | ||
427 | u_char *name = NULL, *data_blob = NULL; | 435 | u_char *name = NULL, *data_blob = NULL; |
428 | u_int nlen, dlen, clen; | 436 | u_int nlen, dlen, clen; |
429 | Buffer c, data; | 437 | Buffer c, data; |
430 | int ret = -1; | 438 | int ret = -1, found; |
431 | |||
432 | int cert_no_port_forwarding_flag = 1; | ||
433 | int cert_no_agent_forwarding_flag = 1; | ||
434 | int cert_no_x11_forwarding_flag = 1; | ||
435 | int cert_no_pty_flag = 1; | ||
436 | int cert_no_user_rc = 1; | ||
437 | char *cert_forced_command = NULL; | ||
438 | int cert_source_address_done = 0; | ||
439 | 439 | ||
440 | buffer_init(&data); | 440 | buffer_init(&data); |
441 | 441 | ||
442 | /* Make copy to avoid altering original */ | 442 | /* Make copy to avoid altering original */ |
443 | buffer_init(&c); | 443 | buffer_init(&c); |
444 | buffer_append(&c, | 444 | buffer_append(&c, optblob, optblob_len); |
445 | buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); | ||
446 | 445 | ||
447 | while (buffer_len(&c) > 0) { | 446 | while (buffer_len(&c) > 0) { |
448 | if ((name = buffer_get_string_ret(&c, &nlen)) == NULL || | 447 | if ((name = buffer_get_string_ret(&c, &nlen)) == NULL || |
@@ -451,90 +450,114 @@ auth_cert_options(Key *k, struct passwd *pw) | |||
451 | goto out; | 450 | goto out; |
452 | } | 451 | } |
453 | buffer_append(&data, data_blob, dlen); | 452 | buffer_append(&data, data_blob, dlen); |
454 | debug3("found certificate constraint \"%.100s\" len %u", | 453 | debug3("found certificate option \"%.100s\" len %u", |
455 | name, dlen); | 454 | name, dlen); |
456 | if (strlen(name) != nlen) { | 455 | if (strlen(name) != nlen) { |
457 | error("Certificate constraint name contains \\0"); | 456 | error("Certificate constraint name contains \\0"); |
458 | goto out; | 457 | goto out; |
459 | } | 458 | } |
460 | if (strcmp(name, "permit-X11-forwarding") == 0) | 459 | found = 0; |
461 | cert_no_x11_forwarding_flag = 0; | 460 | if ((which & OPTIONS_EXTENSIONS) != 0) { |
462 | else if (strcmp(name, "permit-agent-forwarding") == 0) | 461 | if (strcmp(name, "permit-X11-forwarding") == 0) { |
463 | cert_no_agent_forwarding_flag = 0; | 462 | *cert_no_x11_forwarding_flag = 0; |
464 | else if (strcmp(name, "permit-port-forwarding") == 0) | 463 | found = 1; |
465 | cert_no_port_forwarding_flag = 0; | 464 | } else if (strcmp(name, |
466 | else if (strcmp(name, "permit-pty") == 0) | 465 | "permit-agent-forwarding") == 0) { |
467 | cert_no_pty_flag = 0; | 466 | *cert_no_agent_forwarding_flag = 0; |
468 | else if (strcmp(name, "permit-user-rc") == 0) | 467 | found = 1; |
469 | cert_no_user_rc = 0; | 468 | } else if (strcmp(name, |
470 | else if (strcmp(name, "force-command") == 0) { | 469 | "permit-port-forwarding") == 0) { |
471 | char *command = buffer_get_string_ret(&data, &clen); | 470 | *cert_no_port_forwarding_flag = 0; |
472 | 471 | found = 1; | |
473 | if (command == NULL) { | 472 | } else if (strcmp(name, "permit-pty") == 0) { |
474 | error("Certificate constraint \"%s\" corrupt", | 473 | *cert_no_pty_flag = 0; |
475 | name); | 474 | found = 1; |
476 | goto out; | 475 | } else if (strcmp(name, "permit-user-rc") == 0) { |
477 | } | 476 | *cert_no_user_rc = 0; |
478 | if (strlen(command) != clen) { | 477 | found = 1; |
479 | error("force-command constraint contains \\0"); | ||
480 | goto out; | ||
481 | } | ||
482 | if (cert_forced_command != NULL) { | ||
483 | error("Certificate has multiple " | ||
484 | "force-command options"); | ||
485 | xfree(command); | ||
486 | goto out; | ||
487 | } | ||
488 | cert_forced_command = command; | ||
489 | } else if (strcmp(name, "source-address") == 0) { | ||
490 | char *allowed = buffer_get_string_ret(&data, &clen); | ||
491 | const char *remote_ip = get_remote_ipaddr(); | ||
492 | |||
493 | if (allowed == NULL) { | ||
494 | error("Certificate constraint \"%s\" corrupt", | ||
495 | name); | ||
496 | goto out; | ||
497 | } | ||
498 | if (strlen(allowed) != clen) { | ||
499 | error("source-address constraint contains \\0"); | ||
500 | goto out; | ||
501 | } | 478 | } |
502 | if (cert_source_address_done++) { | 479 | } |
503 | error("Certificate has multiple " | 480 | if (!found && (which & OPTIONS_CRITICAL) != 0) { |
504 | "source-address options"); | 481 | if (strcmp(name, "force-command") == 0) { |
505 | xfree(allowed); | 482 | if ((command = buffer_get_string_ret(&data, |
506 | goto out; | 483 | &clen)) == NULL) { |
484 | error("Certificate constraint \"%s\" " | ||
485 | "corrupt", name); | ||
486 | goto out; | ||
487 | } | ||
488 | if (strlen(command) != clen) { | ||
489 | error("force-command constraint " | ||
490 | "contains \\0"); | ||
491 | goto out; | ||
492 | } | ||
493 | if (*cert_forced_command != NULL) { | ||
494 | error("Certificate has multiple " | ||
495 | "force-command options"); | ||
496 | xfree(command); | ||
497 | goto out; | ||
498 | } | ||
499 | *cert_forced_command = command; | ||
500 | found = 1; | ||
507 | } | 501 | } |
508 | switch (addr_match_cidr_list(remote_ip, allowed)) { | 502 | if (strcmp(name, "source-address") == 0) { |
509 | case 1: | 503 | if ((allowed = buffer_get_string_ret(&data, |
510 | /* accepted */ | 504 | &clen)) == NULL) { |
511 | xfree(allowed); | 505 | error("Certificate constraint " |
512 | break; | 506 | "\"%s\" corrupt", name); |
513 | case 0: | 507 | goto out; |
514 | /* no match */ | 508 | } |
515 | logit("Authentication tried for %.100s with " | 509 | if (strlen(allowed) != clen) { |
516 | "valid certificate but not from a " | 510 | error("source-address constraint " |
517 | "permitted host (ip=%.200s).", | 511 | "contains \\0"); |
518 | pw->pw_name, remote_ip); | 512 | goto out; |
519 | auth_debug_add("Your address '%.200s' is not " | 513 | } |
520 | "permitted to use this certificate for " | 514 | if ((*cert_source_address_done)++) { |
521 | "login.", remote_ip); | 515 | error("Certificate has multiple " |
522 | xfree(allowed); | 516 | "source-address options"); |
523 | goto out; | 517 | xfree(allowed); |
524 | case -1: | 518 | goto out; |
525 | error("Certificate source-address contents " | 519 | } |
526 | "invalid"); | 520 | remote_ip = get_remote_ipaddr(); |
527 | xfree(allowed); | 521 | switch (addr_match_cidr_list(remote_ip, |
528 | goto out; | 522 | allowed)) { |
523 | case 1: | ||
524 | /* accepted */ | ||
525 | xfree(allowed); | ||
526 | break; | ||
527 | case 0: | ||
528 | /* no match */ | ||
529 | logit("Authentication tried for %.100s " | ||
530 | "with valid certificate but not " | ||
531 | "from a permitted host " | ||
532 | "(ip=%.200s).", pw->pw_name, | ||
533 | remote_ip); | ||
534 | auth_debug_add("Your address '%.200s' " | ||
535 | "is not permitted to use this " | ||
536 | "certificate for login.", | ||
537 | remote_ip); | ||
538 | xfree(allowed); | ||
539 | goto out; | ||
540 | case -1: | ||
541 | error("Certificate source-address " | ||
542 | "contents invalid"); | ||
543 | xfree(allowed); | ||
544 | goto out; | ||
545 | } | ||
546 | found = 1; | ||
529 | } | 547 | } |
530 | } else { | ||
531 | error("Certificate constraint \"%s\" is not supported", | ||
532 | name); | ||
533 | goto out; | ||
534 | } | 548 | } |
535 | 549 | ||
536 | if (buffer_len(&data) != 0) { | 550 | if (!found) { |
537 | error("Certificate constraint \"%s\" corrupt " | 551 | if (crit) { |
552 | error("Certificate critical option \"%s\" " | ||
553 | "is not supported", name); | ||
554 | goto out; | ||
555 | } else { | ||
556 | logit("Certificate extension \"%s\" " | ||
557 | "is not supported", name); | ||
558 | } | ||
559 | } else if (buffer_len(&data) != 0) { | ||
560 | error("Certificate option \"%s\" corrupt " | ||
538 | "(extra data)", name); | 561 | "(extra data)", name); |
539 | goto out; | 562 | goto out; |
540 | } | 563 | } |
@@ -543,10 +566,73 @@ auth_cert_options(Key *k, struct passwd *pw) | |||
543 | xfree(data_blob); | 566 | xfree(data_blob); |
544 | name = data_blob = NULL; | 567 | name = data_blob = NULL; |
545 | } | 568 | } |
546 | |||
547 | /* successfully parsed all options */ | 569 | /* successfully parsed all options */ |
548 | ret = 0; | 570 | ret = 0; |
549 | 571 | ||
572 | out: | ||
573 | if (ret != 0 && | ||
574 | cert_forced_command != NULL && | ||
575 | *cert_forced_command != NULL) { | ||
576 | xfree(*cert_forced_command); | ||
577 | *cert_forced_command = NULL; | ||
578 | } | ||
579 | if (name != NULL) | ||
580 | xfree(name); | ||
581 | if (data_blob != NULL) | ||
582 | xfree(data_blob); | ||
583 | buffer_free(&data); | ||
584 | buffer_free(&c); | ||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * Set options from critical certificate options. These supersede user key | ||
590 | * options so this must be called after auth_parse_options(). | ||
591 | */ | ||
592 | int | ||
593 | auth_cert_options(Key *k, struct passwd *pw) | ||
594 | { | ||
595 | int cert_no_port_forwarding_flag = 1; | ||
596 | int cert_no_agent_forwarding_flag = 1; | ||
597 | int cert_no_x11_forwarding_flag = 1; | ||
598 | int cert_no_pty_flag = 1; | ||
599 | int cert_no_user_rc = 1; | ||
600 | char *cert_forced_command = NULL; | ||
601 | int cert_source_address_done = 0; | ||
602 | |||
603 | if (key_cert_is_legacy(k)) { | ||
604 | /* All options are in the one field for v00 certs */ | ||
605 | if (parse_option_list(buffer_ptr(&k->cert->critical), | ||
606 | buffer_len(&k->cert->critical), pw, | ||
607 | OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1, | ||
608 | &cert_no_port_forwarding_flag, | ||
609 | &cert_no_agent_forwarding_flag, | ||
610 | &cert_no_x11_forwarding_flag, | ||
611 | &cert_no_pty_flag, | ||
612 | &cert_no_user_rc, | ||
613 | &cert_forced_command, | ||
614 | &cert_source_address_done) == -1) | ||
615 | return -1; | ||
616 | } else { | ||
617 | /* Separate options and extensions for v01 certs */ | ||
618 | if (parse_option_list(buffer_ptr(&k->cert->critical), | ||
619 | buffer_len(&k->cert->critical), pw, | ||
620 | OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, | ||
621 | &cert_forced_command, | ||
622 | &cert_source_address_done) == -1) | ||
623 | return -1; | ||
624 | if (parse_option_list(buffer_ptr(&k->cert->extensions), | ||
625 | buffer_len(&k->cert->extensions), pw, | ||
626 | OPTIONS_EXTENSIONS, 1, | ||
627 | &cert_no_port_forwarding_flag, | ||
628 | &cert_no_agent_forwarding_flag, | ||
629 | &cert_no_x11_forwarding_flag, | ||
630 | &cert_no_pty_flag, | ||
631 | &cert_no_user_rc, | ||
632 | NULL, NULL) == -1) | ||
633 | return -1; | ||
634 | } | ||
635 | |||
550 | no_port_forwarding_flag |= cert_no_port_forwarding_flag; | 636 | no_port_forwarding_flag |= cert_no_port_forwarding_flag; |
551 | no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; | 637 | no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; |
552 | no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; | 638 | no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; |
@@ -558,14 +644,6 @@ auth_cert_options(Key *k, struct passwd *pw) | |||
558 | xfree(forced_command); | 644 | xfree(forced_command); |
559 | forced_command = cert_forced_command; | 645 | forced_command = cert_forced_command; |
560 | } | 646 | } |
561 | 647 | return 0; | |
562 | out: | ||
563 | if (name != NULL) | ||
564 | xfree(name); | ||
565 | if (data_blob != NULL) | ||
566 | xfree(data_blob); | ||
567 | buffer_free(&data); | ||
568 | buffer_free(&c); | ||
569 | return ret; | ||
570 | } | 648 | } |
571 | 649 | ||
diff --git a/ssh-keygen.c b/ssh-keygen.c index 1eb25bd94..14eee6f87 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.189 2010/04/23 22:48:31 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.190 2010/05/20 23:46:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -122,17 +122,16 @@ u_int64_t cert_valid_from = 0; | |||
122 | u_int64_t cert_valid_to = ~0ULL; | 122 | u_int64_t cert_valid_to = ~0ULL; |
123 | 123 | ||
124 | /* Certificate options */ | 124 | /* Certificate options */ |
125 | #define CRITOPT_X_FWD (1) | 125 | #define CERTOPT_X_FWD (1) |
126 | #define CRITOPT_AGENT_FWD (1<<1) | 126 | #define CERTOPT_AGENT_FWD (1<<1) |
127 | #define CRITOPT_PORT_FWD (1<<2) | 127 | #define CERTOPT_PORT_FWD (1<<2) |
128 | #define CRITOPT_PTY (1<<3) | 128 | #define CERTOPT_PTY (1<<3) |
129 | #define CRITOPT_USER_RC (1<<4) | 129 | #define CERTOPT_USER_RC (1<<4) |
130 | #define CRITOPT_DEFAULT (CRITOPT_X_FWD|CRITOPT_AGENT_FWD| \ | 130 | #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \ |
131 | CRITOPT_PORT_FWD|CRITOPT_PTY| \ | 131 | CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC) |
132 | CRITOPT_USER_RC) | 132 | u_int32_t certflags_flags = CERTOPT_DEFAULT; |
133 | u_int32_t critical_flags = CRITOPT_DEFAULT; | 133 | char *certflags_command = NULL; |
134 | char *critical_command = NULL; | 134 | char *certflags_src_addr = NULL; |
135 | char *critical_src_addr = NULL; | ||
136 | 135 | ||
137 | /* Dump public key file in format used by real and the original SSH 2 */ | 136 | /* Dump public key file in format used by real and the original SSH 2 */ |
138 | int convert_to_ssh2 = 0; | 137 | int convert_to_ssh2 = 0; |
@@ -1133,24 +1132,33 @@ add_string_option(Buffer *c, const char *name, const char *value) | |||
1133 | buffer_free(&b); | 1132 | buffer_free(&b); |
1134 | } | 1133 | } |
1135 | 1134 | ||
1135 | #define OPTIONS_CRITICAL 1 | ||
1136 | #define OPTIONS_EXTENSIONS 2 | ||
1136 | static void | 1137 | static void |
1137 | prepare_options_buf(Buffer *c) | 1138 | prepare_options_buf(Buffer *c, int which) |
1138 | { | 1139 | { |
1139 | buffer_clear(c); | 1140 | buffer_clear(c); |
1140 | if ((critical_flags & CRITOPT_X_FWD) != 0) | 1141 | if ((which & OPTIONS_EXTENSIONS) != 0 && |
1142 | (certflags_flags & CERTOPT_X_FWD) != 0) | ||
1141 | add_flag_option(c, "permit-X11-forwarding"); | 1143 | add_flag_option(c, "permit-X11-forwarding"); |
1142 | if ((critical_flags & CRITOPT_AGENT_FWD) != 0) | 1144 | if ((which & OPTIONS_EXTENSIONS) != 0 && |
1145 | (certflags_flags & CERTOPT_AGENT_FWD) != 0) | ||
1143 | add_flag_option(c, "permit-agent-forwarding"); | 1146 | add_flag_option(c, "permit-agent-forwarding"); |
1144 | if ((critical_flags & CRITOPT_PORT_FWD) != 0) | 1147 | if ((which & OPTIONS_EXTENSIONS) != 0 && |
1148 | (certflags_flags & CERTOPT_PORT_FWD) != 0) | ||
1145 | add_flag_option(c, "permit-port-forwarding"); | 1149 | add_flag_option(c, "permit-port-forwarding"); |
1146 | if ((critical_flags & CRITOPT_PTY) != 0) | 1150 | if ((which & OPTIONS_EXTENSIONS) != 0 && |
1151 | (certflags_flags & CERTOPT_PTY) != 0) | ||
1147 | add_flag_option(c, "permit-pty"); | 1152 | add_flag_option(c, "permit-pty"); |
1148 | if ((critical_flags & CRITOPT_USER_RC) != 0) | 1153 | if ((which & OPTIONS_EXTENSIONS) != 0 && |
1154 | (certflags_flags & CERTOPT_USER_RC) != 0) | ||
1149 | add_flag_option(c, "permit-user-rc"); | 1155 | add_flag_option(c, "permit-user-rc"); |
1150 | if (critical_command != NULL) | 1156 | if ((which & OPTIONS_CRITICAL) != 0 && |
1151 | add_string_option(c, "force-command", critical_command); | 1157 | certflags_command != NULL) |
1152 | if (critical_src_addr != NULL) | 1158 | add_string_option(c, "force-command", certflags_command); |
1153 | add_string_option(c, "source-address", critical_src_addr); | 1159 | if ((which & OPTIONS_CRITICAL) != 0 && |
1160 | certflags_src_addr != NULL) | ||
1161 | add_string_option(c, "source-address", certflags_src_addr); | ||
1154 | } | 1162 | } |
1155 | 1163 | ||
1156 | static void | 1164 | static void |
@@ -1218,7 +1226,15 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) | |||
1218 | public->cert->principals = plist; | 1226 | public->cert->principals = plist; |
1219 | public->cert->valid_after = cert_valid_from; | 1227 | public->cert->valid_after = cert_valid_from; |
1220 | public->cert->valid_before = cert_valid_to; | 1228 | public->cert->valid_before = cert_valid_to; |
1221 | prepare_options_buf(&public->cert->critical); | 1229 | if (v00) { |
1230 | prepare_options_buf(&public->cert->critical, | ||
1231 | OPTIONS_CRITICAL|OPTIONS_EXTENSIONS); | ||
1232 | } else { | ||
1233 | prepare_options_buf(&public->cert->critical, | ||
1234 | OPTIONS_CRITICAL); | ||
1235 | prepare_options_buf(&public->cert->extensions, | ||
1236 | OPTIONS_EXTENSIONS); | ||
1237 | } | ||
1222 | public->cert->signature_key = key_from_private(ca); | 1238 | public->cert->signature_key = key_from_private(ca); |
1223 | 1239 | ||
1224 | if (key_certify(public, ca) != 0) | 1240 | if (key_certify(public, ca) != 0) |
@@ -1354,43 +1370,43 @@ add_cert_option(char *opt) | |||
1354 | char *val; | 1370 | char *val; |
1355 | 1371 | ||
1356 | if (strcmp(opt, "clear") == 0) | 1372 | if (strcmp(opt, "clear") == 0) |
1357 | critical_flags = 0; | 1373 | certflags_flags = 0; |
1358 | else if (strcasecmp(opt, "no-x11-forwarding") == 0) | 1374 | else if (strcasecmp(opt, "no-x11-forwarding") == 0) |
1359 | critical_flags &= ~CRITOPT_X_FWD; | 1375 | certflags_flags &= ~CERTOPT_X_FWD; |
1360 | else if (strcasecmp(opt, "permit-x11-forwarding") == 0) | 1376 | else if (strcasecmp(opt, "permit-x11-forwarding") == 0) |
1361 | critical_flags |= CRITOPT_X_FWD; | 1377 | certflags_flags |= CERTOPT_X_FWD; |
1362 | else if (strcasecmp(opt, "no-agent-forwarding") == 0) | 1378 | else if (strcasecmp(opt, "no-agent-forwarding") == 0) |
1363 | critical_flags &= ~CRITOPT_AGENT_FWD; | 1379 | certflags_flags &= ~CERTOPT_AGENT_FWD; |
1364 | else if (strcasecmp(opt, "permit-agent-forwarding") == 0) | 1380 | else if (strcasecmp(opt, "permit-agent-forwarding") == 0) |
1365 | critical_flags |= CRITOPT_AGENT_FWD; | 1381 | certflags_flags |= CERTOPT_AGENT_FWD; |
1366 | else if (strcasecmp(opt, "no-port-forwarding") == 0) | 1382 | else if (strcasecmp(opt, "no-port-forwarding") == 0) |
1367 | critical_flags &= ~CRITOPT_PORT_FWD; | 1383 | certflags_flags &= ~CERTOPT_PORT_FWD; |
1368 | else if (strcasecmp(opt, "permit-port-forwarding") == 0) | 1384 | else if (strcasecmp(opt, "permit-port-forwarding") == 0) |
1369 | critical_flags |= CRITOPT_PORT_FWD; | 1385 | certflags_flags |= CERTOPT_PORT_FWD; |
1370 | else if (strcasecmp(opt, "no-pty") == 0) | 1386 | else if (strcasecmp(opt, "no-pty") == 0) |
1371 | critical_flags &= ~CRITOPT_PTY; | 1387 | certflags_flags &= ~CERTOPT_PTY; |
1372 | else if (strcasecmp(opt, "permit-pty") == 0) | 1388 | else if (strcasecmp(opt, "permit-pty") == 0) |
1373 | critical_flags |= CRITOPT_PTY; | 1389 | certflags_flags |= CERTOPT_PTY; |
1374 | else if (strcasecmp(opt, "no-user-rc") == 0) | 1390 | else if (strcasecmp(opt, "no-user-rc") == 0) |
1375 | critical_flags &= ~CRITOPT_USER_RC; | 1391 | certflags_flags &= ~CERTOPT_USER_RC; |
1376 | else if (strcasecmp(opt, "permit-user-rc") == 0) | 1392 | else if (strcasecmp(opt, "permit-user-rc") == 0) |
1377 | critical_flags |= CRITOPT_USER_RC; | 1393 | certflags_flags |= CERTOPT_USER_RC; |
1378 | else if (strncasecmp(opt, "force-command=", 14) == 0) { | 1394 | else if (strncasecmp(opt, "force-command=", 14) == 0) { |
1379 | val = opt + 14; | 1395 | val = opt + 14; |
1380 | if (*val == '\0') | 1396 | if (*val == '\0') |
1381 | fatal("Empty force-command option"); | 1397 | fatal("Empty force-command option"); |
1382 | if (critical_command != NULL) | 1398 | if (certflags_command != NULL) |
1383 | fatal("force-command already specified"); | 1399 | fatal("force-command already specified"); |
1384 | critical_command = xstrdup(val); | 1400 | certflags_command = xstrdup(val); |
1385 | } else if (strncasecmp(opt, "source-address=", 15) == 0) { | 1401 | } else if (strncasecmp(opt, "source-address=", 15) == 0) { |
1386 | val = opt + 15; | 1402 | val = opt + 15; |
1387 | if (*val == '\0') | 1403 | if (*val == '\0') |
1388 | fatal("Empty source-address option"); | 1404 | fatal("Empty source-address option"); |
1389 | if (critical_src_addr != NULL) | 1405 | if (certflags_src_addr != NULL) |
1390 | fatal("source-address already specified"); | 1406 | fatal("source-address already specified"); |
1391 | if (addr_match_cidr_list(NULL, val) != 0) | 1407 | if (addr_match_cidr_list(NULL, val) != 0) |
1392 | fatal("Invalid source-address list"); | 1408 | fatal("Invalid source-address list"); |
1393 | critical_src_addr = xstrdup(val); | 1409 | certflags_src_addr = xstrdup(val); |
1394 | } else | 1410 | } else |
1395 | fatal("Unsupported certificate option \"%s\"", opt); | 1411 | fatal("Unsupported certificate option \"%s\"", opt); |
1396 | } | 1412 | } |
@@ -1667,7 +1683,7 @@ main(int argc, char **argv) | |||
1667 | break; | 1683 | break; |
1668 | case 'h': | 1684 | case 'h': |
1669 | cert_key_type = SSH2_CERT_TYPE_HOST; | 1685 | cert_key_type = SSH2_CERT_TYPE_HOST; |
1670 | critical_flags = 0; | 1686 | certflags_flags = 0; |
1671 | break; | 1687 | break; |
1672 | case 'i': | 1688 | case 'i': |
1673 | case 'X': | 1689 | case 'X': |