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

📄 sshconnect.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (options.protocol & SSH_PROTO_2) {			enable_compat20();			break;		}		/* FALLTHROUGH */	default:		mismatch = 1;		break;	}	if (mismatch)		fatal("Protocol major versions differ: %d vs. %d",		    (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,		    remote_major);	/* Send our own protocol version identification. */	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",	    compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,	    compat20 ? PROTOCOL_MINOR_2 : minor1,	    SSH_VERSION);	if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))		fatal("write: %.100s", strerror(errno));	client_version_string = xstrdup(buf);	chop(client_version_string);	chop(server_version_string);	debug("Local version string %.100s", client_version_string);}/* defaults to 'no' */static intconfirm(const char *prompt){	const char *msg, *again = "Please type 'yes' or 'no': ";	char *p;	int ret = -1;	if (options.batch_mode)		return 0;	for (msg = prompt;;msg = again) {		p = read_passphrase(msg, RP_ECHO);		if (p == NULL ||		    (p[0] == '\0') || (p[0] == '\n') ||		    strncasecmp(p, "no", 2) == 0)			ret = 0;		if (strncasecmp(p, "yes", 3) == 0)			ret = 1;		if (p)			xfree(p);		if (ret != -1)			return ret;	}}/* * check whether the supplied host key is valid, return -1 if the key * is not valid. the user_hostfile will not be updated if 'readonly' is true. */static intcheck_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,    int readonly, const char *user_hostfile, const char *system_hostfile){	Key *file_key;	char *type = key_type(host_key);	char *ip = NULL;	char hostline[1000], *hostp, *fp;	HostStatus host_status;	HostStatus ip_status;	int local = 0, host_ip_differ = 0;	int salen;	char ntop[NI_MAXHOST];	char msg[1024];	int len, host_line, ip_line;	const char *host_file = NULL, *ip_file = NULL;	/*	 * Force accepting of the host key for loopback/localhost. The	 * problem is that if the home directory is NFS-mounted to multiple	 * machines, localhost will refer to a different machine in each of	 * them, and the user will get bogus HOST_CHANGED warnings.  This	 * essentially disables host authentication for localhost; however,	 * this is probably not a real problem.	 */	/**  hostaddr == 0! */	switch (hostaddr->sa_family) {	case AF_INET:		local = (ntohl(((struct sockaddr_in *)hostaddr)->		   sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;		salen = sizeof(struct sockaddr_in);		break;	case AF_INET6:		local = IN6_IS_ADDR_LOOPBACK(		    &(((struct sockaddr_in6 *)hostaddr)->sin6_addr));		salen = sizeof(struct sockaddr_in6);		break;	default:		local = 0;		salen = sizeof(struct sockaddr_storage);		break;	}	if (options.no_host_authentication_for_localhost == 1 && local &&	    options.host_key_alias == NULL) {		debug("Forcing accepting of host key for "		    "loopback/localhost.");		return 0;	}	/*	 * We don't have the remote ip-address for connections	 * using a proxy command	 */	if (options.proxy_command == NULL) {		if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),		    NULL, 0, NI_NUMERICHOST) != 0)			fatal("check_host_key: getnameinfo failed");		ip = xstrdup(ntop);	} else {		ip = xstrdup("<no hostip for proxy command>");	}	/*	 * Turn off check_host_ip if the connection is to localhost, via proxy	 * command or if we don't have a hostname to compare with	 */	if (options.check_host_ip &&	    (local || strcmp(host, ip) == 0 || options.proxy_command != NULL))		options.check_host_ip = 0;	/*	 * Allow the user to record the key under a different name. This is	 * useful for ssh tunneling over forwarded connections or if you run	 * multiple sshd's on different ports on the same machine.	 */	if (options.host_key_alias != NULL) {		host = options.host_key_alias;		debug("using hostkeyalias: %s", host);	}	/*	 * Store the host key from the known host file in here so that we can	 * compare it with the key for the IP address.	 */	file_key = key_new(host_key->type);	/*	 * Check if the host key is present in the user\'s list of known	 * hosts or in the systemwide list.	 */	host_file = user_hostfile;	host_status = check_host_in_hostfile(host_file, host, host_key,	    file_key, &host_line);	if (host_status == HOST_NEW) {		host_file = system_hostfile;		host_status = check_host_in_hostfile(host_file, host, host_key,		    file_key, &host_line);	}	/*	 * Also perform check for the ip address, skip the check if we are	 * localhost or the hostname was an ip address to begin with	 */	if (options.check_host_ip) {		Key *ip_key = key_new(host_key->type);		ip_file = user_hostfile;		ip_status = check_host_in_hostfile(ip_file, ip, host_key,		    ip_key, &ip_line);		if (ip_status == HOST_NEW) {			ip_file = system_hostfile;			ip_status = check_host_in_hostfile(ip_file, ip,			    host_key, ip_key, &ip_line);		}		if (host_status == HOST_CHANGED &&		    (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))			host_ip_differ = 1;		key_free(ip_key);	} else		ip_status = host_status;	key_free(file_key);	switch (host_status) {	case HOST_OK:		/* The host is known and the key matches. */		debug("Host '%.200s' is known and matches the %s host key.",		    host, type);		debug("Found key in %s:%d", host_file, host_line);		if (options.check_host_ip && ip_status == HOST_NEW) {			if (readonly)				log("%s host key for IP address "				    "'%.128s' not in list of known hosts.",				    type, ip);			else if (!add_host_to_hostfile(user_hostfile, ip,			    host_key))				log("Failed to add the %s host key for IP "				    "address '%.128s' to the list of known "				    "hosts (%.30s).", type, ip, user_hostfile);			else				log("Warning: Permanently added the %s host "				    "key for IP address '%.128s' to the list "				    "of known hosts.", type, ip);		}		break;	case HOST_NEW:		if (readonly)			goto fail;		/* The host is new. */		if (options.strict_host_key_checking == 1) {			/*			 * User has requested strict host key checking.  We			 * will not add the host key automatically.  The only			 * alternative left is to abort.			 */			error("No %s host key is known for %.200s and you "			    "have requested strict checking.", type, host);			goto fail;		} else if (options.strict_host_key_checking == 2) {			/* The default */			fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);			snprintf(msg, sizeof(msg),			    "The authenticity of host '%.200s (%s)' can't be "			    "established.\n"			    "%s key fingerprint is %s.\n"			    "Are you sure you want to continue connecting "			    "(yes/no)? ", host, ip, type, fp);			xfree(fp);			if (!confirm(msg))				goto fail;		}		if (options.check_host_ip && ip_status == HOST_NEW) {			snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);			hostp = hostline;		} else			hostp = host;		/*		 * If not in strict mode, add the key automatically to the		 * local known_hosts file.		 */		if (!add_host_to_hostfile(user_hostfile, hostp, host_key))			log("Failed to add the host to the list of known "			    "hosts (%.500s).", user_hostfile);		else			log("Warning: Permanently added '%.200s' (%s) to the "			    "list of known hosts.", hostp, type);		break;	case HOST_CHANGED:		if (options.check_host_ip && host_ip_differ) {			char *msg;			if (ip_status == HOST_NEW)				msg = "is unknown";			else if (ip_status == HOST_OK)				msg = "is unchanged";			else				msg = "has a different value";			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");			error("The %s host key for %s has changed,", type, host);			error("and the key for the according IP address %s", ip);			error("%s. This could either mean that", msg);			error("DNS SPOOFING is happening or the IP address for the host");			error("and its host key have changed at the same time.");			if (ip_status != HOST_NEW)				error("Offending key for IP in %s:%d", ip_file, ip_line);		}		/* The host key has changed. */		fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");		error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");		error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");		error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");		error("It is also possible that the %s host key has just been changed.", type);		error("The fingerprint for the %s key sent by the remote host is\n%s.",		    type, fp);		error("Please contact your system administrator.");		error("Add correct host key in %.100s to get rid of this message.",		    user_hostfile);		error("Offending key in %s:%d", host_file, host_line);		xfree(fp);		/*		 * If strict host key checking is in use, the user will have		 * to edit the key manually and we can only abort.		 */		if (options.strict_host_key_checking) {			error("%s host key for %.200s has changed and you have "			    "requested strict checking.", type, host);			goto fail;		}		/*		 * If strict host key checking has not been requested, allow		 * the connection but without password authentication or		 * agent forwarding.		 */		if (options.password_authentication) {			error("Password authentication is disabled to avoid "			    "man-in-the-middle attacks.");			options.password_authentication = 0;		}		if (options.forward_agent) {			error("Agent forwarding is disabled to avoid "			    "man-in-the-middle attacks.");			options.forward_agent = 0;		}		if (options.forward_x11) {			error("X11 forwarding is disabled to avoid "			    "man-in-the-middle attacks.");			options.forward_x11 = 0;		}		if (options.num_local_forwards > 0 ||		    options.num_remote_forwards > 0) {			error("Port forwarding is disabled to avoid "			    "man-in-the-middle attacks.");			options.num_local_forwards =			    options.num_remote_forwards = 0;		}		/*		 * XXX Should permit the user to change to use the new id.		 * This could be done by converting the host key to an		 * identifying sentence, tell that the host identifies itself		 * by that sentence, and ask the user if he/she whishes to		 * accept the authentication.		 */		break;	}	if (options.check_host_ip && host_status != HOST_CHANGED &&	    ip_status == HOST_CHANGED) {		snprintf(msg, sizeof(msg),		    "Warning: the %s host key for '%.200s' "		    "differs from the key for the IP address '%.128s'"		    "\nOffending key for IP in %s:%d",		    type, host, ip, ip_file, ip_line);		if (host_status == HOST_OK) {			len = strlen(msg);			snprintf(msg + len, sizeof(msg) - len,			    "\nMatching host key in %s:%d",			    host_file, host_line);		}		if (options.strict_host_key_checking == 1) {			log(msg);			error("Exiting, you have requested strict checking.");			goto fail;		} else if (options.strict_host_key_checking == 2) {			strlcat(msg, "\nAre you sure you want "			    "to continue connecting (yes/no)? ", sizeof(msg));			if (!confirm(msg))				goto fail;		} else {			log(msg);		}	}	xfree(ip);	return 0;fail:	xfree(ip);	return -1;}intverify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key){	struct stat st;	/* return ok if the key can be found in an old keyfile */	if (stat(options.system_hostfile2, &st) == 0 ||	    stat(options.user_hostfile2, &st) == 0) {		if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1,		    options.user_hostfile2, options.system_hostfile2) == 0)			return 0;	}	return check_host_key(host, hostaddr, host_key, /*readonly*/ 0,	    options.user_hostfile, options.system_hostfile);}/* * Starts a dialog with the server, and authenticates the current user on the * server.  This does not need any extra privileges.  The basic connection * to the server must already have been established before this is called. * If login fails, this function prints an error and never returns. * This function does not require super-user privileges. */voidssh_login(Sensitive *sensitive, const char *orighost,    struct sockaddr *hostaddr, struct passwd *pw){	char *host, *cp;	char *server_user, *local_user;	local_user = xstrdup(pw->pw_name);	server_user = options.user ? options.user : local_user;	/* Convert the user-supplied hostname into all lowercase. */	host = xstrdup(orighost);	for (cp = host; *cp; cp++)		if (isupper(*cp))			*cp = tolower(*cp);	/* Exchange protocol version identification strings with the server. */	ssh_exchange_identification();	/* Put the connection into non-blocking mode. */	packet_set_nonblocking();	/* key exchange */	/* authenticate user */	if (compat20) {		ssh_kex2(host, hostaddr);		ssh_userauth2(local_user, server_user, host, sensitive);	} else {		ssh_kex(host, hostaddr);		ssh_userauth1(local_user, server_user, host, sensitive);	}}voidssh_put_password(char *password){	int size;	char *padded;	if (datafellows & SSH_BUG_PASSWORDPAD) {		packet_put_cstring(password);		return;	}	size = roundup(strlen(password) + 1, 32);	padded = xmalloc(size);	memset(padded, 0, size);	strlcpy(padded, password, size);	packet_put_string(padded, size);	memset(padded, 0, size);	xfree(padded);}

⌨️ 快捷键说明

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