diff options
author | Colin Watson <cjwatson@debian.org> | 2010-03-31 10:46:28 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2010-03-31 10:46:28 +0100 |
commit | efd3d4522636ae029488c2e9730b60c88e257d2e (patch) | |
tree | 31e02ac3f16090ce8c53448677356b2b7f423683 /sshconnect2.c | |
parent | bbec4db36d464ea1d464a707625125f9fd5c7b5e (diff) | |
parent | d1a87e462e1db89f19cd960588d0c6b287cb5ccc (diff) |
* New upstream release (LP: #535029).
- After a transition period of about 10 years, this release disables SSH
protocol 1 by default. Clients and servers that need to use the
legacy protocol must explicitly enable it in ssh_config / sshd_config
or on the command-line.
- Remove the libsectok/OpenSC-based smartcard code and add support for
PKCS#11 tokens. This support is enabled by default in the Debian
packaging, since it now doesn't involve additional library
dependencies (closes: #231472, LP: #16918).
- Add support for certificate authentication of users and hosts using a
new, minimal OpenSSH certificate format (closes: #482806).
- Added a 'netcat mode' to ssh(1): "ssh -W host:port ...".
- Add the ability to revoke keys in sshd(8) and ssh(1). (For the Debian
package, this overlaps with the key blacklisting facility added in
openssh 1:4.7p1-9, but with different file formats and slightly
different scopes; for the moment, I've roughly merged the two.)
- Various multiplexing improvements, including support for requesting
port-forwardings via the multiplex protocol (closes: #360151).
- Allow setting an explicit umask on the sftp-server(8) commandline to
override whatever default the user has (closes: #496843).
- Many sftp client improvements, including tab-completion, more options,
and recursive transfer support for get/put (LP: #33378). The old
mget/mput commands never worked properly and have been removed
(closes: #270399, #428082).
- Do not prompt for a passphrase if we fail to open a keyfile, and log
the reason why the open failed to debug (closes: #431538).
- Prevent sftp from crashing when given a "-" without a command. Also,
allow whitespace to follow a "-" (closes: #531561).
Diffstat (limited to 'sshconnect2.c')
-rw-r--r-- | sshconnect2.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/sshconnect2.c b/sshconnect2.c index bc8d206ae..f10f6bf8c 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.171 2009/03/05 07:18:19 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.180 2010/02/26 20:29:54 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. |
@@ -32,6 +32,7 @@ | |||
32 | #include <sys/stat.h> | 32 | #include <sys/stat.h> |
33 | 33 | ||
34 | #include <errno.h> | 34 | #include <errno.h> |
35 | #include <fcntl.h> | ||
35 | #include <netdb.h> | 36 | #include <netdb.h> |
36 | #include <pwd.h> | 37 | #include <pwd.h> |
37 | #include <signal.h> | 38 | #include <signal.h> |
@@ -204,6 +205,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
204 | 205 | ||
205 | dispatch_run(DISPATCH_BLOCK, &kex->done, kex); | 206 | dispatch_run(DISPATCH_BLOCK, &kex->done, kex); |
206 | 207 | ||
208 | if (options.use_roaming && !kex->roaming) { | ||
209 | debug("Roaming not allowed by server"); | ||
210 | options.use_roaming = 0; | ||
211 | } | ||
212 | |||
207 | session_id2 = kex->session_id; | 213 | session_id2 = kex->session_id; |
208 | session_id2_len = kex->session_id_len; | 214 | session_id2_len = kex->session_id_len; |
209 | 215 | ||
@@ -262,6 +268,7 @@ struct Authmethod { | |||
262 | }; | 268 | }; |
263 | 269 | ||
264 | void input_userauth_success(int, u_int32_t, void *); | 270 | void input_userauth_success(int, u_int32_t, void *); |
271 | void input_userauth_success_unexpected(int, u_int32_t, void *); | ||
265 | void input_userauth_failure(int, u_int32_t, void *); | 272 | void input_userauth_failure(int, u_int32_t, void *); |
266 | void input_userauth_banner(int, u_int32_t, void *); | 273 | void input_userauth_banner(int, u_int32_t, void *); |
267 | void input_userauth_error(int, u_int32_t, void *); | 274 | void input_userauth_error(int, u_int32_t, void *); |
@@ -485,12 +492,15 @@ void | |||
485 | input_userauth_success(int type, u_int32_t seq, void *ctxt) | 492 | input_userauth_success(int type, u_int32_t seq, void *ctxt) |
486 | { | 493 | { |
487 | Authctxt *authctxt = ctxt; | 494 | Authctxt *authctxt = ctxt; |
495 | |||
488 | if (authctxt == NULL) | 496 | if (authctxt == NULL) |
489 | fatal("input_userauth_success: no authentication context"); | 497 | fatal("input_userauth_success: no authentication context"); |
490 | if (authctxt->authlist) { | 498 | if (authctxt->authlist) { |
491 | xfree(authctxt->authlist); | 499 | xfree(authctxt->authlist); |
492 | authctxt->authlist = NULL; | 500 | authctxt->authlist = NULL; |
493 | } | 501 | } |
502 | if (authctxt->method != NULL && authctxt->method->cleanup != NULL) | ||
503 | authctxt->method->cleanup(authctxt); | ||
494 | if (authctxt->methoddata) { | 504 | if (authctxt->methoddata) { |
495 | xfree(authctxt->methoddata); | 505 | xfree(authctxt->methoddata); |
496 | authctxt->methoddata = NULL; | 506 | authctxt->methoddata = NULL; |
@@ -498,6 +508,18 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt) | |||
498 | authctxt->success = 1; /* break out */ | 508 | authctxt->success = 1; /* break out */ |
499 | } | 509 | } |
500 | 510 | ||
511 | void | ||
512 | input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) | ||
513 | { | ||
514 | Authctxt *authctxt = ctxt; | ||
515 | |||
516 | if (authctxt == NULL) | ||
517 | fatal("%s: no authentication context", __func__); | ||
518 | |||
519 | fatal("Unexpected authentication success during %s.", | ||
520 | authctxt->method->name); | ||
521 | } | ||
522 | |||
501 | /* ARGSUSED */ | 523 | /* ARGSUSED */ |
502 | void | 524 | void |
503 | input_userauth_failure(int type, u_int32_t seq, void *ctxt) | 525 | input_userauth_failure(int type, u_int32_t seq, void *ctxt) |
@@ -892,6 +914,8 @@ userauth_passwd(Authctxt *authctxt) | |||
892 | static int attempt = 0; | 914 | static int attempt = 0; |
893 | char prompt[150]; | 915 | char prompt[150]; |
894 | char *password; | 916 | char *password; |
917 | const char *host = options.host_key_alias ? options.host_key_alias : | ||
918 | authctxt->host; | ||
895 | 919 | ||
896 | if (attempt++ >= options.number_of_password_prompts) | 920 | if (attempt++ >= options.number_of_password_prompts) |
897 | return 0; | 921 | return 0; |
@@ -900,7 +924,7 @@ userauth_passwd(Authctxt *authctxt) | |||
900 | error("Permission denied, please try again."); | 924 | error("Permission denied, please try again."); |
901 | 925 | ||
902 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", | 926 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", |
903 | authctxt->server_user, authctxt->host); | 927 | authctxt->server_user, host); |
904 | password = read_passphrase(prompt, 0); | 928 | password = read_passphrase(prompt, 0); |
905 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 929 | packet_start(SSH2_MSG_USERAUTH_REQUEST); |
906 | packet_put_cstring(authctxt->server_user); | 930 | packet_put_cstring(authctxt->server_user); |
@@ -929,6 +953,8 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | |||
929 | Authctxt *authctxt = ctxt; | 953 | Authctxt *authctxt = ctxt; |
930 | char *info, *lang, *password = NULL, *retype = NULL; | 954 | char *info, *lang, *password = NULL, *retype = NULL; |
931 | char prompt[150]; | 955 | char prompt[150]; |
956 | const char *host = options.host_key_alias ? options.host_key_alias : | ||
957 | authctxt->host; | ||
932 | 958 | ||
933 | debug2("input_userauth_passwd_changereq"); | 959 | debug2("input_userauth_passwd_changereq"); |
934 | 960 | ||
@@ -949,7 +975,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | |||
949 | packet_put_char(1); /* additional info */ | 975 | packet_put_char(1); /* additional info */ |
950 | snprintf(prompt, sizeof(prompt), | 976 | snprintf(prompt, sizeof(prompt), |
951 | "Enter %.30s@%.128s's old password: ", | 977 | "Enter %.30s@%.128s's old password: ", |
952 | authctxt->server_user, authctxt->host); | 978 | authctxt->server_user, host); |
953 | password = read_passphrase(prompt, 0); | 979 | password = read_passphrase(prompt, 0); |
954 | packet_put_cstring(password); | 980 | packet_put_cstring(password); |
955 | memset(password, 0, strlen(password)); | 981 | memset(password, 0, strlen(password)); |
@@ -958,7 +984,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | |||
958 | while (password == NULL) { | 984 | while (password == NULL) { |
959 | snprintf(prompt, sizeof(prompt), | 985 | snprintf(prompt, sizeof(prompt), |
960 | "Enter %.30s@%.128s's new password: ", | 986 | "Enter %.30s@%.128s's new password: ", |
961 | authctxt->server_user, authctxt->host); | 987 | authctxt->server_user, host); |
962 | password = read_passphrase(prompt, RP_ALLOW_EOF); | 988 | password = read_passphrase(prompt, RP_ALLOW_EOF); |
963 | if (password == NULL) { | 989 | if (password == NULL) { |
964 | /* bail out */ | 990 | /* bail out */ |
@@ -966,7 +992,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | |||
966 | } | 992 | } |
967 | snprintf(prompt, sizeof(prompt), | 993 | snprintf(prompt, sizeof(prompt), |
968 | "Retype %.30s@%.128s's new password: ", | 994 | "Retype %.30s@%.128s's new password: ", |
969 | authctxt->server_user, authctxt->host); | 995 | authctxt->server_user, host); |
970 | retype = read_passphrase(prompt, 0); | 996 | retype = read_passphrase(prompt, 0); |
971 | if (strcmp(password, retype) != 0) { | 997 | if (strcmp(password, retype) != 0) { |
972 | memset(password, 0, strlen(password)); | 998 | memset(password, 0, strlen(password)); |
@@ -1334,7 +1360,7 @@ load_identity_file(char *filename) | |||
1334 | { | 1360 | { |
1335 | Key *private; | 1361 | Key *private; |
1336 | char prompt[300], *passphrase; | 1362 | char prompt[300], *passphrase; |
1337 | int perm_ok, quit, i; | 1363 | int perm_ok = 0, quit, i; |
1338 | struct stat st; | 1364 | struct stat st; |
1339 | 1365 | ||
1340 | if (stat(filename, &st) < 0) { | 1366 | if (stat(filename, &st) < 0) { |
@@ -1397,6 +1423,8 @@ pubkey_prepare(Authctxt *authctxt) | |||
1397 | key = options.identity_keys[i]; | 1423 | key = options.identity_keys[i]; |
1398 | if (key && key->type == KEY_RSA1) | 1424 | if (key && key->type == KEY_RSA1) |
1399 | continue; | 1425 | continue; |
1426 | if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER) | ||
1427 | continue; | ||
1400 | options.identity_keys[i] = NULL; | 1428 | options.identity_keys[i] = NULL; |
1401 | id = xcalloc(1, sizeof(*id)); | 1429 | id = xcalloc(1, sizeof(*id)); |
1402 | id->key = key; | 1430 | id->key = key; |
@@ -1600,7 +1628,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, | |||
1600 | debug2("ssh_keysign called"); | 1628 | debug2("ssh_keysign called"); |
1601 | 1629 | ||
1602 | if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { | 1630 | if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { |
1603 | error("ssh_keysign: no installed: %s", strerror(errno)); | 1631 | error("ssh_keysign: not installed: %s", strerror(errno)); |
1604 | return -1; | 1632 | return -1; |
1605 | } | 1633 | } |
1606 | if (fflush(stdout) != 0) | 1634 | if (fflush(stdout) != 0) |
@@ -1618,6 +1646,8 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, | |||
1618 | return -1; | 1646 | return -1; |
1619 | } | 1647 | } |
1620 | if (pid == 0) { | 1648 | if (pid == 0) { |
1649 | /* keep the socket on exec */ | ||
1650 | fcntl(packet_get_connection_in(), F_SETFD, 0); | ||
1621 | permanently_drop_suid(getuid()); | 1651 | permanently_drop_suid(getuid()); |
1622 | close(from[0]); | 1652 | close(from[0]); |
1623 | if (dup2(from[1], STDOUT_FILENO) < 0) | 1653 | if (dup2(from[1], STDOUT_FILENO) < 0) |
@@ -1670,10 +1700,10 @@ userauth_hostbased(Authctxt *authctxt) | |||
1670 | Sensitive *sensitive = authctxt->sensitive; | 1700 | Sensitive *sensitive = authctxt->sensitive; |
1671 | Buffer b; | 1701 | Buffer b; |
1672 | u_char *signature, *blob; | 1702 | u_char *signature, *blob; |
1673 | char *chost, *pkalg, *p, myname[NI_MAXHOST]; | 1703 | char *chost, *pkalg, *p; |
1674 | const char *service; | 1704 | const char *service; |
1675 | u_int blen, slen; | 1705 | u_int blen, slen; |
1676 | int ok, i, len, found = 0; | 1706 | int ok, i, found = 0; |
1677 | 1707 | ||
1678 | /* check for a useful key */ | 1708 | /* check for a useful key */ |
1679 | for (i = 0; i < sensitive->nkeys; i++) { | 1709 | for (i = 0; i < sensitive->nkeys; i++) { |
@@ -1694,23 +1724,13 @@ userauth_hostbased(Authctxt *authctxt) | |||
1694 | return 0; | 1724 | return 0; |
1695 | } | 1725 | } |
1696 | /* figure out a name for the client host */ | 1726 | /* figure out a name for the client host */ |
1697 | p = NULL; | 1727 | p = get_local_name(packet_get_connection_in()); |
1698 | if (packet_connection_is_on_socket()) | ||
1699 | p = get_local_name(packet_get_connection_in()); | ||
1700 | if (p == NULL) { | ||
1701 | if (gethostname(myname, sizeof(myname)) == -1) { | ||
1702 | verbose("userauth_hostbased: gethostname: %s", | ||
1703 | strerror(errno)); | ||
1704 | } else | ||
1705 | p = xstrdup(myname); | ||
1706 | } | ||
1707 | if (p == NULL) { | 1728 | if (p == NULL) { |
1708 | error("userauth_hostbased: cannot get local ipaddr/name"); | 1729 | error("userauth_hostbased: cannot get local ipaddr/name"); |
1709 | key_free(private); | 1730 | key_free(private); |
1710 | xfree(blob); | 1731 | xfree(blob); |
1711 | return 0; | 1732 | return 0; |
1712 | } | 1733 | } |
1713 | len = strlen(p) + 2; | ||
1714 | xasprintf(&chost, "%s.", p); | 1734 | xasprintf(&chost, "%s.", p); |
1715 | debug2("userauth_hostbased: chost %s", chost); | 1735 | debug2("userauth_hostbased: chost %s", chost); |
1716 | xfree(p); | 1736 | xfree(p); |
@@ -1821,6 +1841,8 @@ userauth_jpake(Authctxt *authctxt) | |||
1821 | /* Expect step 1 packet from peer */ | 1841 | /* Expect step 1 packet from peer */ |
1822 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, | 1842 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, |
1823 | input_userauth_jpake_server_step1); | 1843 | input_userauth_jpake_server_step1); |
1844 | dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, | ||
1845 | &input_userauth_success_unexpected); | ||
1824 | 1846 | ||
1825 | return 1; | 1847 | return 1; |
1826 | } | 1848 | } |
@@ -1833,6 +1855,7 @@ userauth_jpake_cleanup(Authctxt *authctxt) | |||
1833 | jpake_free(authctxt->methoddata); | 1855 | jpake_free(authctxt->methoddata); |
1834 | authctxt->methoddata = NULL; | 1856 | authctxt->methoddata = NULL; |
1835 | } | 1857 | } |
1858 | dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); | ||
1836 | } | 1859 | } |
1837 | #endif /* JPAKE */ | 1860 | #endif /* JPAKE */ |
1838 | 1861 | ||