static void
privsep_preauth_child(void)
{
	u_int32_t rand[256];
	gid_t gidset[2];
	struct passwd *pw;
	int i;

	/* Enable challenge-response authentication for privilege separation */
	privsep_challenge_enable();

	for (i = 0; i < 256; i++)
		rand[i] = arc4random();
	RAND_seed(rand, sizeof(rand));

	/* Demote the private keys to public keys. */
	demote_sensitive_data();

	if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
		fatal("Privilege separation user %s does not exist",
		    SSH_PRIVSEP_USER);
	memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
	endpwent();

	/* Change our root directory*/
	if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
		fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
		    strerror(errno));
	if (chdir("/") == -1)
		fatal("chdir(\"/\"): %s", strerror(errno));

	/* Drop our privileges */
	debug3("privsep user:group %u:%u", (u_int)pw->pw_uid,
	    (u_int)pw->pw_gid);
#if 0
	/* XXX not ready, to heavy after chroot */
	do_setusercontext(pw);
#else
	gidset[0] = pw->pw_gid;
	if (setgid(pw->pw_gid) < 0)
		fatal("setgid failed for %u", pw->pw_gid );
	if (setgroups(1, gidset) < 0)
		fatal("setgroups: %.100s", strerror(errno));
	permanently_set_uid(pw);
#endif
}
Exemplo n.º 2
0
static void
privsep_postauth(Authctxt *authctxt)
{
#ifdef DISABLE_FD_PASSING
	if (1) {
#else
	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;
	}

	/* New socket pair */
	monitor_reinit(pmonitor);

	pmonitor->m_pid = fork();
	if (pmonitor->m_pid == -1)
		fatal("fork of unprivileged child failed");
	else if (pmonitor->m_pid != 0) {
		debug2("User child is on pid %ld", (long)pmonitor->m_pid);
		close(pmonitor->m_recvfd);
		buffer_clear(&loginmsg);
		monitor_child_postauth(pmonitor);

		/* NEVERREACHED */
		exit(0);
	}

	close(pmonitor->m_sendfd);

	/* Demote the private keys to public keys. */
	demote_sensitive_data();

	/* Drop privileges */
	do_setusercontext(authctxt->pw);

	/* It is safe now to apply the key state */
	monitor_apply_keystate(pmonitor);
}

static char *
list_hostkey_types(void)
{
	Buffer b;
	const char *p;
	char *ret;
	int i;

	buffer_init(&b);
	for (i = 0; i < options.num_host_key_files; i++) {
		Key *key = sensitive_data.host_keys[i];
		if (key == NULL)
			continue;
		switch (key->type) {
		case KEY_RSA:
		case KEY_DSA:
			if (buffer_len(&b) > 0)
				buffer_append(&b, ",", 1);
			p = key_ssh_name(key);
			buffer_append(&b, p, strlen(p));
			break;
		}
	}
	buffer_append(&b, "\0", 1);
	ret = xstrdup(buffer_ptr(&b));
	buffer_free(&b);
	debug("list_hostkey_types: %s", ret);
	return ret;
}