summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c87
1 files changed, 43 insertions, 44 deletions
diff --git a/sshd.c b/sshd.c
index 010a2c38ab95..51a1aaf6ec86 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.485 2017/03/15 03:52:30 deraadt Exp $ */
+/* $OpenBSD: sshd.c,v 1.492 2017/09/12 06:32:07 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -88,7 +88,6 @@
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
-#include "rsa.h"
#include "sshpty.h"
#include "packet.h"
#include "log.h"
@@ -195,10 +194,10 @@ int have_agent = 0;
* not very useful. Currently, memory locking is not implemented.
*/
struct {
- Key **host_keys; /* all private host keys */
- Key **host_pubkeys; /* all public host keys */
- Key **host_certificates; /* all public host certificates */
- int have_ssh2_key;
+ struct sshkey **host_keys; /* all private host keys */
+ struct sshkey **host_pubkeys; /* all public host keys */
+ struct sshkey **host_certificates; /* all public host certificates */
+ int have_ssh2_key;
} sensitive_data;
/* This is set to true when a signal is received. */
@@ -223,6 +222,7 @@ int startup_pipe; /* in child */
int use_privsep = -1;
struct monitor *pmonitor = NULL;
int privsep_is_preauth = 1;
+static int privsep_chroot = 1;
/* global authentication context */
Authctxt *the_authctxt = NULL;
@@ -449,10 +449,8 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
chop(server_version_string);
debug("Local version string %.200s", server_version_string);
- if (remote_major == 2 ||
- (remote_major == 1 && remote_minor == 99)) {
- enable_compat20();
- } else {
+ if (remote_major != 2 ||
+ (remote_major == 1 && remote_minor != 99)) {
s = "Protocol major versions differ.\n";
(void) atomicio(vwrite, sock_out, s, strlen(s));
close(sock_in);
@@ -487,7 +485,7 @@ destroy_sensitive_data(void)
void
demote_sensitive_data(void)
{
- Key *tmp;
+ struct sshkey *tmp;
int i;
for (i = 0; i < options.num_host_key_files; i++) {
@@ -541,7 +539,7 @@ privsep_preauth_child(void)
demote_sensitive_data();
/* Demote the child */
- if (getuid() == 0 || geteuid() == 0) {
+ if (privsep_chroot) {
/* Change our root directory */
if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
@@ -650,6 +648,7 @@ privsep_postauth(Authctxt *authctxt)
else if (pmonitor->m_pid != 0) {
verbose("User child is on pid %ld", (long)pmonitor->m_pid);
buffer_clear(&loginmsg);
+ monitor_clear_keystate(pmonitor);
monitor_child_postauth(pmonitor);
/* NEVERREACHED */
@@ -687,7 +686,7 @@ list_hostkey_types(void)
const char *p;
char *ret;
int i;
- Key *key;
+ struct sshkey *key;
buffer_init(&b);
for (i = 0; i < options.num_host_key_files; i++) {
@@ -743,11 +742,11 @@ list_hostkey_types(void)
return ret;
}
-static Key *
+static struct sshkey *
get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
{
int i;
- Key *key;
+ struct sshkey *key;
for (i = 0; i < options.num_host_key_files; i++) {
switch (type) {
@@ -771,19 +770,19 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
return NULL;
}
-Key *
+struct sshkey *
get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
{
return get_hostkey_by_type(type, nid, 0, ssh);
}
-Key *
+struct sshkey *
get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
{
return get_hostkey_by_type(type, nid, 1, ssh);
}
-Key *
+struct sshkey *
get_hostkey_by_index(int ind)
{
if (ind < 0 || ind >= options.num_host_key_files)
@@ -791,7 +790,7 @@ get_hostkey_by_index(int ind)
return (sensitive_data.host_keys[ind]);
}
-Key *
+struct sshkey *
get_hostkey_public_by_index(int ind, struct ssh *ssh)
{
if (ind < 0 || ind >= options.num_host_key_files)
@@ -800,7 +799,7 @@ get_hostkey_public_by_index(int ind, struct ssh *ssh)
}
int
-get_hostkey_index(Key *key, int compare, struct ssh *ssh)
+get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh)
{
int i;
@@ -1367,8 +1366,8 @@ main(int ac, char **av)
u_int n;
u_int64_t ibytes, obytes;
mode_t new_umask;
- Key *key;
- Key *pubkey;
+ struct sshkey *key;
+ struct sshkey *pubkey;
int keytype;
Authctxt *authctxt;
struct connection_info *connection_info = get_connection_info(0, 0);
@@ -1622,9 +1621,6 @@ main(int ac, char **av)
"enabled authentication methods");
}
- /* set default channel AF */
- channel_set_af(options.address_family);
-
/* Check that there are no remaining arguments. */
if (optind < ac) {
fprintf(stderr, "Extra argument %s.\n", av[optind]);
@@ -1640,8 +1636,9 @@ main(int ac, char **av)
);
/* Store privilege separation user for later use if required. */
+ privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0);
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
- if (use_privsep || options.kerberos_authentication)
+ if (privsep_chroot || options.kerberos_authentication)
fatal("Privilege separation user %s does not exist",
SSH_PRIVSEP_USER);
} else {
@@ -1655,9 +1652,9 @@ main(int ac, char **av)
/* load host keys */
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
- sizeof(Key *));
+ sizeof(struct sshkey *));
sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
- sizeof(Key *));
+ sizeof(struct sshkey *));
if (options.host_key_agent) {
if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
@@ -1676,14 +1673,6 @@ main(int ac, char **av)
key = key_load_private(options.host_key_files[i], "", NULL);
pubkey = key_load_public(options.host_key_files[i], NULL);
- if ((pubkey != NULL && pubkey->type == KEY_RSA1) ||
- (key != NULL && key->type == KEY_RSA1)) {
- verbose("Ignoring RSA1 key %s",
- options.host_key_files[i]);
- key_free(key);
- key_free(pubkey);
- continue;
- }
if (pubkey == NULL && key != NULL)
pubkey = key_demote(key);
sensitive_data.host_keys[i] = key;
@@ -1729,7 +1718,7 @@ main(int ac, char **av)
* indices to the public keys that they relate to.
*/
sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
- sizeof(Key *));
+ sizeof(struct sshkey *));
for (i = 0; i < options.num_host_key_files; i++)
sensitive_data.host_certificates[i] = NULL;
@@ -1767,7 +1756,7 @@ main(int ac, char **av)
key_type(key));
}
- if (use_privsep) {
+ if (privsep_chroot) {
struct stat st;
if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
@@ -1963,8 +1952,14 @@ main(int ac, char **av)
packet_set_connection(sock_in, sock_out);
packet_set_server();
ssh = active_state; /* XXX */
+
check_ip_options(ssh);
+ /* Prepare the channels layer */
+ channel_init_channels(ssh);
+ channel_set_af(ssh, options.address_family);
+ process_permitopen(ssh, &options);
+
/* Set SO_KEEPALIVE if requested. */
if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
@@ -2040,6 +2035,7 @@ main(int ac, char **av)
*/
if (use_privsep) {
mm_send_keystate(pmonitor);
+ packet_clear_keys();
exit(0);
}
@@ -2087,10 +2083,10 @@ main(int ac, char **av)
options.client_alive_count_max);
/* Try to send all our hostkeys to the client */
- notify_hostkeys(active_state);
+ notify_hostkeys(ssh);
/* Start session. */
- do_authenticated(authctxt);
+ do_authenticated(ssh, authctxt);
/* The connection has been terminated. */
packet_get_bytes(&ibytes, &obytes);
@@ -2117,8 +2113,9 @@ main(int ac, char **av)
}
int
-sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen,
- const u_char *data, size_t dlen, const char *alg, u_int flag)
+sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey,
+ u_char **signature, size_t *slen, const u_char *data, size_t dlen,
+ const char *alg, u_int flag)
{
int r;
u_int xxx_slen, xxx_dlen = dlen;
@@ -2198,7 +2195,7 @@ do_ssh2_kex(void)
kex->host_key_index=&get_hostkey_index;
kex->sign = sshd_hostkey_sign;
- dispatch_run(DISPATCH_BLOCK, &kex->done, active_state);
+ ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
session_id2 = kex->session_id;
session_id2_len = kex->session_id_len;
@@ -2217,8 +2214,10 @@ do_ssh2_kex(void)
void
cleanup_exit(int i)
{
+ struct ssh *ssh = active_state; /* XXX */
+
if (the_authctxt) {
- do_cleanup(the_authctxt);
+ do_cleanup(ssh, the_authctxt);
if (use_privsep && privsep_is_preauth &&
pmonitor != NULL && pmonitor->m_pid > 1) {
debug("Killing privsep child %d", pmonitor->m_pid);