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

📄 sshconnect2.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	return private;}/* * try keys in the following order: *	1. agent keys that are found in the config file *	2. other agent keys *	3. keys that are only listed in the config file */static voidpubkey_prepare(Authctxt *authctxt){	Identity *id;	Idlist agent, files, *preferred;	Key *key;	AuthenticationConnection *ac;	char *comment;	int i, found;	TAILQ_INIT(&agent);	/* keys from the agent */	TAILQ_INIT(&files);	/* keys from the config file */	preferred = &authctxt->keys;	TAILQ_INIT(preferred);	/* preferred order of keys */	/* list of keys stored in the filesystem */	for (i = 0; i < options.num_identity_files; i++) {		key = options.identity_keys[i];		if (key && key->type == KEY_RSA1)			continue;		options.identity_keys[i] = NULL;		id = xmalloc(sizeof(*id));		memset(id, 0, sizeof(*id));		id->key = key;		id->filename = xstrdup(options.identity_files[i]);		TAILQ_INSERT_TAIL(&files, id, next);	}	/* list of keys supported by the agent */	if ((ac = ssh_get_authentication_connection())) {		for (key = ssh_get_first_identity(ac, &comment, 2);		    key != NULL;		    key = ssh_get_next_identity(ac, &comment, 2)) {			found = 0;			TAILQ_FOREACH(id, &files, next) {				/* agent keys from the config file are preferred */				if (key_equal(key, id->key)) {					key_free(key);					xfree(comment);					TAILQ_REMOVE(&files, id, next);					TAILQ_INSERT_TAIL(preferred, id, next);					id->ac = ac;					found = 1;					break;				}			}			if (!found && !options.identities_only) {				id = xmalloc(sizeof(*id));				memset(id, 0, sizeof(*id));				id->key = key;				id->filename = comment;				id->ac = ac;				TAILQ_INSERT_TAIL(&agent, id, next);			}		}		/* append remaining agent keys */		for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {			TAILQ_REMOVE(&agent, id, next);			TAILQ_INSERT_TAIL(preferred, id, next);		}		authctxt->agent = ac;	}	/* append remaining keys from the config file */	for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {		TAILQ_REMOVE(&files, id, next);		TAILQ_INSERT_TAIL(preferred, id, next);	}	TAILQ_FOREACH(id, preferred, next) {		debug2("key: %s (%p)", id->filename, id->key);	}}static voidpubkey_cleanup(Authctxt *authctxt){	Identity *id;	if (authctxt->agent != NULL)		ssh_close_authentication_connection(authctxt->agent);	for (id = TAILQ_FIRST(&authctxt->keys); id;	    id = TAILQ_FIRST(&authctxt->keys)) {		TAILQ_REMOVE(&authctxt->keys, id, next);		if (id->key)			key_free(id->key);		if (id->filename)			xfree(id->filename);		xfree(id);	}}intuserauth_pubkey(Authctxt *authctxt){	Identity *id;	int sent = 0;	while ((id = TAILQ_FIRST(&authctxt->keys))) {		if (id->tried++)			return (0);		/* move key to the end of the queue */		TAILQ_REMOVE(&authctxt->keys, id, next);		TAILQ_INSERT_TAIL(&authctxt->keys, id, next);		/*		 * send a test message if we have the public key. for		 * encrypted keys we cannot do this and have to load the		 * private key instead		 */		if (id->key && id->key->type != KEY_RSA1) {			debug("Offering public key: %s", id->filename);			sent = send_pubkey_test(authctxt, id);		} else if (id->key == NULL) {			debug("Trying private key: %s", id->filename);			id->key = load_identity_file(id->filename);			if (id->key != NULL) {				id->isprivate = 1;				sent = sign_and_send_pubkey(authctxt, id);				key_free(id->key);				id->key = NULL;			}		}		if (sent)			return (sent);	}	return (0);}/* * Send userauth request message specifying keyboard-interactive method. */intuserauth_kbdint(Authctxt *authctxt){	static int attempt = 0;	if (attempt++ >= options.number_of_password_prompts)		return 0;	/* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */	if (attempt > 1 && !authctxt->info_req_seen) {		debug3("userauth_kbdint: disable: no info_req_seen");		dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);		return 0;	}	debug2("userauth_kbdint");	packet_start(SSH2_MSG_USERAUTH_REQUEST);	packet_put_cstring(authctxt->server_user);	packet_put_cstring(authctxt->service);	packet_put_cstring(authctxt->method->name);	packet_put_cstring("");					/* lang */	packet_put_cstring(options.kbd_interactive_devices ?	    options.kbd_interactive_devices : "");	packet_send();	dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);	return 1;}/* * parse INFO_REQUEST, prompt user and send INFO_RESPONSE */voidinput_userauth_info_req(int type, u_int32_t seq, void *ctxt){	Authctxt *authctxt = ctxt;	char *name, *inst, *lang, *prompt, *response;	u_int num_prompts, i;	int echo = 0;	debug2("input_userauth_info_req");	if (authctxt == NULL)		fatal("input_userauth_info_req: no authentication context");	authctxt->info_req_seen = 1;	name = packet_get_string(NULL);	inst = packet_get_string(NULL);	lang = packet_get_string(NULL);	if (strlen(name) > 0)		logit("%s", name);	if (strlen(inst) > 0)		logit("%s", inst);	xfree(name);	xfree(inst);	xfree(lang);	num_prompts = packet_get_int();	/*	 * Begin to build info response packet based on prompts requested.	 * We commit to providing the correct number of responses, so if	 * further on we run into a problem that prevents this, we have to	 * be sure and clean this up and send a correct error response.	 */	packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);	packet_put_int(num_prompts);	debug2("input_userauth_info_req: num_prompts %d", num_prompts);	for (i = 0; i < num_prompts; i++) {		prompt = packet_get_string(NULL);		echo = packet_get_char();		response = read_passphrase(prompt, echo ? RP_ECHO : 0);		packet_put_cstring(response);		memset(response, 0, strlen(response));		xfree(response);		xfree(prompt);	}	packet_check_eom(); /* done with parsing incoming message. */	packet_add_padding(64);	packet_send();}static intssh_keysign(Key *key, u_char **sigp, u_int *lenp,    u_char *data, u_int datalen){	Buffer b;	struct stat st;	pid_t pid;	int to[2], from[2], status, version = 2;	debug2("ssh_keysign called");	if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {		error("ssh_keysign: no installed: %s", strerror(errno));		return -1;	}	if (fflush(stdout) != 0)		error("ssh_keysign: fflush: %s", strerror(errno));	if (pipe(to) < 0) {		error("ssh_keysign: pipe: %s", strerror(errno));		return -1;	}	if (pipe(from) < 0) {		error("ssh_keysign: pipe: %s", strerror(errno));		return -1;	}	if ((pid = fork()) < 0) {		error("ssh_keysign: fork: %s", strerror(errno));		return -1;	}	if (pid == 0) {		seteuid(getuid());		setuid(getuid());		close(from[0]);		if (dup2(from[1], STDOUT_FILENO) < 0)			fatal("ssh_keysign: dup2: %s", strerror(errno));		close(to[1]);		if (dup2(to[0], STDIN_FILENO) < 0)			fatal("ssh_keysign: dup2: %s", strerror(errno));		close(from[1]);		close(to[0]);		execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);		fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,		    strerror(errno));	}	close(from[1]);	close(to[0]);	buffer_init(&b);	buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */	buffer_put_string(&b, data, datalen);	if (ssh_msg_send(to[1], version, &b) == -1)		fatal("ssh_keysign: couldn't send request");	if (ssh_msg_recv(from[0], &b) < 0) {		error("ssh_keysign: no reply");		buffer_free(&b);		return -1;	}	close(from[0]);	close(to[1]);	while (waitpid(pid, &status, 0) < 0)		if (errno != EINTR)			break;	if (buffer_get_char(&b) != version) {		error("ssh_keysign: bad version");		buffer_free(&b);		return -1;	}	*sigp = buffer_get_string(&b, lenp);	buffer_free(&b);	return 0;}intuserauth_hostbased(Authctxt *authctxt){	Key *private = NULL;	Sensitive *sensitive = authctxt->sensitive;	Buffer b;	u_char *signature, *blob;	char *chost, *pkalg, *p;	const char *service;	u_int blen, slen;	int ok, i, len, found = 0;	/* check for a useful key */	for (i = 0; i < sensitive->nkeys; i++) {		private = sensitive->keys[i];		if (private && private->type != KEY_RSA1) {			found = 1;			/* we take and free the key */			sensitive->keys[i] = NULL;			break;		}	}	if (!found) {		debug("No more client hostkeys for hostbased authentication.");		return 0;	}	if (key_to_blob(private, &blob, &blen) == 0) {		key_free(private);		return 0;	}	/* figure out a name for the client host */	p = get_local_name(packet_get_connection_in());	if (p == NULL) {		error("userauth_hostbased: cannot get local ipaddr/name");		key_free(private);		return 0;	}	len = strlen(p) + 2;	chost = xmalloc(len);	strlcpy(chost, p, len);	strlcat(chost, ".", len);	debug2("userauth_hostbased: chost %s", chost);	xfree(p);	service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :	    authctxt->service;	pkalg = xstrdup(key_ssh_name(private));	buffer_init(&b);	/* construct data */	buffer_put_string(&b, session_id2, session_id2_len);	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);	buffer_put_cstring(&b, authctxt->server_user);	buffer_put_cstring(&b, service);	buffer_put_cstring(&b, authctxt->method->name);	buffer_put_cstring(&b, pkalg);	buffer_put_string(&b, blob, blen);	buffer_put_cstring(&b, chost);	buffer_put_cstring(&b, authctxt->local_user);#ifdef DEBUG_PK	buffer_dump(&b);#endif	if (sensitive->external_keysign)		ok = ssh_keysign(private, &signature, &slen,		    buffer_ptr(&b), buffer_len(&b));	else		ok = key_sign(private, &signature, &slen,		    buffer_ptr(&b), buffer_len(&b));	key_free(private);	buffer_free(&b);	if (ok != 0) {		error("key_sign failed");		xfree(chost);		xfree(pkalg);		return 0;	}	packet_start(SSH2_MSG_USERAUTH_REQUEST);	packet_put_cstring(authctxt->server_user);	packet_put_cstring(authctxt->service);	packet_put_cstring(authctxt->method->name);	packet_put_cstring(pkalg);	packet_put_string(blob, blen);	packet_put_cstring(chost);	packet_put_cstring(authctxt->local_user);	packet_put_string(signature, slen);	memset(signature, 's', slen);	xfree(signature);	xfree(chost);	xfree(pkalg);	packet_send();	return 1;}/* find auth method *//* * given auth method name, if configurable options permit this method fill * in auth_ident field and return true, otherwise return false. */static intauthmethod_is_enabled(Authmethod *method){	if (method == NULL)		return 0;	/* return false if options indicate this method is disabled */	if  (method->enabled == NULL || *method->enabled == 0)		return 0;	/* return false if batch mode is enabled but method needs interactive mode */	if  (method->batch_flag != NULL && *method->batch_flag != 0)		return 0;	return 1;}static Authmethod *authmethod_lookup(const char *name){	Authmethod *method = NULL;	if (name != NULL)		for (method = authmethods; method->name != NULL; method++)			if (strcmp(name, method->name) == 0)				return method;	debug2("Unrecognized authentication method name: %s", name ? name : "NULL");	return NULL;}/* XXX internal state */static Authmethod *current = NULL;static char *supported = NULL;static char *preferred = NULL;/* * Given the authentication method list sent by the server, return the * next method we should try.  If the server initially sends a nil list, * use a built-in default list. */static Authmethod *authmethod_get(char *authlist){	char *name = NULL;	u_int next;	/* Use a suitable default if we're passed a nil list.  */	if (authlist == NULL || strlen(authlist) == 0)		authlist = options.preferred_authentications;	if (supported == NULL || strcmp(authlist, supported) != 0) {		debug3("start over, passed a different list %s", authlist);		if (supported != NULL)			xfree(supported);		supported = xstrdup(authlist);		preferred = options.preferred_authentications;		debug3("preferred %s", preferred);		current = NULL;	} else if (current != NULL && authmethod_is_enabled(current))		return current;	for (;;) {		if ((name = match_list(preferred, supported, &next)) == NULL) {			debug("No more authentication methods to try.");			current = NULL;			return NULL;		}		preferred += next;		debug3("authmethod_lookup %s", name);		debug3("remaining preferred: %s", preferred);		if ((current = authmethod_lookup(name)) != NULL &&		    authmethod_is_enabled(current)) {			debug3("authmethod_is_enabled %s", name);			debug("Next authentication method: %s", name);			return current;		}	}}static char *authmethods_get(void){	Authmethod *method = NULL;	Buffer b;	char *list;	buffer_init(&b);	for (method = authmethods; method->name != NULL; method++) {		if (authmethod_is_enabled(method)) {			if (buffer_len(&b) > 0)				buffer_append(&b, ",", 1);			buffer_append(&b, method->name, strlen(method->name));		}	}	buffer_append(&b, "\0", 1);	list = xstrdup(buffer_ptr(&b));	buffer_free(&b);	return list;}

⌨️ 快捷键说明

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