diff options
-rw-r--r-- | readconf.c | 25 | ||||
-rw-r--r-- | readconf.h | 4 | ||||
-rw-r--r-- | scp.1 | 5 | ||||
-rw-r--r-- | sftp.1 | 5 | ||||
-rw-r--r-- | ssh.1 | 5 | ||||
-rw-r--r-- | ssh_config.5 | 15 | ||||
-rw-r--r-- | sshconnect2.c | 306 |
7 files changed, 245 insertions, 120 deletions
diff --git a/readconf.c b/readconf.c index 401f3430d..dd78da530 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.229 2015/01/26 03:04:45 djm Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.230 2015/01/30 11:43:14 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 |
@@ -156,7 +156,7 @@ typedef enum { | |||
156 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, | 156 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, |
157 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, | 157 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, |
158 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, | 158 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, |
159 | oFingerprintHash, oUpdateHostkeys, | 159 | oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, |
160 | oIgnoredUnknownOption, oDeprecated, oUnsupported | 160 | oIgnoredUnknownOption, oDeprecated, oUnsupported |
161 | } OpCodes; | 161 | } OpCodes; |
162 | 162 | ||
@@ -274,6 +274,7 @@ static struct { | |||
274 | { "revokedhostkeys", oRevokedHostKeys }, | 274 | { "revokedhostkeys", oRevokedHostKeys }, |
275 | { "fingerprinthash", oFingerprintHash }, | 275 | { "fingerprinthash", oFingerprintHash }, |
276 | { "updatehostkeys", oUpdateHostkeys }, | 276 | { "updatehostkeys", oUpdateHostkeys }, |
277 | { "hostbasedkeytypes", oHostbasedKeyTypes }, | ||
277 | { "ignoreunknown", oIgnoreUnknown }, | 278 | { "ignoreunknown", oIgnoreUnknown }, |
278 | 279 | ||
279 | { NULL, oBadOption } | 280 | { NULL, oBadOption } |
@@ -1481,6 +1482,19 @@ parse_int: | |||
1481 | intptr = &options->update_hostkeys; | 1482 | intptr = &options->update_hostkeys; |
1482 | goto parse_flag; | 1483 | goto parse_flag; |
1483 | 1484 | ||
1485 | case oHostbasedKeyTypes: | ||
1486 | charptr = &options->hostbased_key_types; | ||
1487 | arg = strdelim(&s); | ||
1488 | if (!arg || *arg == '\0') | ||
1489 | fatal("%.200s line %d: Missing argument.", | ||
1490 | filename, linenum); | ||
1491 | if (!sshkey_names_valid2(arg, 1)) | ||
1492 | fatal("%s line %d: Bad key types '%s'.", | ||
1493 | filename, linenum, arg ? arg : "<NONE>"); | ||
1494 | if (*activep && *charptr == NULL) | ||
1495 | *charptr = xstrdup(arg); | ||
1496 | break; | ||
1497 | |||
1484 | case oDeprecated: | 1498 | case oDeprecated: |
1485 | debug("%s line %d: Deprecated option \"%s\"", | 1499 | debug("%s line %d: Deprecated option \"%s\"", |
1486 | filename, linenum, keyword); | 1500 | filename, linenum, keyword); |
@@ -1660,6 +1674,7 @@ initialize_options(Options * options) | |||
1660 | options->revoked_host_keys = NULL; | 1674 | options->revoked_host_keys = NULL; |
1661 | options->fingerprint_hash = -1; | 1675 | options->fingerprint_hash = -1; |
1662 | options->update_hostkeys = -1; | 1676 | options->update_hostkeys = -1; |
1677 | options->hostbased_key_types = NULL; | ||
1663 | } | 1678 | } |
1664 | 1679 | ||
1665 | /* | 1680 | /* |
@@ -1841,6 +1856,8 @@ fill_default_options(Options * options) | |||
1841 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; | 1856 | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; |
1842 | if (options->update_hostkeys == -1) | 1857 | if (options->update_hostkeys == -1) |
1843 | options->update_hostkeys = 1; | 1858 | options->update_hostkeys = 1; |
1859 | if (options->hostbased_key_types == NULL) | ||
1860 | options->hostbased_key_types = xstrdup("*"); | ||
1844 | 1861 | ||
1845 | #define CLEAR_ON_NONE(v) \ | 1862 | #define CLEAR_ON_NONE(v) \ |
1846 | do { \ | 1863 | do { \ |
@@ -2281,6 +2298,7 @@ dump_client_config(Options *o, const char *host) | |||
2281 | dump_cfg_string(oControlPath, o->control_path); | 2298 | dump_cfg_string(oControlPath, o->control_path); |
2282 | dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); | 2299 | dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); |
2283 | dump_cfg_string(oHostKeyAlias, o->host_key_alias); | 2300 | dump_cfg_string(oHostKeyAlias, o->host_key_alias); |
2301 | dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); | ||
2284 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); | 2302 | dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); |
2285 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); | 2303 | dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); |
2286 | dump_cfg_string(oLocalCommand, o->local_command); | 2304 | dump_cfg_string(oLocalCommand, o->local_command); |
@@ -2289,9 +2307,10 @@ dump_client_config(Options *o, const char *host) | |||
2289 | dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); | 2307 | dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); |
2290 | dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); | 2308 | dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); |
2291 | dump_cfg_string(oProxyCommand, o->proxy_command); | 2309 | dump_cfg_string(oProxyCommand, o->proxy_command); |
2292 | dump_cfg_string(oXAuthLocation, o->xauth_location); | ||
2293 | dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); | 2310 | dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); |
2311 | dump_cfg_string(oXAuthLocation, o->xauth_location); | ||
2294 | 2312 | ||
2313 | /* Forwards */ | ||
2295 | dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); | 2314 | dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); |
2296 | dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); | 2315 | dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); |
2297 | dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); | 2316 | dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); |
diff --git a/readconf.h b/readconf.h index 7a8ae17c0..701b9c696 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.107 2015/01/26 03:04:45 djm Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.108 2015/01/30 11:43:14 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -150,6 +150,8 @@ typedef struct { | |||
150 | 150 | ||
151 | int update_hostkeys; | 151 | int update_hostkeys; |
152 | 152 | ||
153 | char *hostbased_key_types; | ||
154 | |||
153 | char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ | 155 | char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ |
154 | } Options; | 156 | } Options; |
155 | 157 | ||
@@ -8,9 +8,9 @@ | |||
8 | .\" | 8 | .\" |
9 | .\" Created: Sun May 7 00:14:37 1995 ylo | 9 | .\" Created: Sun May 7 00:14:37 1995 ylo |
10 | .\" | 10 | .\" |
11 | .\" $OpenBSD: scp.1,v 1.65 2015/01/26 13:55:29 jmc Exp $ | 11 | .\" $OpenBSD: scp.1,v 1.66 2015/01/30 11:43:14 djm Exp $ |
12 | .\" | 12 | .\" |
13 | .Dd $Mdocdate: January 26 2015 $ | 13 | .Dd $Mdocdate: January 30 2015 $ |
14 | .Dt SCP 1 | 14 | .Dt SCP 1 |
15 | .Os | 15 | .Os |
16 | .Sh NAME | 16 | .Sh NAME |
@@ -150,6 +150,7 @@ For full details of the options listed below, and their possible values, see | |||
150 | .It HashKnownHosts | 150 | .It HashKnownHosts |
151 | .It Host | 151 | .It Host |
152 | .It HostbasedAuthentication | 152 | .It HostbasedAuthentication |
153 | .It HostbasedKeyTypes | ||
153 | .It HostKeyAlgorithms | 154 | .It HostKeyAlgorithms |
154 | .It HostKeyAlias | 155 | .It HostKeyAlias |
155 | .It HostName | 156 | .It HostName |
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: sftp.1,v 1.100 2015/01/26 12:16:36 djm Exp $ | 1 | .\" $OpenBSD: sftp.1,v 1.101 2015/01/30 11:43:14 djm Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright (c) 2001 Damien Miller. All rights reserved. | 3 | .\" Copyright (c) 2001 Damien Miller. All rights reserved. |
4 | .\" | 4 | .\" |
@@ -22,7 +22,7 @@ | |||
22 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 22 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
23 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | .\" | 24 | .\" |
25 | .Dd $Mdocdate: January 26 2015 $ | 25 | .Dd $Mdocdate: January 30 2015 $ |
26 | .Dt SFTP 1 | 26 | .Dt SFTP 1 |
27 | .Os | 27 | .Os |
28 | .Sh NAME | 28 | .Sh NAME |
@@ -215,6 +215,7 @@ For full details of the options listed below, and their possible values, see | |||
215 | .It HashKnownHosts | 215 | .It HashKnownHosts |
216 | .It Host | 216 | .It Host |
217 | .It HostbasedAuthentication | 217 | .It HostbasedAuthentication |
218 | .It HostbasedKeyTypes | ||
218 | .It HostKeyAlgorithms | 219 | .It HostKeyAlgorithms |
219 | .It HostKeyAlias | 220 | .It HostKeyAlias |
220 | .It HostName | 221 | .It HostName |
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: ssh.1,v 1.354 2015/01/26 12:16:36 djm Exp $ | 36 | .\" $OpenBSD: ssh.1,v 1.355 2015/01/30 11:43:14 djm Exp $ |
37 | .Dd $Mdocdate: January 26 2015 $ | 37 | .Dd $Mdocdate: January 30 2015 $ |
38 | .Dt SSH 1 | 38 | .Dt SSH 1 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -445,6 +445,7 @@ For full details of the options listed below, and their possible values, see | |||
445 | .It HashKnownHosts | 445 | .It HashKnownHosts |
446 | .It Host | 446 | .It Host |
447 | .It HostbasedAuthentication | 447 | .It HostbasedAuthentication |
448 | .It HostbasedKeyTypes | ||
448 | .It HostKeyAlgorithms | 449 | .It HostKeyAlgorithms |
449 | .It HostKeyAlias | 450 | .It HostKeyAlias |
450 | .It HostName | 451 | .It HostName |
diff --git a/ssh_config.5 b/ssh_config.5 index 9c0b35795..95b7bf6e4 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: ssh_config.5,v 1.201 2015/01/26 12:16:36 djm Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.202 2015/01/30 11:43:14 djm Exp $ |
37 | .Dd $Mdocdate: January 26 2015 $ | 37 | .Dd $Mdocdate: January 30 2015 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -777,6 +777,17 @@ The default is | |||
777 | This option applies to protocol version 2 only and | 777 | This option applies to protocol version 2 only and |
778 | is similar to | 778 | is similar to |
779 | .Cm RhostsRSAAuthentication . | 779 | .Cm RhostsRSAAuthentication . |
780 | .It Cm HostbasedKeyTypes | ||
781 | Specifies the key types that will be used for hostbased authentication | ||
782 | as a comma-separated pattern list. | ||
783 | The default | ||
784 | .Dq * | ||
785 | will allow all key types. | ||
786 | The | ||
787 | .Fl Q | ||
788 | option of | ||
789 | .Xr ssh 1 | ||
790 | may be used to list supported key types. | ||
780 | .It Cm HostKeyAlgorithms | 791 | .It Cm HostKeyAlgorithms |
781 | Specifies the protocol version 2 host key algorithms | 792 | Specifies the protocol version 2 host key algorithms |
782 | that the client wants to use in order of preference. | 793 | that the client wants to use in order of preference. |
diff --git a/sshconnect2.c b/sshconnect2.c index 48882e3a5..804194aab 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.222 2015/01/28 22:36:00 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.223 2015/01/30 11:43:14 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -273,6 +273,8 @@ struct cauthctxt { | |||
273 | int agent_fd; | 273 | int agent_fd; |
274 | /* hostbased */ | 274 | /* hostbased */ |
275 | Sensitive *sensitive; | 275 | Sensitive *sensitive; |
276 | char *oktypes, *ktypes; | ||
277 | const char *active_ktype; | ||
276 | /* kbd-interactive */ | 278 | /* kbd-interactive */ |
277 | int info_req_seen; | 279 | int info_req_seen; |
278 | /* generic */ | 280 | /* generic */ |
@@ -401,6 +403,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, | |||
401 | authctxt.authlist = NULL; | 403 | authctxt.authlist = NULL; |
402 | authctxt.methoddata = NULL; | 404 | authctxt.methoddata = NULL; |
403 | authctxt.sensitive = sensitive; | 405 | authctxt.sensitive = sensitive; |
406 | authctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL; | ||
404 | authctxt.info_req_seen = 0; | 407 | authctxt.info_req_seen = 0; |
405 | authctxt.agent_fd = -1; | 408 | authctxt.agent_fd = -1; |
406 | if (authctxt.method == NULL) | 409 | if (authctxt.method == NULL) |
@@ -1452,78 +1455,116 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt) | |||
1452 | } | 1455 | } |
1453 | 1456 | ||
1454 | static int | 1457 | static int |
1455 | ssh_keysign(Key *key, u_char **sigp, u_int *lenp, | 1458 | ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, |
1456 | u_char *data, u_int datalen) | 1459 | const u_char *data, size_t datalen) |
1457 | { | 1460 | { |
1458 | Buffer b; | 1461 | struct sshbuf *b; |
1459 | struct stat st; | 1462 | struct stat st; |
1460 | pid_t pid; | 1463 | pid_t pid; |
1461 | int to[2], from[2], status, version = 2; | 1464 | int i, r, to[2], from[2], status, sock = packet_get_connection_in(); |
1465 | u_char rversion = 0, version = 2; | ||
1466 | void (*osigchld)(int); | ||
1462 | 1467 | ||
1463 | debug2("ssh_keysign called"); | 1468 | *sigp = NULL; |
1469 | *lenp = 0; | ||
1464 | 1470 | ||
1465 | if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { | 1471 | if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { |
1466 | error("ssh_keysign: not installed: %s", strerror(errno)); | 1472 | error("%s: not installed: %s", __func__, strerror(errno)); |
1473 | return -1; | ||
1474 | } | ||
1475 | if (fflush(stdout) != 0) { | ||
1476 | error("%s: fflush: %s", __func__, strerror(errno)); | ||
1467 | return -1; | 1477 | return -1; |
1468 | } | 1478 | } |
1469 | if (fflush(stdout) != 0) | ||
1470 | error("ssh_keysign: fflush: %s", strerror(errno)); | ||
1471 | if (pipe(to) < 0) { | 1479 | if (pipe(to) < 0) { |
1472 | error("ssh_keysign: pipe: %s", strerror(errno)); | 1480 | error("%s: pipe: %s", __func__, strerror(errno)); |
1473 | return -1; | 1481 | return -1; |
1474 | } | 1482 | } |
1475 | if (pipe(from) < 0) { | 1483 | if (pipe(from) < 0) { |
1476 | error("ssh_keysign: pipe: %s", strerror(errno)); | 1484 | error("%s: pipe: %s", __func__, strerror(errno)); |
1477 | return -1; | 1485 | return -1; |
1478 | } | 1486 | } |
1479 | if ((pid = fork()) < 0) { | 1487 | if ((pid = fork()) < 0) { |
1480 | error("ssh_keysign: fork: %s", strerror(errno)); | 1488 | error("%s: fork: %s", __func__, strerror(errno)); |
1481 | return -1; | 1489 | return -1; |
1482 | } | 1490 | } |
1491 | osigchld = signal(SIGCHLD, SIG_DFL); | ||
1483 | if (pid == 0) { | 1492 | if (pid == 0) { |
1484 | /* keep the socket on exec */ | 1493 | /* keep the socket on exec */ |
1485 | fcntl(packet_get_connection_in(), F_SETFD, 0); | 1494 | fcntl(sock, F_SETFD, 0); |
1486 | permanently_drop_suid(getuid()); | 1495 | permanently_drop_suid(getuid()); |
1487 | close(from[0]); | 1496 | close(from[0]); |
1488 | if (dup2(from[1], STDOUT_FILENO) < 0) | 1497 | if (dup2(from[1], STDOUT_FILENO) < 0) |
1489 | fatal("ssh_keysign: dup2: %s", strerror(errno)); | 1498 | fatal("%s: dup2: %s", __func__, strerror(errno)); |
1490 | close(to[1]); | 1499 | close(to[1]); |
1491 | if (dup2(to[0], STDIN_FILENO) < 0) | 1500 | if (dup2(to[0], STDIN_FILENO) < 0) |
1492 | fatal("ssh_keysign: dup2: %s", strerror(errno)); | 1501 | fatal("%s: dup2: %s", __func__, strerror(errno)); |
1493 | close(from[1]); | 1502 | close(from[1]); |
1494 | close(to[0]); | 1503 | close(to[0]); |
1504 | /* Close everything but stdio and the socket */ | ||
1505 | for (i = STDERR_FILENO + 1; i < sock; i++) | ||
1506 | close(i); | ||
1507 | closefrom(sock + 1); | ||
1508 | debug3("%s: [child] pid=%ld, exec %s", | ||
1509 | __func__, (long)getpid(), _PATH_SSH_KEY_SIGN); | ||
1495 | execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); | 1510 | execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); |
1496 | fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, | 1511 | fatal("%s: exec(%s): %s", __func__, _PATH_SSH_KEY_SIGN, |
1497 | strerror(errno)); | 1512 | strerror(errno)); |
1498 | } | 1513 | } |
1499 | close(from[1]); | 1514 | close(from[1]); |
1500 | close(to[0]); | 1515 | close(to[0]); |
1501 | 1516 | ||
1502 | buffer_init(&b); | 1517 | if ((b = sshbuf_new()) == NULL) |
1503 | buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */ | 1518 | fatal("%s: sshbuf_new failed", __func__); |
1504 | buffer_put_string(&b, data, datalen); | 1519 | /* send # of sock, data to be signed */ |
1505 | if (ssh_msg_send(to[1], version, &b) == -1) | 1520 | if ((r = sshbuf_put_u32(b, sock) != 0) || |
1506 | fatal("ssh_keysign: couldn't send request"); | 1521 | (r = sshbuf_put_string(b, data, datalen)) != 0) |
1507 | 1522 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | |
1508 | if (ssh_msg_recv(from[0], &b) < 0) { | 1523 | if (ssh_msg_send(to[1], version, b) == -1) |
1509 | error("ssh_keysign: no reply"); | 1524 | fatal("%s: couldn't send request", __func__); |
1510 | buffer_free(&b); | 1525 | sshbuf_reset(b); |
1511 | return -1; | 1526 | r = ssh_msg_recv(from[0], b); |
1512 | } | ||
1513 | close(from[0]); | 1527 | close(from[0]); |
1514 | close(to[1]); | 1528 | close(to[1]); |
1529 | if (r < 0) { | ||
1530 | error("%s: no reply", __func__); | ||
1531 | goto fail; | ||
1532 | } | ||
1515 | 1533 | ||
1516 | while (waitpid(pid, &status, 0) < 0) | 1534 | errno = 0; |
1517 | if (errno != EINTR) | 1535 | while (waitpid(pid, &status, 0) < 0) { |
1518 | break; | 1536 | if (errno != EINTR) { |
1519 | 1537 | error("%s: waitpid %ld: %s", | |
1520 | if (buffer_get_char(&b) != version) { | 1538 | __func__, (long)pid, strerror(errno)); |
1521 | error("ssh_keysign: bad version"); | 1539 | goto fail; |
1522 | buffer_free(&b); | 1540 | } |
1541 | } | ||
1542 | if (!WIFEXITED(status)) { | ||
1543 | error("%s: exited abnormally", __func__); | ||
1544 | goto fail; | ||
1545 | } | ||
1546 | if (WEXITSTATUS(status) != 0) { | ||
1547 | error("%s: exited with status %d", | ||
1548 | __func__, WEXITSTATUS(status)); | ||
1549 | goto fail; | ||
1550 | } | ||
1551 | if ((r = sshbuf_get_u8(b, &rversion)) != 0) { | ||
1552 | error("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1553 | goto fail; | ||
1554 | } | ||
1555 | if (rversion != version) { | ||
1556 | error("%s: bad version", __func__); | ||
1557 | goto fail; | ||
1558 | } | ||
1559 | if ((r = sshbuf_get_string(b, sigp, lenp)) != 0) { | ||
1560 | error("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1561 | fail: | ||
1562 | signal(SIGCHLD, osigchld); | ||
1563 | sshbuf_free(b); | ||
1523 | return -1; | 1564 | return -1; |
1524 | } | 1565 | } |
1525 | *sigp = buffer_get_string(&b, lenp); | 1566 | signal(SIGCHLD, osigchld); |
1526 | buffer_free(&b); | 1567 | sshbuf_free(b); |
1527 | 1568 | ||
1528 | return 0; | 1569 | return 0; |
1529 | } | 1570 | } |
@@ -1531,100 +1572,149 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, | |||
1531 | int | 1572 | int |
1532 | userauth_hostbased(Authctxt *authctxt) | 1573 | userauth_hostbased(Authctxt *authctxt) |
1533 | { | 1574 | { |
1534 | Key *private = NULL; | 1575 | struct ssh *ssh = active_state; |
1535 | Sensitive *sensitive = authctxt->sensitive; | 1576 | struct sshkey *private = NULL; |
1536 | Buffer b; | 1577 | struct sshbuf *b = NULL; |
1537 | u_char *signature, *blob; | ||
1538 | char *chost, *pkalg, *p; | ||
1539 | const char *service; | 1578 | const char *service; |
1540 | u_int blen, slen; | 1579 | u_char *sig = NULL, *keyblob = NULL; |
1541 | int ok, i, found = 0; | 1580 | char *fp = NULL, *chost = NULL, *lname = NULL; |
1542 | 1581 | size_t siglen = 0, keylen = 0; | |
1543 | /* XXX provide some way to allow user to specify key types attempted */ | 1582 | int i, r, success = 0; |
1583 | |||
1584 | if (authctxt->ktypes == NULL) { | ||
1585 | authctxt->oktypes = xstrdup(options.hostbased_key_types); | ||
1586 | authctxt->ktypes = authctxt->oktypes; | ||
1587 | } | ||
1544 | 1588 | ||
1545 | /* check for a useful key */ | 1589 | /* |
1546 | for (i = 0; i < sensitive->nkeys; i++) { | 1590 | * Work through each listed type pattern in HostbasedKeyTypes, |
1547 | private = sensitive->keys[i]; | 1591 | * trying each hostkey that matches the type in turn. |
1548 | if (private && private->type != KEY_RSA1) { | 1592 | */ |
1549 | found = 1; | 1593 | for (;;) { |
1594 | if (authctxt->active_ktype == NULL) | ||
1595 | authctxt->active_ktype = strsep(&authctxt->ktypes, ","); | ||
1596 | if (authctxt->active_ktype == NULL || | ||
1597 | *authctxt->active_ktype == '\0') | ||
1598 | break; | ||
1599 | debug3("%s: trying key type %s", __func__, | ||
1600 | authctxt->active_ktype); | ||
1601 | |||
1602 | /* check for a useful key */ | ||
1603 | private = NULL; | ||
1604 | for (i = 0; i < authctxt->sensitive->nkeys; i++) { | ||
1605 | if (authctxt->sensitive->keys[i] == NULL || | ||
1606 | authctxt->sensitive->keys[i]->type == KEY_RSA1 || | ||
1607 | authctxt->sensitive->keys[i]->type == KEY_UNSPEC) | ||
1608 | continue; | ||
1609 | if (match_pattern_list( | ||
1610 | sshkey_ssh_name(authctxt->sensitive->keys[i]), | ||
1611 | authctxt->active_ktype, | ||
1612 | strlen(authctxt->active_ktype), 0) != 1) | ||
1613 | continue; | ||
1550 | /* we take and free the key */ | 1614 | /* we take and free the key */ |
1551 | sensitive->keys[i] = NULL; | 1615 | private = authctxt->sensitive->keys[i]; |
1616 | authctxt->sensitive->keys[i] = NULL; | ||
1552 | break; | 1617 | break; |
1553 | } | 1618 | } |
1619 | /* Found one */ | ||
1620 | if (private != NULL) | ||
1621 | break; | ||
1622 | /* No more keys of this type; advance */ | ||
1623 | authctxt->active_ktype = NULL; | ||
1554 | } | 1624 | } |
1555 | if (!found) { | 1625 | if (private == NULL) { |
1626 | free(authctxt->oktypes); | ||
1627 | authctxt->oktypes = authctxt->ktypes = NULL; | ||
1628 | authctxt->active_ktype = NULL; | ||
1556 | debug("No more client hostkeys for hostbased authentication."); | 1629 | debug("No more client hostkeys for hostbased authentication."); |
1557 | return 0; | 1630 | goto out; |
1558 | } | 1631 | } |
1559 | 1632 | ||
1560 | debug("%s: trying hostkey type %s", __func__, key_type(private)); | 1633 | if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, |
1561 | 1634 | SSH_FP_DEFAULT)) == NULL) { | |
1562 | if (key_to_blob(private, &blob, &blen) == 0) { | 1635 | error("%s: sshkey_fingerprint failed", __func__); |
1563 | key_free(private); | 1636 | goto out; |
1564 | return 0; | ||
1565 | } | 1637 | } |
1638 | debug("%s: trying hostkey %s %s", | ||
1639 | __func__, sshkey_ssh_name(private), fp); | ||
1566 | 1640 | ||
1567 | /* figure out a name for the client host */ | 1641 | /* figure out a name for the client host */ |
1568 | p = get_local_name(packet_get_connection_in()); | 1642 | if ((lname = get_local_name(packet_get_connection_in())) == NULL) { |
1569 | if (p == NULL) { | 1643 | error("%s: cannot get local ipaddr/name", __func__); |
1570 | error("userauth_hostbased: cannot get local ipaddr/name"); | 1644 | goto out; |
1571 | key_free(private); | ||
1572 | free(blob); | ||
1573 | return 0; | ||
1574 | } | 1645 | } |
1575 | xasprintf(&chost, "%s.", p); | 1646 | |
1576 | debug2("userauth_hostbased: chost %s", chost); | 1647 | /* XXX sshbuf_put_stringf? */ |
1577 | free(p); | 1648 | xasprintf(&chost, "%s.", lname); |
1649 | debug2("%s: chost %s", __func__, chost); | ||
1578 | 1650 | ||
1579 | service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : | 1651 | service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : |
1580 | authctxt->service; | 1652 | authctxt->service; |
1581 | pkalg = xstrdup(key_ssh_name(private)); | 1653 | |
1582 | buffer_init(&b); | ||
1583 | /* construct data */ | 1654 | /* construct data */ |
1584 | buffer_put_string(&b, session_id2, session_id2_len); | 1655 | if ((b = sshbuf_new()) == NULL) { |
1585 | buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); | 1656 | error("%s: sshbuf_new failed", __func__); |
1586 | buffer_put_cstring(&b, authctxt->server_user); | 1657 | goto out; |
1587 | buffer_put_cstring(&b, service); | 1658 | } |
1588 | buffer_put_cstring(&b, authctxt->method->name); | 1659 | if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) { |
1589 | buffer_put_cstring(&b, pkalg); | 1660 | error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); |
1590 | buffer_put_string(&b, blob, blen); | 1661 | goto out; |
1591 | buffer_put_cstring(&b, chost); | 1662 | } |
1592 | buffer_put_cstring(&b, authctxt->local_user); | 1663 | if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || |
1664 | (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || | ||
1665 | (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || | ||
1666 | (r = sshbuf_put_cstring(b, service)) != 0 || | ||
1667 | (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 || | ||
1668 | (r = sshbuf_put_cstring(b, key_ssh_name(private))) != 0 || | ||
1669 | (r = sshbuf_put_string(b, keyblob, keylen)) != 0 || | ||
1670 | (r = sshbuf_put_cstring(b, chost)) != 0 || | ||
1671 | (r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) { | ||
1672 | error("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1673 | goto out; | ||
1674 | } | ||
1675 | |||
1593 | #ifdef DEBUG_PK | 1676 | #ifdef DEBUG_PK |
1594 | buffer_dump(&b); | 1677 | sshbuf_dump(b, stderr); |
1595 | #endif | 1678 | #endif |
1596 | if (sensitive->external_keysign) | 1679 | if (authctxt->sensitive->external_keysign) |
1597 | ok = ssh_keysign(private, &signature, &slen, | 1680 | r = ssh_keysign(private, &sig, &siglen, |
1598 | buffer_ptr(&b), buffer_len(&b)); | 1681 | sshbuf_ptr(b), sshbuf_len(b)); |
1599 | else | 1682 | else if ((r = sshkey_sign(private, &sig, &siglen, |
1600 | ok = key_sign(private, &signature, &slen, | 1683 | sshbuf_ptr(b), sshbuf_len(b), datafellows)) != 0) |
1601 | buffer_ptr(&b), buffer_len(&b)); | 1684 | debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); |
1602 | key_free(private); | 1685 | if (r != 0) { |
1603 | buffer_free(&b); | 1686 | error("sign using hostkey %s %s failed", |
1604 | if (ok != 0) { | 1687 | sshkey_ssh_name(private), fp); |
1605 | error("key_sign failed"); | 1688 | goto out; |
1606 | free(chost); | ||
1607 | free(pkalg); | ||
1608 | free(blob); | ||
1609 | return 0; | ||
1610 | } | 1689 | } |
1611 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 1690 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1612 | packet_put_cstring(authctxt->server_user); | 1691 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
1613 | packet_put_cstring(authctxt->service); | 1692 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
1614 | packet_put_cstring(authctxt->method->name); | 1693 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
1615 | packet_put_cstring(pkalg); | 1694 | (r = sshpkt_put_cstring(ssh, key_ssh_name(private))) != 0 || |
1616 | packet_put_string(blob, blen); | 1695 | (r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 || |
1617 | packet_put_cstring(chost); | 1696 | (r = sshpkt_put_cstring(ssh, chost)) != 0 || |
1618 | packet_put_cstring(authctxt->local_user); | 1697 | (r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 || |
1619 | packet_put_string(signature, slen); | 1698 | (r = sshpkt_put_string(ssh, sig, siglen)) != 0 || |
1620 | explicit_bzero(signature, slen); | 1699 | (r = sshpkt_send(ssh)) != 0) { |
1621 | free(signature); | 1700 | error("%s: packet error: %s", __func__, ssh_err(r)); |
1701 | goto out; | ||
1702 | } | ||
1703 | success = 1; | ||
1704 | |||
1705 | out: | ||
1706 | if (sig != NULL) { | ||
1707 | explicit_bzero(sig, siglen); | ||
1708 | free(sig); | ||
1709 | } | ||
1710 | free(keyblob); | ||
1711 | free(lname); | ||
1712 | free(fp); | ||
1622 | free(chost); | 1713 | free(chost); |
1623 | free(pkalg); | 1714 | sshkey_free(private); |
1624 | free(blob); | 1715 | sshbuf_free(b); |
1625 | 1716 | ||
1626 | packet_send(); | 1717 | return success; |
1627 | return 1; | ||
1628 | } | 1718 | } |
1629 | 1719 | ||
1630 | /* find auth method */ | 1720 | /* find auth method */ |