#include "uidswap.h"
#include "compat.h"
+#ifdef HAVE_MAILLOCK_H
+# include <maillock.h>
+#endif
+
#ifdef LIBWRAP
#include <tcpd.h>
#include <syslog.h>
static int pamconv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
- int count = 0;
- struct pam_response *reply = NULL;
+ struct pam_response *reply;
+ int count;
+ size_t msg_len;
+ char *p;
/* PAM will free this later */
reply = malloc(num_msg * sizeof(*reply));
reply[count].resp_retcode = PAM_SUCCESS;
reply[count].resp = xstrdup("");
- if (msg[count]->msg == NULL) break;
+ 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
+
+ msg_len = strlen(msg[count]->msg);
+ if (pamconv_msg)
{
- 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';
+ size_t n = strlen(pamconv_msg);
+ pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2);
+ p = pamconv_msg + n;
}
+ else
+ pamconv_msg = p = xmalloc(msg_len + 2);
+ memcpy(p, msg[count]->msg, msg_len);
+ p[msg_len] = '\n';
+ p[msg_len + 1] = '\0';
break;
case PAM_PROMPT_ECHO_ON:
exit(1);
}
- /* Initialize the log (it is reinitialized below in case we forked). */
-
- if (debug_flag && !inetd_flag)
- log_stderr = 1;
-
- log_init(av0, options.log_level, options.log_facility, log_stderr);
+ /* Force logging to stderr while loading the private host key
+ unless started from inetd */
+ log_init(av0, options.log_level, options.log_facility, !inetd_flag);
debug("sshd version %.100s", SSH_VERSION);
sensitive_data.host_key = RSA_new();
+ errno = 0;
/* Load the host key. It must have empty passphrase. */
if (!load_private_key(options.host_key_file, "",
sensitive_data.host_key, &comment))
{
- if (debug_flag)
- fprintf(stderr, "Could not load host key: %s: %s\n",
- options.host_key_file, strerror(errno));
- else
- {
- int err = errno;
- /* force logging */
- log_init(av0, SYSLOG_LEVEL_DEBUG, options.log_facility, log_stderr);
- error("Could not load host key: %.200s: %.100s",
- options.host_key_file, strerror(err));
- }
+ error("Could not load host key: %.200s: %.100s",
+ options.host_key_file, strerror(errno));
exit(1);
}
xfree(comment);
+ /* Initialize the log (it is reinitialized below in case we forked). */
+ if (debug_flag && !inetd_flag)
+ log_stderr = 1;
+ log_init(av0, options.log_level, options.log_facility, log_stderr);
+
/* If not in debugging mode, and not started from inetd, disconnect from
the controlling terminal, and fork. The original process exits. */
if (!debug_flag && !inetd_flag)
/* Compute session id for this session. */
compute_session_id(session_id, check_bytes,
- BN_num_bits(sensitive_data.host_key->n),
sensitive_data.host_key->n,
- BN_num_bits(sensitive_data.private_key->n),
sensitive_data.private_key->n);
/* Extract session key from the decrypted integer. The key is in the
/* Set the session key. From this on all communications will be
encrypted. */
- packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH,
- cipher_type, 0);
+ packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type);
/* Destroy our copy of the session key. It is no longer needed. */
memset(session_key, 0, sizeof(session_key));
do_authloop(struct passwd *pw)
{
int authentication_failures = 0;
- unsigned int client_host_key_bits;
+ unsigned int bits;
BIGNUM *client_host_key_e, *client_host_key_n;
BIGNUM *n;
char *client_user = NULL, *password = NULL;
/* Get the client host key. */
client_host_key_e = BN_new();
client_host_key_n = BN_new();
- client_host_key_bits = packet_get_int();
+ bits = packet_get_int();
packet_get_bignum(client_host_key_e, &elen);
packet_get_bignum(client_host_key_n, &nlen);
-
+
+ if (bits != BN_num_bits(client_host_key_n))
+ error("Warning: keysize mismatch for client_host_key: "
+ "actual %d, announced %d", BN_num_bits(client_host_key_n), bits);
packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
- authenticated = auth_rhosts_rsa(pw, client_user, client_host_key_bits,
+ authenticated = auth_rhosts_rsa(pw, client_user,
client_host_key_e, client_host_key_n);
log("Rhosts authentication %s for %.100s, remote %.100s.",
authenticated ? "accepted" : "failed",
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);
+ BN_clear_free(n);
break;
case SSH_CMSG_AUTH_PASSWORD:
#else /* HAVE_LIBPAM */
/* Try authentication with the password. */
authenticated = auth_password(pw, password);
+ log("Password authentication %s for %.100s.",
+ authenticated ? "accepted" : "failed",
+ pw->pw_name);
memset(password, 0, strlen(password));
xfree(password);