*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.312 2005/07/25 11:59:40 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.318 2005/12/24 02:27:41 djm Exp $");
#include <openssl/dh.h>
#include <openssl/bn.h>
#include "monitor_wrap.h"
#include "monitor_fdpass.h"
-#ifdef GSSAPI
-#include "ssh-gss.h"
+#ifdef USE_SECURITY_SESSION_API
+#include <Security/AuthSession.h>
#endif
-#ifdef GSSAPI
-#include <openssl/md5.h>
-#include "bufaux.h"
-#endif /* GSSAPI */
-
#ifdef LIBWRAP
#include <tcpd.h>
#include <syslog.h>
major = PROTOCOL_MAJOR_1;
minor = PROTOCOL_MINOR_1;
}
- snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
+ snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE);
server_version_string = xstrdup(buf);
/* Send our protocol version identification. */
if (authctxt->pw->pw_uid == 0 || options.use_login) {
#endif
/* File descriptor passing is broken or root login */
- monitor_apply_keystate(pmonitor);
use_privsep = 0;
- return;
- }
-
- /* Authentication complete */
- alarm(0);
- if (startup_pipe != -1) {
- close(startup_pipe);
- startup_pipe = -1;
+ goto skip;
}
/* New socket pair */
/* Drop privileges */
do_setusercontext(authctxt->pw);
+ skip:
/* It is safe now to apply the key state */
monitor_apply_keystate(pmonitor);
* bignum iqmp "
* bignum p "
* bignum q "
+ * string rngseed (only if OpenSSL is not self-seeded)
*/
buffer_init(&m);
buffer_put_cstring(&m, buffer_ptr(conf));
} else
buffer_put_int(&m, 0);
+#ifndef OPENSSL_PRNG_ONLY
+ rexec_send_rng_seed(&m);
+#endif
+
if (ssh_msg_send(fd, 0, &m) == -1)
fatal("%s: ssh_msg_send failed", __func__);
rsa_generate_additional_parameters(
sensitive_data.server_key->rsa);
}
+
+#ifndef OPENSSL_PRNG_ONLY
+ rexec_recv_rng_seed(&m);
+#endif
+
buffer_free(&m);
debug3("%s: done", __func__);
if (geteuid() == 0 && setgroups(0, NULL) == -1)
debug("setgroups(): %.200s", strerror(errno));
+ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
+ sanitise_stdfd();
+
/* Initialize configuration options to their default values. */
initialize_server_options(&options);
drop_cray_privs();
#endif
- seed_rng();
-
sensitive_data.server_key = NULL;
sensitive_data.ssh1_host_key = NULL;
sensitive_data.have_ssh1_key = 0;
if (!rexec_flag)
buffer_free(&cfg);
+ seed_rng();
+
/* Fill in default values for those options not explicitly set. */
fill_default_server_options(&options);
debug("get_remote_port failed");
cleanup_exit(255);
}
- remote_ip = get_remote_ipaddr();
+
+ /*
+ * We use get_canonical_hostname with usedns = 0 instead of
+ * get_remote_ipaddr here so IP options will be checked.
+ */
+ remote_ip = get_canonical_hostname(0);
#ifdef SSH_AUDIT_EVENTS
audit_connection_from(remote_ip, remote_port);
/* Log the connection. */
verbose("Connection from %.500s port %d", remote_ip, remote_port);
+#ifdef USE_SECURITY_SESSION_API
+ /*
+ * Create a new security session for use by the new user login if
+ * the current session is the root session or we are not launched
+ * by inetd (eg: debugging mode or server mode). We do not
+ * necessarily need to create a session if we are launched from
+ * inetd because Panther xinetd will create a session for us.
+ *
+ * The only case where this logic will fail is if there is an
+ * inetd running in a non-root session which is not creating
+ * new sessions for us. Then all the users will end up in the
+ * same session (bad).
+ *
+ * When the client exits, the session will be destroyed for us
+ * automatically.
+ *
+ * We must create the session before any credentials are stored
+ * (including AFS pags, which happens a few lines below).
+ */
+ {
+ OSStatus err = 0;
+ SecuritySessionId sid = 0;
+ SessionAttributeBits sattrs = 0;
+
+ err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
+ if (err)
+ error("SessionGetInfo() failed with error %.8X",
+ (unsigned) err);
+ else
+ debug("Current Session ID is %.8X / Session Attributes are %.8X",
+ (unsigned) sid, (unsigned) sattrs);
+
+ if (inetd_flag && !(sattrs & sessionIsRoot))
+ debug("Running in inetd mode in a non-root session... "
+ "assuming inetd created the session for us.");
+ else {
+ debug("Creating new security session...");
+ err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
+ if (err)
+ error("SessionCreate() failed with error %.8X",
+ (unsigned) err);
+
+ err = SessionGetInfo(callerSecuritySession, &sid,
+ &sattrs);
+ if (err)
+ error("SessionGetInfo() failed with error %.8X",
+ (unsigned) err);
+ else
+ debug("New Session ID is %.8X / Session Attributes are %.8X",
+ (unsigned) sid, (unsigned) sattrs);
+ }
+ }
+#endif
+
/*
- * We don\'t want to listen forever unless the other side
+ * We don't want to listen forever unless the other side
* successfully authenticates itself. So we set up an alarm which is
* cleared after successful authentication. A limit of zero
- * indicates no limit. Note that we don\'t set the alarm in debugging
+ * indicates no limit. Note that we don't set the alarm in debugging
* mode; it is just annoying to have the server exit just when you
* are about to discover the bug.
*/
}
authenticated:
+ /*
+ * Cancel the alarm we set to limit the time taken for
+ * authentication.
+ */
+ alarm(0);
+ signal(SIGALRM, SIG_DFL);
+ if (startup_pipe != -1) {
+ close(startup_pipe);
+ startup_pipe = -1;
+ }
+
#ifdef SSH_AUDIT_EVENTS
audit_event(SSH_AUTH_SUCCESS);
#endif
if (options.ciphers != NULL) {
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
+ } else if (options.none_enabled == 1) {
+ debug ("WARNING: None cipher enabled");
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
}
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
+ /* start key exchange */
+
#ifdef GSSAPI
- {
+ {
char *orig;
char *gss = NULL;
char *newstr = NULL;
- orig = myproposal[PROPOSAL_KEX_ALGS];
-
- /* If we don't have a host key, then all of the algorithms
- * currently in myproposal are useless */
- if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])==0)
- orig= NULL;
-
- if (options.gss_keyex)
- gss = ssh_gssapi_server_mechanisms();
- else
- gss = NULL;
-
+ orig = myproposal[PROPOSAL_KEX_ALGS];
+
+ /*
+ * If we don't have a host key, then there's no point advertising
+ * the other key exchange algorithms
+ */
+
+ if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
+ orig = NULL;
+
+ if (options.gss_keyex)
+ gss = ssh_gssapi_server_mechanisms();
+ else
+ gss = NULL;
+
if (gss && orig) {
- int len = strlen(orig) + strlen(gss) +2;
- newstr=xmalloc(len);
- snprintf(newstr,len,"%s,%s",gss,orig);
+ int len = strlen(orig) + strlen(gss) + 2;
+ newstr = xmalloc(len);
+ snprintf(newstr, len, "%s,%s", gss, orig);
} else if (gss) {
- newstr=gss;
+ newstr = gss;
} else if (orig) {
- newstr=orig;
- }
- /* If we've got GSSAPI mechanisms, then we've also got the 'null'
- host key algorithm, but we're not allowed to advertise it, unless
- its the only host key algorithm we're supporting */
- if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) {
- myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]="null";
+ newstr = orig;
}
+ /*
+ * If we've got GSSAPI mechanisms, then we've got the 'null' host
+ * key alg, but we can't tell people about it unless its the only
+ * host key algorithm we support
+ */
+ if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
+
if (newstr)
- myproposal[PROPOSAL_KEX_ALGS]=newstr;
+ myproposal[PROPOSAL_KEX_ALGS] = newstr;
else
fatal("No supported key exchange algorithms");
- }
+ }
#endif
- /* start key exchange */
- kex = kex_setup(myproposal);
- kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
+ /* start key exchange */
+ kex = kex_setup(myproposal);
+ kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
#ifdef GSSAPI
kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
+ kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
#endif
- kex->server = 1;
- kex->client_version_string=client_version_string;
- kex->server_version_string=server_version_string;
+ kex->server = 1;
+ kex->client_version_string=client_version_string;
+ kex->server_version_string=server_version_string;
kex->load_host_key=&get_hostkey_by_type;
kex->host_key_index=&get_hostkey_index;