diff options
author | Damien Miller <djm@mindrot.org> | 1999-11-15 15:25:10 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-11-15 15:25:10 +1100 |
commit | 2ccf661cbe0924a1549a74b5a4f970e90f94d6a9 (patch) | |
tree | 8bb7ea3cbe9d473e7f46b7084f563cc593cc5d47 /sshd.c | |
parent | cedfecc99e73f9661d4dc3cea8c88e57c6e0b487 (diff) |
- Merged more OpenBSD CVS changes:
[auth-krb4.c]
- disconnect if getpeername() fails
- missing xfree(*client)
[canohost.c]
- disconnect if getpeername() fails
- fix comment: we _do_ disconnect if ip-options are set
[sshd.c]
- disconnect if getpeername() fails
- move checking of remote port to central place
[auth-rhosts.c] move checking of remote port to central place
[log-server.c] avoid extra fd per sshd, from millert@
[readconf.c] print _all_ bad config-options in ssh(1), too
[readconf.h] print _all_ bad config-options in ssh(1), too
[ssh.c] print _all_ bad config-options in ssh(1), too
[sshconnect.c] disconnect if getpeername() fails
- OpenBSD's changes to sshd.c broke the PAM stuff, re-merged it.
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 671 |
1 files changed, 307 insertions, 364 deletions
@@ -18,7 +18,7 @@ agent connections. */ #include "includes.h" -RCSID("$Id: sshd.c,v 1.17 1999/11/12 04:19:27 damien Exp $"); +RCSID("$Id: sshd.c,v 1.18 1999/11/15 04:25:10 damien Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -114,9 +114,10 @@ int received_sighup = 0; RSA *public_key; /* Prototypes for various functions defined later in this file. */ -void do_connection(int privileged_port); -void do_authentication(char *user, int privileged_port); -void eat_packets_and_disconnect(const char *user); +void do_connection(); +void do_authentication(char *user); +void do_authloop(struct passwd *pw); +void do_fake_authloop(char *user); void do_authenticated(struct passwd *pw); void do_exec_pty(const char *command, int ptyfd, int ttyfd, const char *ttyname, struct passwd *pw, const char *term, @@ -128,11 +129,12 @@ void do_exec_no_pty(const char *command, struct passwd *pw, void do_child(const char *command, struct passwd *pw, const char *term, const char *display, const char *auth_proto, const char *auth_data, const char *ttyname); + #ifdef HAVE_LIBPAM static int pamconv(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr); -void do_pam_account_and_session(const char *username, const char *password, - const char *remote_user, const char *remote_host); + struct pam_response **resp, void *appdata_ptr); +void do_pam_account_and_session(const char *username, + const char *remote_user, const char *remote_host); void pam_cleanup_proc(void *context); static struct pam_conv conv = { @@ -228,7 +230,7 @@ void pam_cleanup_proc(void *context) } } -void do_pam_account_and_session(const char *username, const char *password, const char *remote_user, const char *remote_host) +void do_pam_account_and_session(const char *username, const char *remote_user, const char *remote_host) { int pam_retval; @@ -239,7 +241,7 @@ void do_pam_account_and_session(const char *username, const char *password, cons if (pam_retval != PAM_SUCCESS) { log("PAM set rhost failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); - eat_packets_and_disconnect(username); + do_fake_authloop(username); } } @@ -250,7 +252,7 @@ void do_pam_account_and_session(const char *username, const char *password, cons if (pam_retval != PAM_SUCCESS) { log("PAM set ruser failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); - eat_packets_and_disconnect(username); + do_fake_authloop(username); } } @@ -258,14 +260,14 @@ void do_pam_account_and_session(const char *username, const char *password, cons if (pam_retval != PAM_SUCCESS) { log("PAM rejected by account configuration: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); - eat_packets_and_disconnect(username); + do_fake_authloop(username); } pam_retval = pam_open_session((pam_handle_t *)pamh, 0); if (pam_retval != PAM_SUCCESS) { log("PAM session setup failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); - eat_packets_and_disconnect(username); + do_fake_authloop(username); } } #endif /* HAVE_LIBPAM */ @@ -375,6 +377,7 @@ main(int ac, char **av) struct sockaddr_in sin; char buf[100]; /* Must not be larger than remote_version. */ char remote_version[100]; /* Must be at least as big as buf. */ + int remote_port; char *comment; FILE *f; struct linger linger; @@ -742,6 +745,8 @@ main(int ac, char **av) have a key. */ packet_set_connection(sock_in, sock_out); + remote_port = get_remote_port(); + /* Check whether logins are denied from this host. */ #ifdef LIBWRAP { @@ -755,13 +760,11 @@ main(int ac, char **av) close(sock_out); refuse(&req); } - log("Connection from %.500s port %d", - eval_client(&req), get_remote_port()); + log("Connection from %.500s port %d", eval_client(&req), remote_port); } #else /* Log the connection. */ - log("Connection from %.100s port %d", - get_remote_ipaddr(), get_remote_port()); + log("Connection from %.100s port %d", get_remote_ipaddr(), remote_port); #endif /* LIBWRAP */ /* We don\'t want to listen forever unless the other side successfully @@ -834,11 +837,23 @@ main(int ac, char **av) } } + /* Check that the connection comes from a privileged port. + Rhosts- and Rhosts-RSA-Authentication only make sense + from priviledged programs. + Of course, if the intruder has root access on his local machine, + he can connect from any port. So do not use these authentication + methods from machines that you do not trust. */ + if (remote_port >= IPPORT_RESERVED || + remote_port < IPPORT_RESERVED / 2) + { + options.rhosts_authentication = 0; + options.rhosts_rsa_authentication = 0; + } + packet_set_nonblocking(); - /* Handle the connection. We pass as argument whether the connection - came from a privileged port. */ - do_connection(get_remote_port() < IPPORT_RESERVED); + /* Handle the connection. */ + do_connection(); #ifdef KRB4 /* Cleanup user's ticket cache file. */ @@ -879,7 +894,8 @@ main(int ac, char **av) been exchanged. This sends server key and performs the key exchange. Server and host keys will no longer be needed after this functions. */ -void do_connection(int privileged_port) +void +do_connection() { int i, len; BIGNUM *session_key_int; @@ -1071,7 +1087,7 @@ void do_connection(int privileged_port) setproctitle("%s", user); /* Do the authentication. */ - do_authentication(user, privileged_port); + do_authentication(user); } /* Check if the user is allowed to log in via ssh. If user is listed in @@ -1154,26 +1170,13 @@ allowed_user(struct passwd *pw) /* Performs authentication of an incoming connection. Session key has already been exchanged and encryption is enabled. User is the user name to log - in as (received from the clinet). Privileged_port is true if the - connection comes from a privileged port (used for .rhosts authentication).*/ - -#define MAX_AUTH_FAILURES 5 + in as (received from the client). */ void -do_authentication(char *user, int privileged_port) +do_authentication(char *user) { - int type; - int authenticated = 0; - int authentication_failures = 0; - char *password = NULL; struct passwd *pw, pwcopy; - char *client_user = NULL; - unsigned int client_host_key_bits; - BIGNUM *client_host_key_e, *client_host_key_n; -#ifdef HAVE_LIBPAM - int pam_retval; -#endif /* HAVE_LIBPAM */ - + #ifdef AFS /* If machine has AFS, set process authentication group. */ if (k_hasafs()) { @@ -1185,8 +1188,8 @@ do_authentication(char *user, int privileged_port) /* Verify that the user is a valid user. */ pw = getpwnam(user); if (!pw || !allowed_user(pw)) - eat_packets_and_disconnect(user); - + do_fake_authloop(user); + /* Take a copy of the returned structure. */ memset(&pwcopy, 0, sizeof(pwcopy)); pwcopy.pw_name = xstrdup(pw->pw_name); @@ -1199,13 +1202,11 @@ do_authentication(char *user, int privileged_port) #ifdef HAVE_LIBPAM debug("Starting up PAM with username \"%.200s\"", pw->pw_name); - pam_retval = pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh); - if (pam_retval != PAM_SUCCESS) - { - log("PAM initialisation failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); - eat_packets_and_disconnect(user); - } - fatal_add_cleanup(&pam_cleanup_proc, NULL); + + if (pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh) != PAM_SUCCESS) + fatal("PAM initialisation failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval)); + + fatal_add_cleanup(&pam_cleanup_proc, NULL); #endif /* If we are not running as root, the user must have the same uid as the @@ -1224,313 +1225,263 @@ do_authentication(char *user, int privileged_port) { /* Authentication with empty password succeeded. */ debug("Login for user %.100s accepted without authentication.", user); - /* authentication_type = SSH_AUTH_PASSWORD; */ - authenticated = 1; - /* Success packet will be sent after loop below. */ + } else { + /* Loop until the user has been authenticated or the connection is closed, + do_authloop() returns only if authentication is successfull */ + do_authloop(pw); } - else + + /* XXX log unified auth message */ + + /* Check if the user is logging in as root and root logins are disallowed. */ + if (pw->pw_uid == 0 && !options.permit_root_login) { - /* Indicate that authentication is needed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); + if (forced_command) + log("Root login accepted for forced command."); + else + packet_disconnect("ROOT LOGIN REFUSED FROM %.200s", + get_canonical_hostname()); } - /* Loop until the user has been authenticated or the connection is closed. */ - while (!authenticated) - { - int plen; - /* Get a packet from the client. */ - type = packet_read(&plen); - - /* Process the packet. */ - switch (type) - { + /* The user has been authenticated and accepted. */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); -#ifdef AFS - case SSH_CMSG_HAVE_KERBEROS_TGT: - if (!options.kerberos_tgt_passing) - { - /* packet_get_all(); */ - log("Kerberos tgt passing disabled."); - break; - } - else { - /* Accept Kerberos tgt. */ - int dlen; - char *tgt = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - if (!auth_kerberos_tgt(pw, tgt)) - debug("Kerberos tgt REFUSED for %s", user); - xfree(tgt); - } - continue; + /* Perform session preparation. */ + do_authenticated(pw); +} + +#define MAX_AUTH_FAILURES 5 + +/* read packets and try to authenticate local user *pw. + return if authentication is successfull */ +void +do_authloop(struct passwd *pw) +{ + int authentication_failures = 0; + unsigned int client_host_key_bits; + BIGNUM *client_host_key_e, *client_host_key_n; + BIGNUM *n; + char *client_user, *password; + int plen, dlen, nlen, ulen, elen; + + /* Indicate that authentication is needed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + for (;;) { + int authenticated = 0; - case SSH_CMSG_HAVE_AFS_TOKEN: - if (!options.afs_token_passing || !k_hasafs()) { + /* Get a packet from the client. */ + int type = packet_read(&plen); + + /* Process the packet. */ + switch (type) + { +#ifdef AFS + case SSH_CMSG_HAVE_KERBEROS_TGT: + if (!options.kerberos_tgt_passing) + { /* packet_get_all(); */ - log("AFS token passing disabled."); + log("Kerberos tgt passing disabled."); break; } - else { - /* Accept AFS token. */ - int dlen; - char *token_string = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); - if (!auth_afs_token(pw, token_string)) - debug("AFS token REFUSED for %s", user); - xfree(token_string); - continue; - } + else { + /* Accept Kerberos tgt. */ + char *tgt = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_kerberos_tgt(pw, tgt)) + debug("Kerberos tgt REFUSED for %s", pw->pw_name); + xfree(tgt); + } + continue; + + case SSH_CMSG_HAVE_AFS_TOKEN: + if (!options.afs_token_passing || !k_hasafs()) { + /* packet_get_all(); */ + log("AFS token passing disabled."); + break; + } + else { + /* Accept AFS token. */ + char *token_string = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + if (!auth_afs_token(pw, token_string)) + debug("AFS token REFUSED for %s", pw->pw_name); + xfree(token_string); + } + continue; #endif /* AFS */ - -#ifdef KRB4 - case SSH_CMSG_AUTH_KERBEROS: - if (!options.kerberos_authentication) - { - /* packet_get_all(); */ - log("Kerberos authentication disabled."); - break; - } - else { - /* Try Kerberos v4 authentication. */ - KTEXT_ST auth; - char *tkt_user = NULL; - char *kdata = packet_get_string((unsigned int *)&auth.length); - packet_integrity_check(plen, 4 + auth.length, type); - - if (auth.length < MAX_KTXT_LEN) - memcpy(auth.dat, kdata, auth.length); - xfree(kdata); - if (auth_krb4(user, &auth, &tkt_user)) { - /* Client has successfully authenticated to us. */ - log("Kerberos authentication accepted %s for account " - "%s from %s", tkt_user, user, get_canonical_hostname()); - /* authentication_type = SSH_AUTH_KERBEROS; */ - authenticated = 1; - xfree(tkt_user); - } - else { - log("Kerberos authentication failed for account " - "%s from %s", user, get_canonical_hostname()); - } +#ifdef KRB4 + case SSH_CMSG_AUTH_KERBEROS: + if (!options.kerberos_authentication) + { + /* packet_get_all(); */ + log("Kerberos authentication disabled."); + break; } - break; -#endif /* KRB4 */ + else { + /* Try Kerberos v4 authentication. */ + KTEXT_ST auth; + char *tkt_user = NULL; + char *kdata = packet_get_string((unsigned int *)&auth.length); + packet_integrity_check(plen, 4 + auth.length, type); + + if (auth.length < MAX_KTXT_LEN) + memcpy(auth.dat, kdata, auth.length); + xfree(kdata); - case SSH_CMSG_AUTH_RHOSTS: - if (!options.rhosts_authentication) - { - log("Rhosts authentication disabled."); - break; - } - - /* Rhosts authentication (also uses /etc/hosts.equiv). */ - if (!privileged_port) - { - log("Rhosts authentication not available for connections from unprivileged port."); - break; - } - - /* Get client user name. Note that we just have to trust the client; - this is one reason why rhosts authentication is insecure. - (Another is IP-spoofing on a local network.) */ + authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); + + log("Kerberos authentication %s%s for account %s from %s", + authenticated ? "accepted " : "failed", + tkt_user != NULL ? tkt_user : "", + pw->pw_name, get_canonical_hostname()); + if (authenticated) + xfree(tkt_user); + } + break; +#endif /* KRB4 */ + + case SSH_CMSG_AUTH_RHOSTS: + if (!options.rhosts_authentication) { - int dlen; - client_user = packet_get_string(&dlen); - packet_integrity_check(plen, 4 + dlen, type); + log("Rhosts authentication disabled."); + break; } + + /* Get client user name. Note that we just have to trust the client; + this is one reason why rhosts authentication is insecure. + (Another is IP-spoofing on a local network.) */ + client_user = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + + /* Try to authenticate using /etc/hosts.equiv and .rhosts. */ + authenticated = auth_rhosts(pw, client_user); - /* Try to authenticate using /etc/hosts.equiv and .rhosts. */ - if (auth_rhosts(pw, client_user)) - { - /* Authentication accepted. */ - log("Rhosts authentication accepted for %.100s, remote %.100s on %.700s.", - user, client_user, get_canonical_hostname()); - authenticated = 1; + log("Rhosts authentication %s for %.100s, remote %.100s on %.700s.", + authenticated ? "accepted" : "failed", + pw->pw_name, client_user, get_canonical_hostname()); #ifndef HAVE_LIBPAM - xfree(client_user); + xfree(client_user); #endif /* HAVE_LIBPAM */ - break; - } - log("Rhosts authentication failed for %.100s, remote %.100s.", - user, client_user); -#ifndef HAVE_LIBPAM - xfree(client_user); -#endif /* HAVE_LIBPAM */ - break; - - case SSH_CMSG_AUTH_RHOSTS_RSA: - if (!options.rhosts_rsa_authentication) - { - log("Rhosts with RSA authentication disabled."); - break; - } - - /* Rhosts authentication (also uses /etc/hosts.equiv) with RSA - host authentication. */ - if (!privileged_port) - { - log("Rhosts authentication not available for connections from unprivileged port."); - break; - } - + break; + + case SSH_CMSG_AUTH_RHOSTS_RSA: + if (!options.rhosts_rsa_authentication) { - int ulen, elen, nlen; - /* Get client user name. Note that we just have to trust - the client; root on the client machine can claim to be - any user. */ - client_user = packet_get_string(&ulen); - - /* Get the client host key. */ - client_host_key_e = BN_new(); - client_host_key_n = BN_new(); - client_host_key_bits = packet_get_int(); - packet_get_bignum(client_host_key_e, &elen); - packet_get_bignum(client_host_key_n, &nlen); - - packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); + log("Rhosts with RSA authentication disabled."); + break; } - - if (auth_rhosts_rsa(pw, client_user, - client_host_key_bits, client_host_key_e, client_host_key_n)) - { - /* Authentication accepted. */ - authenticated = 1; -#ifndef HAVE_LIBPAM - xfree(client_user); -#endif /* HAVE_LIBPAM */ - BN_clear_free(client_host_key_e); - BN_clear_free(client_host_key_n); - break; - } - log("Rhosts authentication failed for %.100s, remote %.100s.", - user, client_user); + + /* Get client user name. Note that we just have to trust + the client; root on the client machine can claim to be + any user. */ + client_user = packet_get_string(&ulen); + + /* Get the client host key. */ + client_host_key_e = BN_new(); + client_host_key_n = BN_new(); + client_host_key_bits = packet_get_int(); + packet_get_bignum(client_host_key_e, &elen); + packet_get_bignum(client_host_key_n, &nlen); + + packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type); + + authenticated = auth_rhosts_rsa(pw, client_user, client_host_key_bits, + client_host_key_e, client_host_key_n); + log("Rhosts authentication %s for %.100s, remote %.100s.", + authenticated ? "accepted" : "failed", + pw->pw_name, client_user); #ifndef HAVE_LIBPAM - xfree(client_user); + xfree(client_user); #endif /* HAVE_LIBPAM */ - BN_clear_free(client_host_key_e); - BN_clear_free(client_host_key_n); - break; - - case SSH_CMSG_AUTH_RSA: - if (!options.rsa_authentication) - { - log("RSA authentication disabled."); - break; - } - - /* RSA authentication requested. */ + BN_clear_free(client_host_key_e); + BN_clear_free(client_host_key_n); + break; + + case SSH_CMSG_AUTH_RSA: + if (!options.rsa_authentication) { - int nlen; - BIGNUM *n; - n = BN_new(); - packet_get_bignum(n, &nlen); - - packet_integrity_check(plen, nlen, type); - - if (auth_rsa(pw, n)) - { - /* Successful authentication. */ - BN_clear_free(n); - log("RSA authentication for %.100s accepted.", user); - authenticated = 1; - break; - } - BN_clear_free(n); - log("RSA authentication for %.100s failed.", user); + log("RSA authentication disabled."); + break; } - break; - - case SSH_CMSG_AUTH_PASSWORD: - if (!options.password_authentication) - { - log("Password authentication disabled."); - break; - } - - /* Password authentication requested. */ - /* Read user password. It is in plain text, but was transmitted - over the encrypted channel so it is not visible to an outside - observer. */ + + /* RSA authentication requested. */ + n = BN_new(); + packet_get_bignum(n, &nlen); + packet_integrity_check(plen, nlen, type); + authenticated = auth_rsa(pw, n); + BN_clear_free(n); + log("RSA authentication %s for %.100s.", + authenticated ? "accepted" : "failed", + pw->pw_name); + break; + + case SSH_CMSG_AUTH_PASSWORD: + if (!options.password_authentication) { - int passw_len; - password = packet_get_string(&passw_len); - packet_integrity_check(plen, 4 + passw_len, type); + log("Password authentication disabled."); + break; } - + + /* Read user password. It is in plain text, but was transmitted + over the encrypted channel so it is not visible to an outside + observer. */ + password = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + #ifdef HAVE_LIBPAM - pampasswd = password; - - pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); - if (pam_retval == PAM_SUCCESS) - { - log("PAM Password authentication accepted for \"%.100s\"", user); - authenticated = 1; - break; - } else - { - log("PAM Password authentication for \"%.100s\" failed: %s", - user, pam_strerror((pam_handle_t *)pamh, pam_retval)); - break; - } + /* Do PAM auth with password */ + pampasswd = password; + pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); + if (pam_retval == PAM_SUCCESS) + { + log("PAM Password authentication accepted for user \"%.100s\"", user); + authenticated = 1; + break; + } + + log("PAM Password authentication for \"%.100s\" failed: %s", + user, pam_strerror((pam_handle_t *)pamh, pam_retval)); + break; #else /* HAVE_LIBPAM */ - /* Try authentication with the password. */ - if (auth_password(pw, password)) - { - /* Successful authentication. */ - /* Clear the password from memory. */ - memset(password, 0, strlen(password)); - xfree(password); - log("Password authentication for %.100s accepted.", user); - authenticated = 1; - break; - } - log("Password authentication for %.100s failed.", user); - memset(password, 0, strlen(password)); - xfree(password); - break; -#endif /* HAVE_LIBPAM */ - - case SSH_CMSG_AUTH_TIS: - /* TIS Authentication is unsupported */ - log("TIS authentication disabled."); - break; + /* Try authentication with the password. */ + authenticated = auth_password(pw, password); - default: - /* Any unknown messages will be ignored (and failure returned) - during authentication. */ - log("Unknown message during authentication: type %d", type); - break; /* Respond with a failure message. */ - } - /* If successfully authenticated, break out of loop. */ - if (authenticated) + memset(password, 0, strlen(password)); + xfree(password); break; - - if (++authentication_failures >= MAX_AUTH_FAILURES) { - packet_disconnect("Too many authentication failures for %.100s from %.200s", - pw->pw_name, get_canonical_hostname()); +#endif /* HAVE_LIBPAM */ + + case SSH_CMSG_AUTH_TIS: + /* TIS Authentication is unsupported */ + log("TIS authentication disabled."); + break; + + default: + /* Any unknown messages will be ignored (and failure returned) + during authentication. */ + log("Unknown message during authentication: type %d", type); + break; /* Respond with a failure message. */ } - /* Send a message indicating that the authentication attempt failed. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - } - - /* Check if the user is logging in as root and root logins are disallowed. */ - if (pw->pw_uid == 0 && !options.permit_root_login) - { - if (forced_command) - log("Root login accepted for forced command."); - else - packet_disconnect("ROOT LOGIN REFUSED FROM %.200s", - get_canonical_hostname()); - } + if (authenticated) + break; + if (++authentication_failures >= MAX_AUTH_FAILURES) + packet_disconnect("Too many authentication failures for %.100s from %.200s", + pw->pw_name, get_canonical_hostname()); + /* Send a message indicating that the authentication attempt failed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + } #ifdef HAVE_LIBPAM - do_pam_account_and_session(pw->pw_name, password, client_user, get_canonical_hostname()); + do_pam_account_and_session(pw->pw_name, client_user, get_canonical_hostname()); /* Clean up */ if (client_user != NULL) @@ -1542,65 +1493,55 @@ do_authentication(char *user, int privileged_port) xfree(password); } #endif /* HAVE_LIBPAM */ - - /* The user has been authenticated and accepted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); - - /* Perform session preparation. */ - do_authenticated(pw); } -/* Read authentication messages, but return only failures until */ -/* max auth attempts exceeded, then disconnect */ -void eat_packets_and_disconnect(const char *user) +/* The user does not exist or access is denied, + but fake indication that authentication is needed. */ +void +do_fake_authloop(char *user) { int authentication_failures = 0; - + + /* Indicate that authentication is needed. */ packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); /* Keep reading packets, and always respond with a failure. This is to avoid disclosing whether such a user really exists. */ - while(1) - { - /* Read a packet. This will not return if the client disconnects. */ - int plen; -#ifndef SKEY - (void) packet_read(&plen); -#else /* SKEY */ - int type = packet_read(&plen); - int passw_len; - char *password, *skeyinfo; - if (options.password_authentication && - options.skey_authentication == 1 && - type == SSH_CMSG_AUTH_PASSWORD && - (password = packet_get_string(&passw_len)) != NULL && - passw_len == 5 && - strncasecmp(password, "s/key", 5) == 0 && - (skeyinfo = skey_fake_keyinfo(user)) != NULL ) + for (;;) { - /* Send a fake s/key challenge. */ - packet_send_debug(skeyinfo); - } -#endif /* SKEY */ - if (++authentication_failures >= MAX_AUTH_FAILURES) - { - packet_disconnect("Too many authentication failures for %.100s from %.200s", - user, get_canonical_hostname()); + /* Read a packet. This will not return if the client disconnects. */ + int plen; + int type = packet_read(&plen); +#ifdef SKEY + int passw_len; + char *password, *skeyinfo; + if (options.password_authentication && + options.skey_authentication == 1 && + type == SSH_CMSG_AUTH_PASSWORD && + (password = packet_get_string(&passw_len)) != NULL && + passw_len == 5 && + strncasecmp(password, "s/key", 5) == 0 && + (skeyinfo = skey_fake_keyinfo(user)) != NULL ){ + /* Send a fake s/key challenge. */ + packet_send_debug(skeyinfo); + } +#endif + if (++authentication_failures >= MAX_AUTH_FAILURES) + packet_disconnect("Too many authentication failures for %.100s from %.200s", + user, get_canonical_hostname()); + /* Send failure. This should be indistinguishable from a failed + authentication. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); } - /* Send failure. This should be indistinguishable from a failed - authentication. */ - packet_start(SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - } /*NOTREACHED*/ abort(); } + /* Remove local Xauthority file. */ static void xauthfile_cleanup_proc(void *ignore) @@ -2075,8 +2016,10 @@ void do_exec_pty(const char *command, int ptyfd, int ttyfd, { fromlen = sizeof(from); if (getpeername(packet_get_connection_in(), - (struct sockaddr *)&from, &fromlen) < 0) - fatal("getpeername: %.100s", strerror(errno)); + (struct sockaddr *)&from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } } /* Record that there was a login on that terminal. */ |