};
struct pam_handle_t *pamh = NULL;
const char *pampasswd = NULL;
+char *pamconv_msg = NULL;
static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
case PAM_TEXT_INFO:
reply[count].resp_retcode = PAM_SUCCESS;
reply[count].resp = xstrdup("");
+
+ if (msg[count]->msg == NULL) break;
+ debug("Adding PAM message: %s", msg[count]->msg);
+ if (pamconv_msg == NULL)
+ {
+ pamconv_msg = malloc(strlen(msg[count]->msg) + 2);
+
+ if (pamconv_msg == NULL)
+ return PAM_CONV_ERR;
+
+ strncpy(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
+ pamconv_msg[strlen(msg[count]->msg)] = '\n';
+ pamconv_msg[strlen(msg[count]->msg) + 1] = '\0';
+ } else
+ {
+ pamconv_msg = realloc(pamconv_msg, strlen(pamconv_msg) + strlen(msg[count]->msg) + 2);
+ strncat(pamconv_msg, msg[count]->msg, strlen(msg[count]->msg));
+ pamconv_msg[strlen(pamconv_msg)] = '\n';
+ pamconv_msg[strlen(pamconv_msg) + 1] = '\0';
+ }
break;
case PAM_PROMPT_ECHO_ON:
void pam_cleanup_proc(void *context)
{
- int retval;
+ int pam_retval;
if (pamh != NULL)
{
- retval = pam_close_session((pam_handle_t *)pamh, 0);
-
- if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
- log("Cannot release PAM authentication.");
+ pam_retval = pam_close_session((pam_handle_t *)pamh, 0);
+ if (pam_retval != PAM_SUCCESS)
+ {
+ log("Cannot close PAM session: %.200s",
+ pam_strerror((pam_handle_t *)pamh, pam_retval));
+ }
+
+ pam_retval = pam_end((pam_handle_t *)pamh, pam_retval);
+ if (pam_retval != PAM_SUCCESS)
+ {
+ log("Cannot release PAM authentication: %.200s",
+ pam_strerror((pam_handle_t *)pamh, pam_retval));
+ }
}
}
void do_pam_account_and_session(const char *username, const char *password, const char *remote_user, const char *remote_host)
{
- if (remote_host && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RHOST, remote_host)))
+ int pam_retval;
+
+ if (remote_host != NULL)
{
- log("PAM setup failed.");
- eat_packets_and_disconnect(username);
+ debug("PAM setting rhost to \"%.200s\"", remote_host);
+ pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, remote_host);
+ if (pam_retval != PAM_SUCCESS)
+ {
+ log("PAM set rhost failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
+ eat_packets_and_disconnect(username);
+ }
}
-
- if (remote_user && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user)))
+
+ if (remote_user != NULL)
{
- log("PAM setup failed.");
- eat_packets_and_disconnect(username);
+ debug("PAM setting ruser to \"%.200s\"", remote_user);
+ pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user);
+ if (pam_retval != PAM_SUCCESS)
+ {
+ log("PAM set ruser failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
+ eat_packets_and_disconnect(username);
+ }
}
-
- if (PAM_SUCCESS != pam_acct_mgmt((pam_handle_t *)pamh, 0))
+
+ pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0);
+ if (pam_retval != PAM_SUCCESS)
{
- log("PAM rejected by account configuration.");
+ log("PAM rejected by account configuration: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
eat_packets_and_disconnect(username);
}
- if (PAM_SUCCESS != pam_open_session((pam_handle_t *)pamh, 0))
+ pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
+ if (pam_retval != PAM_SUCCESS)
{
- log("PAM session setup failed.");
+ log("PAM session setup failed: %.200s", pam_strerror((pam_handle_t *)pamh, pam_retval));
eat_packets_and_disconnect(username);
}
}
if (pamh != NULL)
{
+ debug("Closing PAM session.");
retval = pam_close_session((pam_handle_t *)pamh, 0);
+ debug("Terminating PAM library.");
if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
log("Cannot release PAM authentication.");
if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0)
{
/* Private key has bigger modulus. */
- assert(BN_num_bits(sensitive_data.private_key->n) >=
- BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED);
+ if (BN_num_bits(sensitive_data.private_key->n) <
+ BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) {
+ fatal("do_connection: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
+ BN_num_bits(sensitive_data.private_key->n),
+ BN_num_bits(sensitive_data.host_key->n),
+ SSH_KEY_BITS_RESERVED);
+ }
+
rsa_private_decrypt(session_key_int, session_key_int,
sensitive_data.private_key);
rsa_private_decrypt(session_key_int, session_key_int,
else
{
/* Host key has bigger modulus (or they are equal). */
- assert(BN_num_bits(sensitive_data.host_key->n) >=
- BN_num_bits(sensitive_data.private_key->n) +
- SSH_KEY_BITS_RESERVED);
+ if (BN_num_bits(sensitive_data.host_key->n) <
+ BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) {
+ fatal("do_connection: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d",
+ BN_num_bits(sensitive_data.host_key->n),
+ BN_num_bits(sensitive_data.private_key->n),
+ SSH_KEY_BITS_RESERVED);
+ }
rsa_private_decrypt(session_key_int, session_key_int,
sensitive_data.host_key);
rsa_private_decrypt(session_key_int, session_key_int,
least significant 256 bits of the integer; the first byte of the
key is in the highest bits. */
BN_mask_bits(session_key_int, sizeof(session_key) * 8);
- assert(BN_num_bytes(session_key_int) == sizeof(session_key));
+ if (BN_num_bytes(session_key_int) != sizeof(session_key)){
+ fatal("do_connection: session_key_int %d != sizeof(session_key) %d",
+ BN_num_bytes(session_key_int), sizeof(session_key));
+ }
BN_bn2bin(session_key_int, session_key);
/* Xor the first 16 bytes of the session key with the session id. */
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()) {
pw = &pwcopy;
#ifdef HAVE_LIBPAM
- if (PAM_SUCCESS != pam_start("sshd", pw->pw_name, &conv, (pam_handle_t**)&pamh))
+ 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)
{
- packet_start(SSH_SMSG_FAILURE);
- packet_send();
- packet_write_wait();
- packet_disconnect("PAM initialisation failed.");
+ 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);
+ fatal_add_cleanup(&pam_cleanup_proc, NULL);
#endif
/* If we are not running as root, the user must have the same uid as the
int dlen;
char *token_string = packet_get_string(&dlen);
packet_integrity_check(plen, 4 + dlen, type);
- if (!auth_afs_token(user, pw->pw_uid, token_string))
+ if (!auth_afs_token(pw, token_string))
debug("AFS token REFUSED for %s", user);
xfree(token_string);
continue;
#ifdef HAVE_LIBPAM
pampasswd = password;
-
- if (PAM_SUCCESS == pam_authenticate((pam_handle_t *)pamh, 0))
+
+ pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
+ if (pam_retval == PAM_SUCCESS)
{
- log("PAM Password authentication accepted for %.100s.", user);
+ log("PAM Password authentication accepted for \"%.100s\"", user);
authenticated = 1;
break;
} else
{
- log("PAM Password authentication for %.100s failed.", user);
+ log("PAM Password authentication for \"%.100s\" failed: %s",
+ user, pam_strerror((pam_handle_t *)pamh, pam_retval));
break;
}
#else /* HAVE_LIBPAM */
if (authenticated)
break;
- /* Send a message indicating that the authentication attempt failed. */
- packet_start(SSH_SMSG_FAILURE);
- packet_send();
- packet_write_wait();
-
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();
}
/* 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.", forced_command);
+ log("Root login accepted for forced command.");
else
packet_disconnect("ROOT LOGIN REFUSED FROM %.200s",
get_canonical_hostname());
packet_send_debug(skeyinfo);
}
#endif /* SKEY */
- /* Send failure. This should be indistinguishable from a failed
- authentication. */
- packet_start(SSH_SMSG_FAILURE);
- packet_send();
- packet_write_wait();
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();
}
/*NOTREACHED*/
abort();
/* Check if .hushlogin exists. */
snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
quiet_login = stat(line, &st) >= 0;
-
+
+#ifdef HAVE_LIBPAM
+ /* output the results of the pamconv() */
+ if (!quiet_login && pamconv_msg != NULL)
+ fprintf(stderr, pamconv_msg);
+#endif
+
/* If the user has logged in before, display the time of last login.
However, don't display anything extra if a command has been
specified (so that ssh can be used to execute commands on a remote
struct stat st;
char *argv[10];
+#ifndef HAVE_LIBPAM /* pam_nologin handles this */
/* Check /etc/nologin. */
f = fopen("/etc/nologin", "r");
if (f)
if (pw->pw_uid != 0)
exit(254);
}
+#endif
/* Set uid, gid, and groups. */
/* Login(1) does this as well, and it needs uid 0 for the "-h" switch,
{
char *equal_sign, var_name[256], var_val[256];
long this_var;
- char **pam_env = pam_getenvlist(pamh);
+ char **pam_env = pam_getenvlist((pam_handle_t *)pamh);
for(this_var = 0; pam_env && pam_env[this_var]; this_var++)
{
- if(strlen(pam_env[this_var]) < sizeof(var_name))
+ if(strlen(pam_env[this_var]) < (sizeof(var_name) - 1))
if((equal_sign = strstr(pam_env[this_var], "=")) != NULL)
{
memset(var_name, 0, sizeof(var_name));
if (auth_get_socket_name() != NULL)
child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
auth_get_socket_name());
-
+
/* Read $HOME/.ssh/environment. */
if(!options.use_login) {
snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);
}
}
}
+
/* Start the shell. Set initial character to '-'. */
buf[0] = '-';
strncpy(buf + 1, cp, sizeof(buf) - 1);
} else {
/* Launch login(1). */
- execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL);
+ execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(), "-p", "-f", "--", pw->pw_name, NULL);
/* Login couldn't be executed, die. */