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

📄 authfile.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 2 页
字号:
{	int i, check1, check2, cipher_type;	off_t len;	Buffer buffer, decrypted;	u_char *cp;	CipherContext ciphercontext;	Cipher *cipher;	Key *prv = NULL;	len = lseek(fd, (off_t) 0, SEEK_END);	lseek(fd, (off_t) 0, SEEK_SET);	buffer_init(&buffer);	cp = buffer_append_space(&buffer, len);	if (read(fd, cp, (size_t) len) != (size_t) len) {		debug("Read from key file %.200s failed: %.100s", filename,		    strerror(errno));		buffer_free(&buffer);		close(fd);		return NULL;	}	/* Check that it is at least big enough to contain the ID string. */	if (len < sizeof(authfile_id_string)) {		debug3("Not a RSA1 key file %.200s.", filename);		buffer_free(&buffer);		close(fd);		return NULL;	}	/*	 * Make sure it begins with the id string.  Consume the id string	 * from the buffer.	 */	for (i = 0; i < sizeof(authfile_id_string); i++)		if (buffer_get_char(&buffer) != authfile_id_string[i]) {			debug3("Not a RSA1 key file %.200s.", filename);			buffer_free(&buffer);			close(fd);			return NULL;		}	/* Read cipher type. */	cipher_type = buffer_get_char(&buffer);	(void) buffer_get_int(&buffer);	/* Reserved data. */	/* Read the public key from the buffer. */	buffer_get_int(&buffer);	prv = key_new_private(KEY_RSA1);	buffer_get_bignum(&buffer, prv->rsa->n);	buffer_get_bignum(&buffer, prv->rsa->e);	if (commentp)		*commentp = buffer_get_string(&buffer, NULL);	else		xfree(buffer_get_string(&buffer, NULL));	/* Check that it is a supported cipher. */	cipher = cipher_by_number(cipher_type);	if (cipher == NULL) {		debug("Unsupported cipher %d used in key file %.200s.",		    cipher_type, filename);		buffer_free(&buffer);		goto fail;	}	/* Initialize space for decrypted data. */	buffer_init(&decrypted);	cp = buffer_append_space(&decrypted, buffer_len(&buffer));	/* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */	cipher_set_key_string(&ciphercontext, cipher, passphrase,	    CIPHER_DECRYPT);	cipher_crypt(&ciphercontext, cp,	    buffer_ptr(&buffer), buffer_len(&buffer));	cipher_cleanup(&ciphercontext);	memset(&ciphercontext, 0, sizeof(ciphercontext));	buffer_free(&buffer);	check1 = buffer_get_char(&decrypted);	check2 = buffer_get_char(&decrypted);	if (check1 != buffer_get_char(&decrypted) ||	    check2 != buffer_get_char(&decrypted)) {		if (strcmp(passphrase, "") != 0)			debug("Bad passphrase supplied for key file %.200s.",			    filename);		/* Bad passphrase. */		buffer_free(&decrypted);		goto fail;	}	/* Read the rest of the private key. */	buffer_get_bignum(&decrypted, prv->rsa->d);	buffer_get_bignum(&decrypted, prv->rsa->iqmp);		/* u */	/* in SSL and SSH v1 p and q are exchanged */	buffer_get_bignum(&decrypted, prv->rsa->q);		/* p */	buffer_get_bignum(&decrypted, prv->rsa->p);		/* q */	/* calculate p-1 and q-1 */	rsa_generate_additional_parameters(prv->rsa);	buffer_free(&decrypted);	close(fd);	return prv;fail:	if (commentp)		xfree(*commentp);	close(fd);	key_free(prv);	return NULL;}Key *key_load_private_pem(int fd, int type, const char *passphrase,    char **commentp){	FILE *fp;	EVP_PKEY *pk = NULL;	Key *prv = NULL;	char *name = "<no key>";	fp = fdopen(fd, "r");	if (fp == NULL) {		error("fdopen failed: %s", strerror(errno));		close(fd);		return NULL;	}	pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);	if (pk == NULL) {		debug("PEM_read_PrivateKey failed");		(void)ERR_get_error();	} else if (pk->type == EVP_PKEY_RSA &&	    (type == KEY_UNSPEC||type==KEY_RSA)) {		prv = key_new(KEY_UNSPEC);		prv->rsa = EVP_PKEY_get1_RSA(pk);		prv->type = KEY_RSA;		name = "rsa w/o comment";#ifdef DEBUG_PK		RSA_print_fp(stderr, prv->rsa, 8);#endif	} else if (pk->type == EVP_PKEY_DSA &&	    (type == KEY_UNSPEC||type==KEY_DSA)) {		prv = key_new(KEY_UNSPEC);		prv->dsa = EVP_PKEY_get1_DSA(pk);		prv->type = KEY_DSA;		name = "dsa w/o comment";#ifdef DEBUG_PK		DSA_print_fp(stderr, prv->dsa, 8);#endif	} else {		error("PEM_read_PrivateKey: mismatch or "		    "unknown EVP_PKEY save_type %d", pk->save_type);	}	fclose(fp);	if (pk != NULL)		EVP_PKEY_free(pk);	if (prv != NULL && commentp)		*commentp = xstrdup(name);	debug("read PEM private key done: type %s",	    prv ? key_type(prv) : "<unknown>");	return prv;}static intkey_perm_ok(int fd, const char *filename){	struct stat st;	if (fstat(fd, &st) < 0)		return 0;	/*	 * if a key owned by the user is accessed, then we check the	 * permissions of the file. if the key owned by a different user,	 * then we don't care.	 */#ifdef HAVE_CYGWIN	if (check_ntsec(filename))#endif	if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");		error("Permissions 0%3.3o for '%s' are too open.",		    st.st_mode & 0777, filename);		error("It is recommended that your private key files are NOT accessible by others.");		error("This private key will be ignored.");		return 0;	}	return 1;}Key *key_load_private_type(int type, const char *filename, const char *passphrase,    char **commentp){	int fd;	fd = open(filename, O_RDONLY);	if (fd < 0)		return NULL;	if (!key_perm_ok(fd, filename)) {		error("bad permissions: ignore key: %s", filename);		close(fd);		return NULL;	}	switch (type) {	case KEY_RSA1:		return key_load_private_rsa1(fd, filename, passphrase,		    commentp);		/* closes fd */		break;	case KEY_DSA:	case KEY_RSA:	case KEY_UNSPEC:		return key_load_private_pem(fd, type, passphrase, commentp);		/* closes fd */		break;	default:		close(fd);		break;	}	return NULL;}Key *key_load_private(const char *filename, const char *passphrase,    char **commentp){	Key *pub, *prv;	int fd;	fd = open(filename, O_RDONLY);	if (fd < 0)		return NULL;	if (!key_perm_ok(fd, filename)) {		error("bad permissions: ignore key: %s", filename);		close(fd);		return NULL;	}	pub = key_load_public_rsa1(fd, filename, commentp);	lseek(fd, (off_t) 0, SEEK_SET);		/* rewind */	if (pub == NULL) {		/* closes fd */		prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL);		/* use the filename as a comment for PEM */		if (commentp && prv)			*commentp = xstrdup(filename);	} else {		/* it's a SSH v1 key if the public key part is readable */		key_free(pub);		/* closes fd */		prv = key_load_private_rsa1(fd, filename, passphrase, NULL);	}	return prv;}static intkey_try_load_public(Key *k, const char *filename, char **commentp){	FILE *f;	char line[4096];	char *cp;	f = fopen(filename, "r");	if (f != NULL) {		while (fgets(line, sizeof(line), f)) {			line[sizeof(line)-1] = '\0';			cp = line;			switch (*cp) {			case '#':			case '\n':			case '\0':				continue;			}			/* Skip leading whitespace. */			for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)				;			if (*cp) {				if (key_read(k, &cp) == 1) {					if (commentp)						*commentp=xstrdup(filename);					fclose(f);					return 1;				}			}		}		fclose(f);	}	return 0;}/* load public key from ssh v1 private or any pubkey file */Key *key_load_public(const char *filename, char **commentp){	Key *pub;	char file[MAXPATHLEN];	pub = key_load_public_type(KEY_RSA1, filename, commentp);	if (pub != NULL)		return pub;	pub = key_new(KEY_UNSPEC);	if (key_try_load_public(pub, filename, commentp) == 1)		return pub;	if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&	    (strlcat(file, ".pub", sizeof file) < sizeof(file)) &&	    (key_try_load_public(pub, file, commentp) == 1))		return pub;	key_free(pub);	return NULL;}

⌨️ 快捷键说明

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