summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c306
1 files changed, 198 insertions, 108 deletions
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
1454static int 1457static int
1455ssh_keysign(Key *key, u_char **sigp, u_int *lenp, 1458ssh_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,
1531int 1572int
1532userauth_hostbased(Authctxt *authctxt) 1573userauth_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 */