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

📄 auth2-pubkey.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
字号:
/* * 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: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");#include "ssh2.h"#include "xmalloc.h"#include "packet.h"#include "buffer.h"#include "log.h"#include "servconf.h"#include "compat.h"#include "bufaux.h"#include "auth.h"#include "key.h"#include "pathnames.h"#include "uidswap.h"#include "auth-options.h"#include "canohost.h"#include "monitor_wrap.h"/* import */extern ServerOptions options;extern u_char *session_id2;extern int session_id2_len;static intuserauth_pubkey(Authctxt *authctxt){	Buffer b;	Key *key = NULL;	char *pkalg;	u_char *pkblob, *sig;	u_int alen, blen, slen;	int have_sig, pktype;	int authenticated = 0;	if (!authctxt->valid) {		debug2("userauth_pubkey: disabled because of invalid user");		return 0;	}	have_sig = packet_get_char();	if (datafellows & SSH_BUG_PKAUTH) {		debug2("userauth_pubkey: SSH_BUG_PKAUTH");		/* no explicit pkalg given */		pkblob = packet_get_string(&blen);		buffer_init(&b);		buffer_append(&b, pkblob, blen);		/* so we have to extract the pkalg from the pkblob */		pkalg = buffer_get_string(&b, &alen);		buffer_free(&b);	} else {		pkalg = packet_get_string(&alen);		pkblob = packet_get_string(&blen);	}	pktype = key_type_from_name(pkalg);	if (pktype == KEY_UNSPEC) {		/* this is perfectly legal */		log("userauth_pubkey: unsupported public key algorithm: %s",		    pkalg);		goto done;	}	key = key_from_blob(pkblob, blen);	if (key == NULL) {		error("userauth_pubkey: cannot decode key: %s", pkalg);		goto done;	}	if (key->type != pktype) {		error("userauth_pubkey: type mismatch for decoded key "		    "(received %d, expected %d)", key->type, pktype);		goto done;	}	if (have_sig) {		sig = packet_get_string(&slen);		packet_check_eom();		buffer_init(&b);		if (datafellows & SSH_OLD_SESSIONID) {			buffer_append(&b, session_id2, session_id2_len);		} else {			buffer_put_string(&b, session_id2, session_id2_len);		}		/* reconstruct packet */		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);		buffer_put_cstring(&b, authctxt->user);		buffer_put_cstring(&b,		    datafellows & SSH_BUG_PKSERVICE ?		    "ssh-userauth" :		    authctxt->service);		if (datafellows & SSH_BUG_PKAUTH) {			buffer_put_char(&b, have_sig);		} else {			buffer_put_cstring(&b, "publickey");			buffer_put_char(&b, have_sig);			buffer_put_cstring(&b, pkalg);		}		buffer_put_string(&b, pkblob, blen);#ifdef DEBUG_PK		buffer_dump(&b);#endif		/* test for correct signature */		authenticated = 0;		if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),				buffer_len(&b))) == 1)			authenticated = 1;		buffer_clear(&b);		xfree(sig);	} else {		debug("test whether pkalg/pkblob are acceptable");		packet_check_eom();		/* XXX fake reply and always send PK_OK ? */		/*		 * XXX this allows testing whether a user is allowed		 * to login: if you happen to have a valid pubkey this		 * message is sent. the message is NEVER sent at all		 * if a user is not allowed to login. is this an		 * issue? -markus		 */		if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {			packet_start(SSH2_MSG_USERAUTH_PK_OK);			packet_put_string(pkalg, alen);			packet_put_string(pkblob, blen);			packet_send();			packet_write_wait();			authctxt->postponed = 1;		}	}	if (authenticated != 1)		auth_clear_options();done:	debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);	if (key != NULL)		key_free(key);	xfree(pkalg);	xfree(pkblob);#ifdef HAVE_CYGWIN	if (check_nt_auth(0, authctxt->pw) == 0)		return(0);#endif	return authenticated;}/* return 1 if user allows given key */static intuser_key_allowed2(struct passwd *pw, Key *key, char *file){	char line[8192];	int found_key = 0;	FILE *f;	u_long linenum = 0;	struct stat st;	Key *found;	char *fp;	if (pw == NULL)		return 0;	/* Temporarily use the user's uid. */	temporarily_use_uid(pw);	debug("trying public key file %s", file);	/* Fail quietly if file does not exist */	if (stat(file, &st) < 0) {		/* Restore the privileged uid. */		restore_uid();		return 0;	}	/* Open the file containing the authorized keys. */	f = fopen(file, "r");	if (!f) {		/* Restore the privileged uid. */		restore_uid();		return 0;	}	if (options.strict_modes &&	    secure_filename(f, file, pw, line, sizeof(line)) != 0) {		fclose(f);		log("Authentication refused: %s", line);		restore_uid();		return 0;	}	found_key = 0;	found = key_new(key->type);	while (fgets(line, sizeof(line), f)) {		char *cp, *options = NULL;		linenum++;		/* Skip leading whitespace, empty and comment lines. */		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)			;		if (!*cp || *cp == '\n' || *cp == '#')			continue;		if (key_read(found, &cp) != 1) {			/* no key?  check if there are options for this key */			int quoted = 0;			debug2("user_key_allowed: check options: '%s'", cp);			options = cp;			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {				if (*cp == '\\' && cp[1] == '"')					cp++;	/* Skip both */				else if (*cp == '"')					quoted = !quoted;			}			/* Skip remaining whitespace. */			for (; *cp == ' ' || *cp == '\t'; cp++)				;			if (key_read(found, &cp) != 1) {				debug2("user_key_allowed: advance: '%s'", cp);				/* still no key?  advance to next line*/				continue;			}		}		if (key_equal(found, key) &&		    auth_parse_options(pw, options, file, linenum) == 1) {			found_key = 1;			debug("matching key found: file %s, line %lu",			    file, linenum);			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);			verbose("Found matching %s key: %s",			    key_type(found), fp);			xfree(fp);			break;		}	}	restore_uid();	fclose(f);	key_free(found);	if (!found_key)		debug2("key not found");	return found_key;}/* check whether given key is in .ssh/authorized_keys* */intuser_key_allowed(struct passwd *pw, Key *key){	int success;	char *file;	file = authorized_keys_file(pw);	success = user_key_allowed2(pw, key, file);	xfree(file);	if (success)		return success;	/* try suffix "2" for backward compat, too */	file = authorized_keys_file2(pw);	success = user_key_allowed2(pw, key, file);	xfree(file);	return success;}Authmethod method_pubkey = {	"publickey",	userauth_pubkey,	&options.pubkey_authentication};

⌨️ 快捷键说明

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