*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.153 2001/01/19 12:45:27 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.163 2001/02/04 23:56:23 deraadt Exp $");
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include <openssl/hmac.h>
+
+#include "ssh.h"
+#include "ssh1.h"
+#include "ssh2.h"
#include "xmalloc.h"
#include "rsa.h"
-#include "ssh.h"
#include "pty.h"
#include "packet.h"
#include "mpaux.h"
+#include "log.h"
#include "servconf.h"
#include "uidswap.h"
#include "compat.h"
#include "buffer.h"
-
-#include "ssh2.h"
-#include <openssl/dh.h>
-#include <openssl/bn.h>
-#include <openssl/hmac.h>
+#include "cipher.h"
#include "kex.h"
-#include <openssl/dsa.h>
-#include <openssl/rsa.h>
#include "key.h"
#include "dh.h"
-
-#include "auth.h"
#include "myproposal.h"
#include "authfile.h"
+#include "pathnames.h"
+#include "atomicio.h"
+#include "canohost.h"
+#include "auth.h"
+#include "misc.h"
#ifdef LIBWRAP
#include <tcpd.h>
ServerOptions options;
/* Name of the server configuration file. */
-char *config_file_name = SERVER_CONFIG_FILE;
+char *config_file_name = _PATH_SERVER_CONFIG_FILE;
/*
* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
key_free(sensitive_data.server_key);
sensitive_data.server_key = NULL;
}
- for(i = 0; i < options.num_host_key_files; i++) {
+ for(i = 0; i < options.num_host_key_files; i++) {
if (sensitive_data.host_keys[i]) {
key_free(sensitive_data.host_keys[i]);
sensitive_data.host_keys[i] = NULL;
int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1;
pid_t pid;
socklen_t fromlen;
- int silent = 0;
fd_set *fdset;
struct sockaddr_storage from;
const char *remote_ip;
inetd_flag = 1;
break;
case 'Q':
- silent = 1;
+ /* ignored */
break;
case 'q':
options.log_level = SYSLOG_LEVEL_QUIET;
fprintf(stderr, "sshd version %s\n", SSH_VERSION);
fprintf(stderr, "Usage: %s [options]\n", __progname);
fprintf(stderr, "Options:\n");
- fprintf(stderr, " -f file Configuration file (default %s)\n", SERVER_CONFIG_FILE);
+ fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
fprintf(stderr, " -d Debugging mode (multiple -d means more debugging)\n");
fprintf(stderr, " -i Started from inetd\n");
fprintf(stderr, " -D Do not fork into daemon mode\n");
fprintf(stderr, " -g seconds Grace period for authentication (default: 600)\n");
fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n");
fprintf(stderr, " -h file File from which to read host key (default: %s)\n",
- HOST_KEY_FILE);
+ _PATH_HOST_KEY_FILE);
fprintf(stderr, " -u len Maximum hostname length for utmp recording\n");
fprintf(stderr, " -4 Use IPv4 only\n");
fprintf(stderr, " -6 Use IPv6 only\n");
log_init(__progname,
options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
- !silent && !inetd_flag);
+ !inetd_flag);
/* Read server configuration options from the configuration file. */
read_server_config(&options, config_file_name);
log("Disabling protocol version 2. Could not load host key");
options.protocol &= ~SSH_PROTO_2;
}
- if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) {
- if (silent == 0)
- fprintf(stderr, "sshd: no hostkeys available -- exiting.\n");
+ if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
log("sshd: no hostkeys available -- exiting.\n");
exit(1);
}
startups++;
break;
}
-
+
/*
* Got connection. Fork a child to handle it, unless
* we are in debugging mode.
{
int i, len;
int plen, slen;
+ int rsafail = 0;
BIGNUM *session_key_int;
u_char session_key[SSH_SESSION_KEY_LENGTH];
u_char cookie[8];
if (options.afs_token_passing)
auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
#endif
- if (options.skey_authentication == 1)
+ if (options.challenge_reponse_authentication == 1)
auth_mask |= 1 << SSH_AUTH_TIS;
if (options.password_authentication)
auth_mask |= 1 << SSH_AUTH_PASSWORD;
* with larger modulus first).
*/
if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) {
- /* Private key has bigger modulus. */
+ /* Server key has bigger modulus. */
if (BN_num_bits(sensitive_data.server_key->rsa->n) <
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
SSH_KEY_BITS_RESERVED);
}
- rsa_private_decrypt(session_key_int, session_key_int,
- sensitive_data.server_key->rsa);
- rsa_private_decrypt(session_key_int, session_key_int,
- sensitive_data.ssh1_host_key->rsa);
+ if (rsa_private_decrypt(session_key_int, session_key_int,
+ sensitive_data.server_key->rsa) <= 0)
+ rsafail++;
+ if (rsa_private_decrypt(session_key_int, session_key_int,
+ sensitive_data.ssh1_host_key->rsa) <= 0)
+ rsafail++;
} else {
/* Host key has bigger modulus (or they are equal). */
if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) <
BN_num_bits(sensitive_data.server_key->rsa->n),
SSH_KEY_BITS_RESERVED);
}
- rsa_private_decrypt(session_key_int, session_key_int,
- sensitive_data.ssh1_host_key->rsa);
- rsa_private_decrypt(session_key_int, session_key_int,
- sensitive_data.server_key->rsa);
+ if (rsa_private_decrypt(session_key_int, session_key_int,
+ sensitive_data.ssh1_host_key->rsa) < 0)
+ rsafail++;
+ if (rsa_private_decrypt(session_key_int, session_key_int,
+ sensitive_data.server_key->rsa) < 0)
+ rsafail++;
}
compute_session_id(session_id, cookie,
* 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);
- len = BN_num_bytes(session_key_int);
- if (len < 0 || len > sizeof(session_key))
- fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d",
- get_remote_ipaddr(),
- len, sizeof(session_key));
- memset(session_key, 0, sizeof(session_key));
- BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len);
-
+ if (!rsafail) {
+ BN_mask_bits(session_key_int, sizeof(session_key) * 8);
+ len = BN_num_bytes(session_key_int);
+ if (len < 0 || len > sizeof(session_key)) {
+ error("do_connection: bad session key len from %s: "
+ "session_key_int %d > sizeof(session_key) %d",
+ get_remote_ipaddr(), len, (int)sizeof(session_key));
+ rsafail++;
+ } else {
+ memset(session_key, 0, sizeof(session_key));
+ BN_bn2bin(session_key_int,
+ session_key + sizeof(session_key) - len);
+ }
+ }
+ if (rsafail) {
+ log("do_connection: generating a fake encryption key");
+ for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
+ if (i % 4 == 0)
+ rand = arc4random();
+ session_key[i] = rand & 0xff;
+ rand >>= 8;
+ }
+ }
/* Destroy the decrypted integer. It is no longer needed. */
BN_clear_free(session_key_int);
fprintf(stderr, "\npub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
- DHparams_print_fp(stderr, dh);
+ DHparams_print_fp(stderr, dh);
#endif
if (!dh_pub_is_valid(dh, dh_client_pub))
packet_disconnect("bad client public DH value");
buffer_free(server_kexinit);
xfree(client_kexinit);
xfree(server_kexinit);
+ BN_free(dh_client_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "hash == ");
for (i = 0; i< 20; i++)
packet_write_wait();
kex_derive_keys(kex, hash, shared_secret);
+ BN_clear_free(shared_secret);
packet_set_kex(kex);
/* have keys, free DH */
fprintf(stderr, "\npub= ");
BN_print_fp(stderr, dh->pub_key);
fprintf(stderr, "\n");
- DHparams_print_fp(stderr, dh);
+ DHparams_print_fp(stderr, dh);
#endif
if (!dh_pub_is_valid(dh, dh_client_pub))
packet_disconnect("bad client public DH value");
buffer_free(server_kexinit);
xfree(client_kexinit);
xfree(server_kexinit);
+ BN_free(dh_client_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "hash == ");
for (i = 0; i< 20; i++)
packet_write_wait();
kex_derive_keys(kex, hash, shared_secret);
+ BN_clear_free(shared_secret);
packet_set_kex(kex);
/* have keys, free DH */