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

📄 sshconnect2.c

📁 OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2000 Markus Friedl.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "includes.h"RCSID("$OpenBSD: sshconnect2.c,v 1.138 2004/06/13 12:53:24 djm Exp $");#include "openbsd-compat/sys-queue.h"#include "ssh.h"#include "ssh2.h"#include "xmalloc.h"#include "buffer.h"#include "packet.h"#include "compat.h"#include "bufaux.h"#include "cipher.h"#include "kex.h"#include "myproposal.h"#include "sshconnect.h"#include "authfile.h"#include "dh.h"#include "authfd.h"#include "log.h"#include "readconf.h"#include "misc.h"#include "match.h"#include "dispatch.h"#include "canohost.h"#include "msg.h"#include "pathnames.h"#ifdef GSSAPI#include "ssh-gss.h"#endif/* import */extern char *client_version_string;extern char *server_version_string;extern Options options;/* * SSH2 key exchange */u_char *session_id2 = NULL;u_int session_id2_len = 0;char *xxx_host;struct sockaddr *xxx_hostaddr;Kex *xxx_kex = NULL;static intverify_host_key_callback(Key *hostkey){	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)		fatal("Host key verification failed.");	return 0;}voidssh_kex2(char *host, struct sockaddr *hostaddr){	Kex *kex;	xxx_host = host;	xxx_hostaddr = hostaddr;	if (options.ciphers == (char *)-1) {		logit("No valid ciphers for protocol version 2 given, using defaults.");		options.ciphers = NULL;	}	if (options.ciphers != NULL) {		myproposal[PROPOSAL_ENC_ALGS_CTOS] =		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;	}	myproposal[PROPOSAL_ENC_ALGS_CTOS] =	    compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);	myproposal[PROPOSAL_ENC_ALGS_STOC] =	    compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);	if (options.compression) {		myproposal[PROPOSAL_COMP_ALGS_CTOS] =		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";	} else {		myproposal[PROPOSAL_COMP_ALGS_CTOS] =		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";	}	if (options.macs != NULL) {		myproposal[PROPOSAL_MAC_ALGS_CTOS] =		myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;	}	if (options.hostkeyalgorithms != NULL)		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =		    options.hostkeyalgorithms;	if (options.rekey_limit)		packet_set_rekey_limit(options.rekey_limit);	/* start key exchange */	kex = kex_setup(myproposal);	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;	kex->client_version_string=client_version_string;	kex->server_version_string=server_version_string;	kex->verify_host_key=&verify_host_key_callback;	xxx_kex = kex;	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);	session_id2 = kex->session_id;	session_id2_len = kex->session_id_len;#ifdef DEBUG_KEXDH	/* send 1st encrypted/maced/compressed message */	packet_start(SSH2_MSG_IGNORE);	packet_put_cstring("markus");	packet_send();	packet_write_wait();#endif}/* * Authenticate user */typedef struct Authctxt Authctxt;typedef struct Authmethod Authmethod;typedef struct identity Identity;typedef struct idlist Idlist;struct identity {	TAILQ_ENTRY(identity) next;	AuthenticationConnection *ac;	/* set if agent supports key */	Key	*key;			/* public/private key */	char	*filename;		/* comment for agent-only keys */	int	tried;	int	isprivate;		/* key points to the private key */};TAILQ_HEAD(idlist, identity);struct Authctxt {	const char *server_user;	const char *local_user;	const char *host;	const char *service;	Authmethod *method;	int success;	char *authlist;	/* pubkey */	Idlist keys;	AuthenticationConnection *agent;	/* hostbased */	Sensitive *sensitive;	/* kbd-interactive */	int info_req_seen;	/* generic */	void *methoddata;};struct Authmethod {	char	*name;		/* string to compare against server's list */	int	(*userauth)(Authctxt *authctxt);	int	*enabled;	/* flag in option struct that enables method */	int	*batch_flag;	/* flag in option struct that disables method */};void	input_userauth_success(int, u_int32_t, void *);void	input_userauth_failure(int, u_int32_t, void *);void	input_userauth_banner(int, u_int32_t, void *);void	input_userauth_error(int, u_int32_t, void *);void	input_userauth_info_req(int, u_int32_t, void *);void	input_userauth_pk_ok(int, u_int32_t, void *);void	input_userauth_passwd_changereq(int, u_int32_t, void *);int	userauth_none(Authctxt *);int	userauth_pubkey(Authctxt *);int	userauth_passwd(Authctxt *);int	userauth_kbdint(Authctxt *);int	userauth_hostbased(Authctxt *);int	userauth_kerberos(Authctxt *);#ifdef GSSAPIint	userauth_gssapi(Authctxt *authctxt);void	input_gssapi_response(int type, u_int32_t, void *);void	input_gssapi_token(int type, u_int32_t, void *);void	input_gssapi_hash(int type, u_int32_t, void *);void	input_gssapi_error(int, u_int32_t, void *);void	input_gssapi_errtok(int, u_int32_t, void *);#endifvoid	userauth(Authctxt *, char *);static int sign_and_send_pubkey(Authctxt *, Identity *);static void pubkey_prepare(Authctxt *);static void pubkey_cleanup(Authctxt *);static Key *load_identity_file(char *);static Authmethod *authmethod_get(char *authlist);static Authmethod *authmethod_lookup(const char *name);static char *authmethods_get(void);Authmethod authmethods[] = {#ifdef GSSAPI	{"gssapi-with-mic",		userauth_gssapi,		&options.gss_authentication,		NULL},#endif	{"hostbased",		userauth_hostbased,		&options.hostbased_authentication,		NULL},	{"publickey",		userauth_pubkey,		&options.pubkey_authentication,		NULL},	{"keyboard-interactive",		userauth_kbdint,		&options.kbd_interactive_authentication,		&options.batch_mode},	{"password",		userauth_passwd,		&options.password_authentication,		&options.batch_mode},	{"none",		userauth_none,		NULL,		NULL},	{NULL, NULL, NULL, NULL}};voidssh_userauth2(const char *local_user, const char *server_user, char *host,    Sensitive *sensitive){	Authctxt authctxt;	int type;	if (options.challenge_response_authentication)		options.kbd_interactive_authentication = 1;	packet_start(SSH2_MSG_SERVICE_REQUEST);	packet_put_cstring("ssh-userauth");	packet_send();	debug("SSH2_MSG_SERVICE_REQUEST sent");	packet_write_wait();	type = packet_read();	if (type != SSH2_MSG_SERVICE_ACCEPT)		fatal("Server denied authentication request: %d", type);	if (packet_remaining() > 0) {		char *reply = packet_get_string(NULL);		debug2("service_accept: %s", reply);		xfree(reply);	} else {		debug2("buggy server: service_accept w/o service");	}	packet_check_eom();	debug("SSH2_MSG_SERVICE_ACCEPT received");	if (options.preferred_authentications == NULL)		options.preferred_authentications = authmethods_get();	/* setup authentication context */	memset(&authctxt, 0, sizeof(authctxt));	pubkey_prepare(&authctxt);	authctxt.server_user = server_user;	authctxt.local_user = local_user;	authctxt.host = host;	authctxt.service = "ssh-connection";		/* service name */	authctxt.success = 0;	authctxt.method = authmethod_lookup("none");	authctxt.authlist = NULL;	authctxt.methoddata = NULL;	authctxt.sensitive = sensitive;	authctxt.info_req_seen = 0;	if (authctxt.method == NULL)		fatal("ssh_userauth2: internal error: cannot send userauth none request");	/* initial userauth request */	userauth_none(&authctxt);	dispatch_init(&input_userauth_error);	dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);	dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);	dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);	dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);	/* loop until success */	pubkey_cleanup(&authctxt);	dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);	debug("Authentication succeeded (%s).", authctxt.method->name);}voiduserauth(Authctxt *authctxt, char *authlist){	if (authctxt->methoddata) {		xfree(authctxt->methoddata);		authctxt->methoddata = NULL;	}	if (authlist == NULL) {		authlist = authctxt->authlist;	} else {		if (authctxt->authlist)			xfree(authctxt->authlist);		authctxt->authlist = authlist;	}	for (;;) {		Authmethod *method = authmethod_get(authlist);		if (method == NULL)			fatal("Permission denied (%s).", authlist);		authctxt->method = method;		/* reset the per method handler */		dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN,		    SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);		/* and try new method */		if (method->userauth(authctxt) != 0) {			debug2("we sent a %s packet, wait for reply", method->name);			break;		} else {			debug2("we did not send a packet, disable method");			method->enabled = NULL;		}	}}voidinput_userauth_error(int type, u_int32_t seq, void *ctxt){	fatal("input_userauth_error: bad message during authentication: "	   "type %d", type);}voidinput_userauth_banner(int type, u_int32_t seq, void *ctxt){	char *msg, *lang;	debug3("input_userauth_banner");	msg = packet_get_string(NULL);	lang = packet_get_string(NULL);	if (options.log_level > SYSLOG_LEVEL_QUIET)		fprintf(stderr, "%s", msg);	xfree(msg);	xfree(lang);}voidinput_userauth_success(int type, u_int32_t seq, void *ctxt){	Authctxt *authctxt = ctxt;	if (authctxt == NULL)		fatal("input_userauth_success: no authentication context");	if (authctxt->authlist) {		xfree(authctxt->authlist);		authctxt->authlist = NULL;	}	if (authctxt->methoddata) {		xfree(authctxt->methoddata);		authctxt->methoddata = NULL;	}	authctxt->success = 1;			/* break out */}voidinput_userauth_failure(int type, u_int32_t seq, void *ctxt){	Authctxt *authctxt = ctxt;	char *authlist = NULL;	int partial;	if (authctxt == NULL)		fatal("input_userauth_failure: no authentication context");	authlist = packet_get_string(NULL);	partial = packet_get_char();	packet_check_eom();	if (partial != 0)		logit("Authenticated with partial success.");	debug("Authentications that can continue: %s", authlist);	userauth(authctxt, authlist);}voidinput_userauth_pk_ok(int type, u_int32_t seq, void *ctxt){	Authctxt *authctxt = ctxt;	Key *key = NULL;	Identity *id = NULL;	Buffer b;	int pktype, sent = 0;	u_int alen, blen;	char *pkalg, *fp;	u_char *pkblob;	if (authctxt == NULL)		fatal("input_userauth_pk_ok: no authentication context");	if (datafellows & SSH_BUG_PKOK) {		/* this is similar to SSH_BUG_PKAUTH */		debug2("input_userauth_pk_ok: SSH_BUG_PKOK");		pkblob = packet_get_string(&blen);		buffer_init(&b);		buffer_append(&b, pkblob, blen);		pkalg = buffer_get_string(&b, &alen);		buffer_free(&b);	} else {		pkalg = packet_get_string(&alen);		pkblob = packet_get_string(&blen);	}	packet_check_eom();	debug("Server accepts key: pkalg %s blen %u", pkalg, blen);	if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {		debug("unknown pkalg %s", pkalg);		goto done;	}	if ((key = key_from_blob(pkblob, blen)) == NULL) {		debug("no key from blob. pkalg %s", pkalg);		goto done;	}	if (key->type != pktype) {		error("input_userauth_pk_ok: type mismatch "		    "for decoded key (received %d, expected %d)",		    key->type, pktype);		goto done;	}	fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);	debug2("input_userauth_pk_ok: fp %s", fp);	xfree(fp);	/*	 * search keys in the reverse order, because last candidate has been	 * moved to the end of the queue.  this also avoids confusion by	 * duplicate keys	 */	TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {		if (key_equal(key, id->key)) {			sent = sign_and_send_pubkey(authctxt, id);			break;		}	}done:	if (key != NULL)		key_free(key);	xfree(pkalg);	xfree(pkblob);	/* try another method if we did not send a packet */	if (sent == 0)		userauth(authctxt, NULL);}#ifdef GSSAPIintuserauth_gssapi(Authctxt *authctxt){	Gssctxt *gssctxt = NULL;	static gss_OID_set gss_supported = NULL;	static int mech = 0;	OM_uint32 min;	int ok = 0;	/* Try one GSSAPI method at a time, rather than sending them all at	 * once. */	if (gss_supported == NULL)		gss_indicate_mechs(&min, &gss_supported);	/* Check to see if the mechanism is usable before we offer it */	while (mech < gss_supported->count && !ok) {

⌨️ 快捷键说明

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