summaryrefslogtreecommitdiff
path: root/auth-options.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2015-01-14 10:30:34 +0000
committerDamien Miller <djm@mindrot.org>2015-01-14 21:34:20 +1100
commitae8b463217f7c9b66655bfc3945c050ffdaeb861 (patch)
tree34ff889bdf7e4751cbb7bf475570ec94e800ace0 /auth-options.c
parent540e891191b98b89ee90aacf5b14a4a68635e763 (diff)
upstream commit
swith auth-options to new sshbuf/sshkey; ok djm@
Diffstat (limited to 'auth-options.c')
-rw-r--r--auth-options.c83
1 files changed, 39 insertions, 44 deletions
diff --git a/auth-options.c b/auth-options.c
index f3d9c9df8..4f0da9c04 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.64 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.65 2015/01/14 10:30:34 markus 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
@@ -21,15 +21,19 @@
21#include <stdarg.h> 21#include <stdarg.h>
22 22
23#include "openbsd-compat/sys-queue.h" 23#include "openbsd-compat/sys-queue.h"
24
25#include "key.h" /* XXX for typedef */
26#include "buffer.h" /* XXX for typedef */
24#include "xmalloc.h" 27#include "xmalloc.h"
25#include "match.h" 28#include "match.h"
29#include "ssherr.h"
26#include "log.h" 30#include "log.h"
27#include "canohost.h" 31#include "canohost.h"
28#include "buffer.h" 32#include "sshbuf.h"
29#include "misc.h" 33#include "misc.h"
30#include "channels.h" 34#include "channels.h"
31#include "servconf.h" 35#include "servconf.h"
32#include "key.h" 36#include "sshkey.h"
33#include "auth-options.h" 37#include "auth-options.h"
34#include "hostfile.h" 38#include "hostfile.h"
35#include "auth.h" 39#include "auth.h"
@@ -417,7 +421,7 @@ bad_option:
417#define OPTIONS_CRITICAL 1 421#define OPTIONS_CRITICAL 1
418#define OPTIONS_EXTENSIONS 2 422#define OPTIONS_EXTENSIONS 2
419static int 423static int
420parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, 424parse_option_list(struct sshbuf *oblob, struct passwd *pw,
421 u_int which, int crit, 425 u_int which, int crit,
422 int *cert_no_port_forwarding_flag, 426 int *cert_no_port_forwarding_flag,
423 int *cert_no_agent_forwarding_flag, 427 int *cert_no_agent_forwarding_flag,
@@ -430,26 +434,25 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
430 char *command, *allowed; 434 char *command, *allowed;
431 const char *remote_ip; 435 const char *remote_ip;
432 char *name = NULL; 436 char *name = NULL;
433 u_char *data_blob = NULL; 437 struct sshbuf *c = NULL, *data = NULL;
434 u_int nlen, dlen, clen; 438 int r, ret = -1, result, found;
435 Buffer c, data;
436 int ret = -1, result, found;
437
438 buffer_init(&data);
439 439
440 /* Make copy to avoid altering original */ 440 if ((c = sshbuf_fromb(oblob)) == NULL) {
441 buffer_init(&c); 441 error("%s: sshbuf_fromb failed", __func__);
442 buffer_append(&c, optblob, optblob_len); 442 goto out;
443 }
443 444
444 while (buffer_len(&c) > 0) { 445 while (sshbuf_len(c) > 0) {
445 if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL || 446 sshbuf_free(data);
446 (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) { 447 data = NULL;
447 error("Certificate options corrupt"); 448 if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 ||
449 (r = sshbuf_froms(c, &data)) != 0) {
450 error("Unable to parse certificate options: %s",
451 ssh_err(r));
448 goto out; 452 goto out;
449 } 453 }
450 buffer_append(&data, data_blob, dlen); 454 debug3("found certificate option \"%.100s\" len %zu",
451 debug3("found certificate option \"%.100s\" len %u", 455 name, sshbuf_len(data));
452 name, dlen);
453 found = 0; 456 found = 0;
454 if ((which & OPTIONS_EXTENSIONS) != 0) { 457 if ((which & OPTIONS_EXTENSIONS) != 0) {
455 if (strcmp(name, "permit-X11-forwarding") == 0) { 458 if (strcmp(name, "permit-X11-forwarding") == 0) {
@@ -473,10 +476,10 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
473 } 476 }
474 if (!found && (which & OPTIONS_CRITICAL) != 0) { 477 if (!found && (which & OPTIONS_CRITICAL) != 0) {
475 if (strcmp(name, "force-command") == 0) { 478 if (strcmp(name, "force-command") == 0) {
476 if ((command = buffer_get_cstring_ret(&data, 479 if ((r = sshbuf_get_cstring(data, &command,
477 &clen)) == NULL) { 480 NULL)) != 0) {
478 error("Certificate constraint \"%s\" " 481 error("Unable to parse \"%s\" "
479 "corrupt", name); 482 "section: %s", name, ssh_err(r));
480 goto out; 483 goto out;
481 } 484 }
482 if (*cert_forced_command != NULL) { 485 if (*cert_forced_command != NULL) {
@@ -489,10 +492,10 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
489 found = 1; 492 found = 1;
490 } 493 }
491 if (strcmp(name, "source-address") == 0) { 494 if (strcmp(name, "source-address") == 0) {
492 if ((allowed = buffer_get_cstring_ret(&data, 495 if ((r = sshbuf_get_cstring(data, &allowed,
493 &clen)) == NULL) { 496 NULL)) != 0) {
494 error("Certificate constraint " 497 error("Unable to parse \"%s\" "
495 "\"%s\" corrupt", name); 498 "section: %s", name, ssh_err(r));
496 goto out; 499 goto out;
497 } 500 }
498 if ((*cert_source_address_done)++) { 501 if ((*cert_source_address_done)++) {
@@ -540,16 +543,13 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
540 logit("Certificate extension \"%s\" " 543 logit("Certificate extension \"%s\" "
541 "is not supported", name); 544 "is not supported", name);
542 } 545 }
543 } else if (buffer_len(&data) != 0) { 546 } else if (sshbuf_len(data) != 0) {
544 error("Certificate option \"%s\" corrupt " 547 error("Certificate option \"%s\" corrupt "
545 "(extra data)", name); 548 "(extra data)", name);
546 goto out; 549 goto out;
547 } 550 }
548 buffer_clear(&data);
549 free(name); 551 free(name);
550 free(data_blob);
551 name = NULL; 552 name = NULL;
552 data_blob = NULL;
553 } 553 }
554 /* successfully parsed all options */ 554 /* successfully parsed all options */
555 ret = 0; 555 ret = 0;
@@ -563,10 +563,8 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
563 } 563 }
564 if (name != NULL) 564 if (name != NULL)
565 free(name); 565 free(name);
566 if (data_blob != NULL) 566 sshbuf_free(data);
567 free(data_blob); 567 sshbuf_free(c);
568 buffer_free(&data);
569 buffer_free(&c);
570 return ret; 568 return ret;
571} 569}
572 570
@@ -575,7 +573,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
575 * options so this must be called after auth_parse_options(). 573 * options so this must be called after auth_parse_options().
576 */ 574 */
577int 575int
578auth_cert_options(Key *k, struct passwd *pw) 576auth_cert_options(struct sshkey *k, struct passwd *pw)
579{ 577{
580 int cert_no_port_forwarding_flag = 1; 578 int cert_no_port_forwarding_flag = 1;
581 int cert_no_agent_forwarding_flag = 1; 579 int cert_no_agent_forwarding_flag = 1;
@@ -585,10 +583,9 @@ auth_cert_options(Key *k, struct passwd *pw)
585 char *cert_forced_command = NULL; 583 char *cert_forced_command = NULL;
586 int cert_source_address_done = 0; 584 int cert_source_address_done = 0;
587 585
588 if (key_cert_is_legacy(k)) { 586 if (sshkey_cert_is_legacy(k)) {
589 /* All options are in the one field for v00 certs */ 587 /* All options are in the one field for v00 certs */
590 if (parse_option_list(buffer_ptr(k->cert->critical), 588 if (parse_option_list(k->cert->critical, pw,
591 buffer_len(k->cert->critical), pw,
592 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1, 589 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1,
593 &cert_no_port_forwarding_flag, 590 &cert_no_port_forwarding_flag,
594 &cert_no_agent_forwarding_flag, 591 &cert_no_agent_forwarding_flag,
@@ -600,14 +597,12 @@ auth_cert_options(Key *k, struct passwd *pw)
600 return -1; 597 return -1;
601 } else { 598 } else {
602 /* Separate options and extensions for v01 certs */ 599 /* Separate options and extensions for v01 certs */
603 if (parse_option_list(buffer_ptr(k->cert->critical), 600 if (parse_option_list(k->cert->critical, pw,
604 buffer_len(k->cert->critical), pw,
605 OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, 601 OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL,
606 &cert_forced_command, 602 &cert_forced_command,
607 &cert_source_address_done) == -1) 603 &cert_source_address_done) == -1)
608 return -1; 604 return -1;
609 if (parse_option_list(buffer_ptr(k->cert->extensions), 605 if (parse_option_list(k->cert->extensions, pw,
610 buffer_len(k->cert->extensions), pw,
611 OPTIONS_EXTENSIONS, 1, 606 OPTIONS_EXTENSIONS, 1,
612 &cert_no_port_forwarding_flag, 607 &cert_no_port_forwarding_flag,
613 &cert_no_agent_forwarding_flag, 608 &cert_no_agent_forwarding_flag,