|
Lines 127-139
static char *certflags_command = NULL;
Link Here
|
| 127 |
static char *certflags_src_addr = NULL; |
127 |
static char *certflags_src_addr = NULL; |
| 128 |
|
128 |
|
| 129 |
/* Arbitrary extensions specified by user */ |
129 |
/* Arbitrary extensions specified by user */ |
| 130 |
struct cert_userext { |
130 |
struct cert_ext { |
| 131 |
char *key; |
131 |
char *key; |
| 132 |
char *val; |
132 |
char *val; |
| 133 |
int crit; |
133 |
int crit; |
| 134 |
}; |
134 |
}; |
| 135 |
static struct cert_userext *cert_userext; |
135 |
static struct cert_ext *cert_ext; |
| 136 |
static size_t ncert_userext; |
136 |
static size_t ncert_ext; |
| 137 |
|
137 |
|
| 138 |
/* Conversion to/from various formats */ |
138 |
/* Conversion to/from various formats */ |
| 139 |
enum { |
139 |
enum { |
|
Lines 1579-1609
do_change_comment(struct passwd *pw, const char *identity_comment)
Link Here
|
| 1579 |
} |
1579 |
} |
| 1580 |
|
1580 |
|
| 1581 |
static void |
1581 |
static void |
| 1582 |
add_flag_option(struct sshbuf *c, const char *name) |
1582 |
cert_ext_add(const char *key, const char *value, int iscrit) |
| 1583 |
{ |
1583 |
{ |
| 1584 |
int r; |
1584 |
cert_ext = xreallocarray(cert_ext, ncert_ext + 1, sizeof(*cert_ext)); |
| 1585 |
|
1585 |
cert_ext[ncert_ext].key = xstrdup(key); |
| 1586 |
debug3("%s: %s", __func__, name); |
1586 |
cert_ext[ncert_ext].val = value == NULL ? NULL : xstrdup(value); |
| 1587 |
if ((r = sshbuf_put_cstring(c, name)) != 0 || |
1587 |
cert_ext[ncert_ext].crit = iscrit; |
| 1588 |
(r = sshbuf_put_string(c, NULL, 0)) != 0) |
1588 |
ncert_ext++; |
| 1589 |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
|
|
| 1590 |
} |
1589 |
} |
| 1591 |
|
1590 |
|
| 1592 |
static void |
1591 |
/* qsort(3) comparison function for certificate extensions */ |
| 1593 |
add_string_option(struct sshbuf *c, const char *name, const char *value) |
1592 |
static int |
|
|
1593 |
cert_ext_cmp(const void *_a, const void *_b) |
| 1594 |
{ |
1594 |
{ |
| 1595 |
struct sshbuf *b; |
1595 |
const struct cert_ext *a = (const struct cert_ext *)_a; |
|
|
1596 |
const struct cert_ext *b = (const struct cert_ext *)_b; |
| 1596 |
int r; |
1597 |
int r; |
| 1597 |
|
1598 |
|
| 1598 |
debug3("%s: %s=%s", __func__, name, value); |
1599 |
if (a->crit != b->crit) |
| 1599 |
if ((b = sshbuf_new()) == NULL) |
1600 |
return (a->crit < b->crit) ? -1 : 1; |
| 1600 |
fatal("%s: sshbuf_new failed", __func__); |
1601 |
if ((r = strcmp(a->key, b->key)) != 0) |
| 1601 |
if ((r = sshbuf_put_cstring(b, value)) != 0 || |
1602 |
return r; |
| 1602 |
(r = sshbuf_put_cstring(c, name)) != 0 || |
1603 |
if ((a->val == NULL) != (b->val == NULL)) |
| 1603 |
(r = sshbuf_put_stringb(c, b)) != 0) |
1604 |
return (a->val == NULL) ? -1 : 1; |
| 1604 |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1605 |
if (a->val != NULL && (r = strcmp(a->val, b->val)) != 0) |
| 1605 |
|
1606 |
return r; |
| 1606 |
sshbuf_free(b); |
1607 |
return 0; |
| 1607 |
} |
1608 |
} |
| 1608 |
|
1609 |
|
| 1609 |
#define OPTIONS_CRITICAL 1 |
1610 |
#define OPTIONS_CRITICAL 1 |
|
Lines 1611-1654
add_string_option(struct sshbuf *c, const char *name, const char *value)
Link Here
|
| 1611 |
static void |
1612 |
static void |
| 1612 |
prepare_options_buf(struct sshbuf *c, int which) |
1613 |
prepare_options_buf(struct sshbuf *c, int which) |
| 1613 |
{ |
1614 |
{ |
|
|
1615 |
struct sshbuf *b; |
| 1614 |
size_t i; |
1616 |
size_t i; |
|
|
1617 |
int r; |
| 1618 |
const struct cert_ext *ext; |
| 1615 |
|
1619 |
|
|
|
1620 |
if ((b = sshbuf_new()) == NULL) |
| 1621 |
fatal("%s: sshbuf_new failed", __func__); |
| 1616 |
sshbuf_reset(c); |
1622 |
sshbuf_reset(c); |
| 1617 |
if ((which & OPTIONS_CRITICAL) != 0 && |
1623 |
for (i = 0; i < ncert_ext; i++) { |
| 1618 |
certflags_command != NULL) |
1624 |
ext = &cert_ext[i]; |
| 1619 |
add_string_option(c, "force-command", certflags_command); |
1625 |
if ((ext->crit && (which & OPTIONS_EXTENSIONS)) || |
| 1620 |
if ((which & OPTIONS_EXTENSIONS) != 0 && |
1626 |
(!ext->crit && (which & OPTIONS_CRITICAL))) |
| 1621 |
(certflags_flags & CERTOPT_X_FWD) != 0) |
|
|
| 1622 |
add_flag_option(c, "permit-X11-forwarding"); |
| 1623 |
if ((which & OPTIONS_EXTENSIONS) != 0 && |
| 1624 |
(certflags_flags & CERTOPT_AGENT_FWD) != 0) |
| 1625 |
add_flag_option(c, "permit-agent-forwarding"); |
| 1626 |
if ((which & OPTIONS_EXTENSIONS) != 0 && |
| 1627 |
(certflags_flags & CERTOPT_PORT_FWD) != 0) |
| 1628 |
add_flag_option(c, "permit-port-forwarding"); |
| 1629 |
if ((which & OPTIONS_EXTENSIONS) != 0 && |
| 1630 |
(certflags_flags & CERTOPT_PTY) != 0) |
| 1631 |
add_flag_option(c, "permit-pty"); |
| 1632 |
if ((which & OPTIONS_EXTENSIONS) != 0 && |
| 1633 |
(certflags_flags & CERTOPT_USER_RC) != 0) |
| 1634 |
add_flag_option(c, "permit-user-rc"); |
| 1635 |
if ((which & OPTIONS_EXTENSIONS) != 0 && |
| 1636 |
(certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0) |
| 1637 |
add_flag_option(c, "no-touch-required"); |
| 1638 |
if ((which & OPTIONS_CRITICAL) != 0 && |
| 1639 |
certflags_src_addr != NULL) |
| 1640 |
add_string_option(c, "source-address", certflags_src_addr); |
| 1641 |
for (i = 0; i < ncert_userext; i++) { |
| 1642 |
if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) || |
| 1643 |
(!cert_userext[i].crit && (which & OPTIONS_CRITICAL))) |
| 1644 |
continue; |
1627 |
continue; |
| 1645 |
if (cert_userext[i].val == NULL) |
1628 |
if (ext->val == NULL) { |
| 1646 |
add_flag_option(c, cert_userext[i].key); |
1629 |
/* flag option */ |
| 1647 |
else { |
1630 |
debug3("%s: %s", __func__, ext->key); |
| 1648 |
add_string_option(c, cert_userext[i].key, |
1631 |
if ((r = sshbuf_put_cstring(c, ext->key)) != 0 || |
| 1649 |
cert_userext[i].val); |
1632 |
(r = sshbuf_put_string(c, NULL, 0)) != 0) |
|
|
1633 |
fatal("%s: buffer: %s", __func__, ssh_err(r)); |
| 1634 |
} else { |
| 1635 |
/* key/value option */ |
| 1636 |
debug3("%s: %s=%s", __func__, ext->key, ext->val); |
| 1637 |
sshbuf_reset(b); |
| 1638 |
if ((r = sshbuf_put_cstring(c, ext->key)) != 0 || |
| 1639 |
(r = sshbuf_put_cstring(b, ext->val)) != 0 || |
| 1640 |
(r = sshbuf_put_stringb(c, b)) != 0) |
| 1641 |
fatal("%s: buffer: %s", __func__, ssh_err(r)); |
| 1650 |
} |
1642 |
} |
| 1651 |
} |
1643 |
} |
|
|
1644 |
sshbuf_free(b); |
| 1645 |
} |
| 1646 |
|
| 1647 |
static void |
| 1648 |
finalise_cert_exts(void) |
| 1649 |
{ |
| 1650 |
if (certflags_command != NULL) |
| 1651 |
cert_ext_add("force-command", certflags_command, 1); |
| 1652 |
if ((certflags_flags & CERTOPT_X_FWD) != 0) |
| 1653 |
cert_ext_add("permit-X11-forwarding", NULL, 0); |
| 1654 |
if ((certflags_flags & CERTOPT_AGENT_FWD) != 0) |
| 1655 |
cert_ext_add("permit-agent-forwarding", NULL, 0); |
| 1656 |
if ((certflags_flags & CERTOPT_PORT_FWD) != 0) |
| 1657 |
cert_ext_add("permit-port-forwarding", NULL, 0); |
| 1658 |
if ((certflags_flags & CERTOPT_PTY) != 0) |
| 1659 |
cert_ext_add("permit-pty", NULL, 0); |
| 1660 |
if ((certflags_flags & CERTOPT_USER_RC) != 0) |
| 1661 |
cert_ext_add("permit-user-rc", NULL, 0); |
| 1662 |
if ((certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0) |
| 1663 |
cert_ext_add("no-touch-required", NULL, 0); |
| 1664 |
if (certflags_src_addr != NULL) |
| 1665 |
cert_ext_add("source-address", certflags_src_addr, 0); |
| 1666 |
if (ncert_ext > 0) |
| 1667 |
qsort(cert_ext, ncert_ext, sizeof(*cert_ext), cert_ext_cmp); |
| 1652 |
} |
1668 |
} |
| 1653 |
|
1669 |
|
| 1654 |
static struct sshkey * |
1670 |
static struct sshkey * |
|
Lines 1765-1770
do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
Link Here
|
| 1765 |
} |
1781 |
} |
| 1766 |
ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT); |
1782 |
ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT); |
| 1767 |
|
1783 |
|
|
|
1784 |
finalise_cert_exts(); |
| 1768 |
for (i = 0; i < argc; i++) { |
1785 |
for (i = 0; i < argc; i++) { |
| 1769 |
/* Split list of principals */ |
1786 |
/* Split list of principals */ |
| 1770 |
n = 0; |
1787 |
n = 0; |
|
Lines 1981-1993
add_cert_option(char *opt)
Link Here
|
| 1981 |
val = xstrdup(strchr(opt, ':') + 1); |
1998 |
val = xstrdup(strchr(opt, ':') + 1); |
| 1982 |
if ((cp = strchr(val, '=')) != NULL) |
1999 |
if ((cp = strchr(val, '=')) != NULL) |
| 1983 |
*cp++ = '\0'; |
2000 |
*cp++ = '\0'; |
| 1984 |
cert_userext = xreallocarray(cert_userext, ncert_userext + 1, |
2001 |
cert_ext_add(val, cp, iscrit); |
| 1985 |
sizeof(*cert_userext)); |
2002 |
free(val); |
| 1986 |
cert_userext[ncert_userext].key = val; |
|
|
| 1987 |
cert_userext[ncert_userext].val = cp == NULL ? |
| 1988 |
NULL : xstrdup(cp); |
| 1989 |
cert_userext[ncert_userext].crit = iscrit; |
| 1990 |
ncert_userext++; |
| 1991 |
} else |
2003 |
} else |
| 1992 |
fatal("Unsupported certificate option \"%s\"", opt); |
2004 |
fatal("Unsupported certificate option \"%s\"", opt); |
| 1993 |
} |
2005 |
} |
|
Lines 1995-2001
add_cert_option(char *opt)
Link Here
|
| 1995 |
static void |
2007 |
static void |
| 1996 |
show_options(struct sshbuf *optbuf, int in_critical) |
2008 |
show_options(struct sshbuf *optbuf, int in_critical) |
| 1997 |
{ |
2009 |
{ |
| 1998 |
char *name, *arg; |
2010 |
char *name, *arg, *hex; |
| 1999 |
struct sshbuf *options, *option = NULL; |
2011 |
struct sshbuf *options, *option = NULL; |
| 2000 |
int r; |
2012 |
int r; |
| 2001 |
|
2013 |
|
|
Lines 2024-2034
show_options(struct sshbuf *optbuf, int in_critical)
Link Here
|
| 2024 |
__func__, ssh_err(r)); |
2036 |
__func__, ssh_err(r)); |
| 2025 |
printf(" %s\n", arg); |
2037 |
printf(" %s\n", arg); |
| 2026 |
free(arg); |
2038 |
free(arg); |
| 2027 |
} else { |
2039 |
} else if (sshbuf_len(option) > 0) { |
| 2028 |
printf(" UNKNOWN OPTION (len %zu)\n", |
2040 |
hex = sshbuf_dtob16(option); |
| 2029 |
sshbuf_len(option)); |
2041 |
printf(" UNKNOWN OPTION: %s (len %zu)\n", |
|
|
2042 |
hex, sshbuf_len(option)); |
| 2030 |
sshbuf_reset(option); |
2043 |
sshbuf_reset(option); |
| 2031 |
} |
2044 |
free(hex); |
|
|
2045 |
} else |
| 2046 |
printf(" UNKNOWN FLAG OPTION\n"); |
| 2032 |
free(name); |
2047 |
free(name); |
| 2033 |
if (sshbuf_len(option) != 0) |
2048 |
if (sshbuf_len(option) != 0) |
| 2034 |
fatal("Option corrupt: extra data at end"); |
2049 |
fatal("Option corrupt: extra data at end"); |