⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sshd.c

📁 C++编写
💻 C
📖 第 1 页 / 共 4 页
字号:
			enable_compat13();		}		break;	case 2:		if (options.protocol & SSH_PROTO_2) {			enable_compat20();			break;		}		/* FALLTHROUGH */	default:		mismatch = 1;		break;	}	chop(server_version_string);	debug("Local version string %.200s", server_version_string);	if (mismatch) {		s = "Protocol major versions differ.\n";		(void) atomicio(write, sock_out, s, strlen(s));		close(sock_in);		close(sock_out);		log("Protocol major versions differ for %s: %.200s vs. %.200s",		    get_remote_ipaddr(),		    server_version_string, client_version_string);		fatal_cleanup();	}}/* Destroy the host and server keys.  They will no longer be needed. */voiddestroy_sensitive_data(void){	int i;	if (sensitive_data.server_key) {		key_free(sensitive_data.server_key);		sensitive_data.server_key = NULL;	}	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;		}	}	sensitive_data.ssh1_host_key = NULL;	memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH);}/* Demote private to public keys for network child */voiddemote_sensitive_data(void){	Key *tmp;	int i;	if (sensitive_data.server_key) {		tmp = key_demote(sensitive_data.server_key);		key_free(sensitive_data.server_key);		sensitive_data.server_key = tmp;	}	for (i = 0; i < options.num_host_key_files; i++) {		if (sensitive_data.host_keys[i]) {			tmp = key_demote(sensitive_data.host_keys[i]);			key_free(sensitive_data.host_keys[i]);			sensitive_data.host_keys[i] = tmp;			if (tmp->type == KEY_RSA1)				sensitive_data.ssh1_host_key = tmp;		}	}	/* We do not clear ssh1_host key and cookie.  XXX - Okay Niels? */}static voidprivsep_preauth_child(void){	u_int32_t rnd[256];	gid_t gidset[1];	struct passwd *pw;	int i;	/* Enable challenge-response authentication for privilege separation */	privsep_challenge_enable();	for (i = 0; i < 256; i++)		rnd[i] = arc4random();	RAND_seed(rnd, sizeof(rnd));	/* 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}static Authctxt *privsep_preauth(void){	Authctxt *authctxt = NULL;	int status;	pid_t pid;	/* Set up unprivileged child process to deal with network data */	pmonitor = monitor_init();	/* Store a pointer to the kex for later rekeying */	pmonitor->m_pkex = &xxx_kex;	pid = fork();	if (pid == -1) {		fatal("fork of unprivileged child failed");	} else if (pid != 0) {		fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);		debug2("Network child is on pid %ld", (long)pid);		close(pmonitor->m_recvfd);		authctxt = monitor_child_preauth(pmonitor);		close(pmonitor->m_sendfd);		/* Sync memory */		monitor_sync(pmonitor);		/* Wait for the child's exit status */		while (waitpid(pid, &status, 0) < 0)			if (errno != EINTR)				break;		/* Reinstall, since the child has finished */		fatal_add_cleanup((void (*) (void *)) packet_close, NULL);		return (authctxt);	} else {		/* child */		close(pmonitor->m_sendfd);		/* Demote the child */		if (getuid() == 0 || geteuid() == 0)			privsep_preauth_child();		setproctitle("%s", "[net]");	}	return (NULL);}static voidprivsep_postauth(Authctxt *authctxt){	extern Authctxt *x_authctxt;	/* XXX - Remote port forwarding */	x_authctxt = authctxt;	if (authctxt->pw->pw_uid == 0 || options.use_login) {		/* 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) {		fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);		debug2("User child is on pid %ld", (long)pmonitor->m_pid);		close(pmonitor->m_recvfd);		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;	char *p;	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);	p = xstrdup(buffer_ptr(&b));	buffer_free(&b);	debug("list_hostkey_types: %s", p);	return p;}Key *get_hostkey_by_type(int type){	int i;	for (i = 0; i < options.num_host_key_files; i++) {		Key *key = sensitive_data.host_keys[i];		if (key != NULL && key->type == type)			return key;	}	return NULL;}Key *get_hostkey_by_index(int ind){	if (ind < 0 || ind >= options.num_host_key_files)		return (NULL);	return (sensitive_data.host_keys[ind]);}intget_hostkey_index(Key *key){	int i;	for (i = 0; i < options.num_host_key_files; i++) {		if (key == sensitive_data.host_keys[i])			return (i);	}	return (-1);}/* * returns 1 if connection should be dropped, 0 otherwise. * dropping starts at connection #max_startups_begin with a probability * of (max_startups_rate/100). the probability increases linearly until * all connections are dropped for startups > max_startups */static intdrop_connection(int startups){	double p, r;	if (startups < options.max_startups_begin)		return 0;	if (startups >= options.max_startups)		return 1;	if (options.max_startups_rate == 100)		return 1;	p  = 100 - options.max_startups_rate;	p *= startups - options.max_startups_begin;	p /= (double) (options.max_startups - options.max_startups_begin);	p += options.max_startups_rate;	p /= 100.0;	r = arc4random() / (double) UINT_MAX;	debug("drop_connection: p %g, r %g", p, r);	return (r < p) ? 1 : 0;}static voidusage(void){	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", _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, "  -t         Only test configuration file and keys\n");	fprintf(stderr, "  -q         Quiet (no logging)\n");	fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");	fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\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",	    _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");	fprintf(stderr, "  -o option  Process the option as if it was read from a configuration file.\n");	exit(1);}/* * Main program for the daemon. */intmain(int ac, char **av){	extern char *optarg;	extern int optind;	int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1;	pid_t pid;	socklen_t fromlen;	fd_set *fdset;	struct sockaddr_storage from;	const char *remote_ip;	int remote_port;	FILE *f;	struct addrinfo *ai;	char ntop[NI_MAXHOST], strport[NI_MAXSERV];	int listen_sock, maxfd;	int startup_p[2];	int startups = 0;	Authctxt *authctxt;	Key *key;	int ret, key_used = 0;	/* Save argv. */	saved_argv = av;	/* Initialize configuration options to their default values. */	initialize_server_options(&options);	/* Parse command-line arguments. */	while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) {		switch (opt) {		case '4':			IPv4or6 = AF_INET;			break;		case '6':			IPv4or6 = AF_INET6;			break;		case 'f':			config_file_name = optarg;			break;		case 'd':			if (0 == debug_flag) {				debug_flag = 1;				options.log_level = SYSLOG_LEVEL_DEBUG1;			} else if (options.log_level < SYSLOG_LEVEL_DEBUG3) {				options.log_level++;			} else {				fprintf(stderr, "Too high debugging level.\n");				exit(1);			}			break;		case 'D':			no_daemon_flag = 1;			break;		case 'e':			log_stderr = 1;			break;		case 'i':			inetd_flag = 1;			break;		case 'Q':			/* ignored */			break;		case 'q':			options.log_level = SYSLOG_LEVEL_QUIET;			break;		case 'b':			options.server_key_bits = atoi(optarg);			break;		case 'p':			options.ports_from_cmdline = 1;			if (options.num_ports >= MAX_PORTS) {				fprintf(stderr, "too many ports.\n");				exit(1);			}			options.ports[options.num_ports++] = a2port(optarg);			if (options.ports[options.num_ports-1] == 0) {				fprintf(stderr, "Bad port number.\n");				exit(1);			}			break;		case 'g':			if ((options.login_grace_time = convtime(optarg)) == -1) {				fprintf(stderr, "Invalid login grace time.\n");				exit(1);			}			break;		case 'k':			if ((options.key_regeneration_time = convtime(optarg)) == -1) {				fprintf(stderr, "Invalid key regeneration interval.\n");				exit(1);			}			break;		case 'h':			if (options.num_host_key_files >= MAX_HOSTKEYS) {				fprintf(stderr, "too many host keys.\n");				exit(1);			}			options.host_key_files[options.num_host_key_files++] = optarg;			break;		case 'V':			client_version_string = optarg;			/* only makes sense with inetd_flag, i.e. no listen() */			inetd_flag = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -