diff options
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/sshconnect.c b/sshconnect.c index 0ec1e54e9..07dfc9da1 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.263 2015/08/20 22:32:42 deraadt Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.271 2016/01/14 22:56:56 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 |
@@ -59,12 +59,12 @@ | |||
59 | #include "readconf.h" | 59 | #include "readconf.h" |
60 | #include "atomicio.h" | 60 | #include "atomicio.h" |
61 | #include "dns.h" | 61 | #include "dns.h" |
62 | #include "roaming.h" | ||
63 | #include "monitor_fdpass.h" | 62 | #include "monitor_fdpass.h" |
64 | #include "ssh2.h" | 63 | #include "ssh2.h" |
65 | #include "version.h" | 64 | #include "version.h" |
66 | #include "authfile.h" | 65 | #include "authfile.h" |
67 | #include "ssherr.h" | 66 | #include "ssherr.h" |
67 | #include "authfd.h" | ||
68 | 68 | ||
69 | char *client_version_string = NULL; | 69 | char *client_version_string = NULL; |
70 | char *server_version_string = NULL; | 70 | char *server_version_string = NULL; |
@@ -167,6 +167,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, | |||
167 | 167 | ||
168 | if ((sock = mm_receive_fd(sp[1])) == -1) | 168 | if ((sock = mm_receive_fd(sp[1])) == -1) |
169 | fatal("proxy dialer did not pass back a connection"); | 169 | fatal("proxy dialer did not pass back a connection"); |
170 | close(sp[1]); | ||
170 | 171 | ||
171 | while (waitpid(pid, NULL, 0) == -1) | 172 | while (waitpid(pid, NULL, 0) == -1) |
172 | if (errno != EINTR) | 173 | if (errno != EINTR) |
@@ -432,7 +433,9 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, | |||
432 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 433 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
433 | struct addrinfo *ai; | 434 | struct addrinfo *ai; |
434 | 435 | ||
435 | debug2("ssh_connect: needpriv %d", needpriv); | 436 | debug2("%s: needpriv %d", __func__, needpriv); |
437 | memset(ntop, 0, sizeof(ntop)); | ||
438 | memset(strport, 0, sizeof(strport)); | ||
436 | 439 | ||
437 | for (attempt = 0; attempt < connection_attempts; attempt++) { | 440 | for (attempt = 0; attempt < connection_attempts; attempt++) { |
438 | if (attempt > 0) { | 441 | if (attempt > 0) { |
@@ -451,7 +454,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, | |||
451 | if (getnameinfo(ai->ai_addr, ai->ai_addrlen, | 454 | if (getnameinfo(ai->ai_addr, ai->ai_addrlen, |
452 | ntop, sizeof(ntop), strport, sizeof(strport), | 455 | ntop, sizeof(ntop), strport, sizeof(strport), |
453 | NI_NUMERICHOST|NI_NUMERICSERV) != 0) { | 456 | NI_NUMERICHOST|NI_NUMERICSERV) != 0) { |
454 | error("ssh_connect: getnameinfo failed"); | 457 | error("%s: getnameinfo failed", __func__); |
455 | continue; | 458 | continue; |
456 | } | 459 | } |
457 | debug("Connecting to %.200s [%.100s] port %s.", | 460 | debug("Connecting to %.200s [%.100s] port %s.", |
@@ -529,7 +532,7 @@ send_client_banner(int connection_out, int minor1) | |||
529 | xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", | 532 | xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", |
530 | PROTOCOL_MAJOR_1, minor1, SSH_RELEASE); | 533 | PROTOCOL_MAJOR_1, minor1, SSH_RELEASE); |
531 | } | 534 | } |
532 | if (roaming_atomicio(vwrite, connection_out, client_version_string, | 535 | if (atomicio(vwrite, connection_out, client_version_string, |
533 | strlen(client_version_string)) != strlen(client_version_string)) | 536 | strlen(client_version_string)) != strlen(client_version_string)) |
534 | fatal("write: %.100s", strerror(errno)); | 537 | fatal("write: %.100s", strerror(errno)); |
535 | chop(client_version_string); | 538 | chop(client_version_string); |
@@ -589,7 +592,7 @@ ssh_exchange_identification(int timeout_ms) | |||
589 | } | 592 | } |
590 | } | 593 | } |
591 | 594 | ||
592 | len = roaming_atomicio(read, connection_in, &buf[i], 1); | 595 | len = atomicio(read, connection_in, &buf[i], 1); |
593 | 596 | ||
594 | if (len != 1 && errno == EPIPE) | 597 | if (len != 1 && errno == EPIPE) |
595 | fatal("ssh_exchange_identification: " | 598 | fatal("ssh_exchange_identification: " |
@@ -925,7 +928,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
925 | options.fingerprint_hash, SSH_FP_RANDOMART); | 928 | options.fingerprint_hash, SSH_FP_RANDOMART); |
926 | if (fp == NULL || ra == NULL) | 929 | if (fp == NULL || ra == NULL) |
927 | fatal("%s: sshkey_fingerprint fail", __func__); | 930 | fatal("%s: sshkey_fingerprint fail", __func__); |
928 | logit("Host key fingerprint is %s\n%s\n", fp, ra); | 931 | logit("Host key fingerprint is %s\n%s", fp, ra); |
929 | free(ra); | 932 | free(ra); |
930 | free(fp); | 933 | free(fp); |
931 | } | 934 | } |
@@ -1242,8 +1245,9 @@ fail: | |||
1242 | int | 1245 | int |
1243 | verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | 1246 | verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) |
1244 | { | 1247 | { |
1248 | u_int i; | ||
1245 | int r = -1, flags = 0; | 1249 | int r = -1, flags = 0; |
1246 | char *fp = NULL; | 1250 | char valid[64], *fp = NULL, *cafp = NULL; |
1247 | struct sshkey *plain = NULL; | 1251 | struct sshkey *plain = NULL; |
1248 | 1252 | ||
1249 | if ((fp = sshkey_fingerprint(host_key, | 1253 | if ((fp = sshkey_fingerprint(host_key, |
@@ -1253,8 +1257,31 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | |||
1253 | goto out; | 1257 | goto out; |
1254 | } | 1258 | } |
1255 | 1259 | ||
1256 | debug("Server host key: %s %s", | 1260 | if (sshkey_is_cert(host_key)) { |
1257 | compat20 ? sshkey_ssh_name(host_key) : sshkey_type(host_key), fp); | 1261 | if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, |
1262 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { | ||
1263 | error("%s: fingerprint CA key: %s", | ||
1264 | __func__, ssh_err(r)); | ||
1265 | r = -1; | ||
1266 | goto out; | ||
1267 | } | ||
1268 | sshkey_format_cert_validity(host_key->cert, | ||
1269 | valid, sizeof(valid)); | ||
1270 | debug("Server host certificate: %s %s, serial %llu " | ||
1271 | "ID \"%s\" CA %s %s valid %s", | ||
1272 | sshkey_ssh_name(host_key), fp, | ||
1273 | (unsigned long long)host_key->cert->serial, | ||
1274 | host_key->cert->key_id, | ||
1275 | sshkey_ssh_name(host_key->cert->signature_key), cafp, | ||
1276 | valid); | ||
1277 | for (i = 0; i < host_key->cert->nprincipals; i++) { | ||
1278 | debug2("Server host certificate hostname: %s", | ||
1279 | host_key->cert->principals[i]); | ||
1280 | } | ||
1281 | } else { | ||
1282 | debug("Server host key: %s %s", compat20 ? | ||
1283 | sshkey_ssh_name(host_key) : sshkey_type(host_key), fp); | ||
1284 | } | ||
1258 | 1285 | ||
1259 | if (sshkey_equal(previous_host_key, host_key)) { | 1286 | if (sshkey_equal(previous_host_key, host_key)) { |
1260 | debug2("%s: server host key %s %s matches cached key", | 1287 | debug2("%s: server host key %s %s matches cached key", |
@@ -1319,6 +1346,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | |||
1319 | out: | 1346 | out: |
1320 | sshkey_free(plain); | 1347 | sshkey_free(plain); |
1321 | free(fp); | 1348 | free(fp); |
1349 | free(cafp); | ||
1322 | if (r == 0 && host_key != NULL) { | 1350 | if (r == 0 && host_key != NULL) { |
1323 | key_free(previous_host_key); | 1351 | key_free(previous_host_key); |
1324 | previous_host_key = key_from_private(host_key); | 1352 | previous_host_key = key_from_private(host_key); |
@@ -1493,3 +1521,30 @@ ssh_local_cmd(const char *args) | |||
1493 | 1521 | ||
1494 | return (WEXITSTATUS(status)); | 1522 | return (WEXITSTATUS(status)); |
1495 | } | 1523 | } |
1524 | |||
1525 | void | ||
1526 | maybe_add_key_to_agent(char *authfile, Key *private, char *comment, | ||
1527 | char *passphrase) | ||
1528 | { | ||
1529 | int auth_sock = -1, r; | ||
1530 | |||
1531 | if (options.add_keys_to_agent == 0) | ||
1532 | return; | ||
1533 | |||
1534 | if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { | ||
1535 | debug3("no authentication agent, not adding key"); | ||
1536 | return; | ||
1537 | } | ||
1538 | |||
1539 | if (options.add_keys_to_agent == 2 && | ||
1540 | !ask_permission("Add key %s (%s) to agent?", authfile, comment)) { | ||
1541 | debug3("user denied adding this key"); | ||
1542 | return; | ||
1543 | } | ||
1544 | |||
1545 | if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0, | ||
1546 | (options.add_keys_to_agent == 3))) == 0) | ||
1547 | debug("identity added to agent: %s", authfile); | ||
1548 | else | ||
1549 | debug("could not add identity to agent: %s (%d)", authfile, r); | ||
1550 | } | ||