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

📄 pgpuserio.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (!fileread) {
	ErrorOutput(TRUE, LEVEL_CRITICAL, "UNABLE_TO_CREATE_READ_MODULE");
	fclose(file);
	return PGPERR_NOMEM;
    }

    err = pgpFileReadPump (fileread, head);
    pgpFileReadDestroy (fileread);
    return err;
}

struct CloseUI {
	struct PgpTtyUI *ui;
	struct PgpPipeline **output; /* No longer used */
	int closing;		/* No longer used */
	PGPFileRef *tmpFileRef;
};

static int
DoCloseKeyAdd (FILE *file, void *arg)
{
    struct CloseUI *ui = (struct CloseUI *)arg;
    int code = 0;

    if (fclose (file) != 0) {
	/* Error closing file */
	perror ("closing temp keyring file");
    } else if (ui->tmpFileRef != NULL) {
	char *filename = NULL;

	pgpFullPathFromFileRef(ui->tmpFileRef, &filename);
	
	if (filename == NULL) {
	    code = PGPERR_NOMEM;
	} else {
	    code = ui->ui->addKeys (ui->ui, filename);
	    pgpFree (filename);
	}
    }

    if (ui->tmpFileRef != NULL) {
	pgpDeleteFile (ui->tmpFileRef);
	pgpFreeFileRef (ui->tmpFileRef);
    }
    pgpMemFree (ui);
    return code;
}

#ifndef NO_POPEN

static int
DoClose (FILE *file, void *arg)
{
	struct CloseUI *ui = (struct CloseUI *)arg;
	int code;

	code = pclose (file);

	fputs ("\nDone...hit any key\n", ui->ui->fp);
	kbCbreak();
	kbGet();
	kbNorm();
	fputs ("\n", ui->ui->fp);
	/* XXX: Ask to save the file (if possible)?? How? */

	if (!code) {
		pgpMemFree (ui);
	}

	return code;
}

#endif /* ifndef NO_POPEN */


#ifndef NO_POPEN

static FILE *
openPager (struct PgpTtyUI const *ui)
{
	char const *pager = "more";

	if (ui->pager)
		pager = ui->pager;

	return popen (pager, "w");
}

#endif /* ifndef NO_POPEN */

int
pgpTtyNewOutput (void *arg, struct PgpPipeline **output, int type,
			char const *suggested_name)
{
	struct PgpTtyUI *ui = (struct PgpTtyUI *)arg;
	struct PgpFile *pgpf;
	struct CloseUI *cui;
	char const *name;
	char buffer[64];
	int len, moreflag = 0, use_stdout = 0, nullflag = 0;
	FILE *fp = NULL;	/* Initialized to shut up the compiler */

	pgpAssert(type >= 0);

	if (!output)
		return PGPERR_BADPARAM;

	name = ui->outname;	/* assume the name passed in */

	/* Send non-pgp portion to the bit bucket, for compat with old.*/
	if (type == PGPANN_NONPGP_BEGIN) {
	    name = NULLNAME;
	    nullflag = 1;
	
	    /* Filter Mode */
	    /* XXX This causes non-PGP output not to appear in filter mode*/
	    if (ui->protect_name < 0) {
		if(ui->moreflag) {
		    name = "stdout";
		    use_stdout++;
		}
	    }

	    type = PGP_LITERAL_TEXT;
	}
	else {
	    if (ui->protect_name < 0) {
		name = "stdout";
		use_stdout++;
	    }
	}


#if 0
	/* For debugging, describe what scope we are in */
	if (type > 255 && type != PGPANN_PGPKEY_BEGIN)
		fprintf (stderr, "pgpTtyNewOutput: type is scope: %d (%s)\n",
			 type, pgpScopeName (type));

	if (type >= 0 && type < 256 && type != PGP_LITERAL_TEXT &&
	    type != PGP_LITERAL_BINARY)
		fprintf (stderr,
 "pgpTtyNewOutput: type is a literal type, but not \'t\' or \'b\': %c (%d)\n",
			 (byte)type, type);
#endif

	/* if we want to use the name from the literal packet... */
	if (ui->protect_name > 0 && suggested_name &&
	    strcmp (suggested_name, "stdin"))
		name = suggested_name;


	/* Check for "for your eyes only" mode */
	if (/*type == PGP_LITERAL_TEXT && */
	    ((suggested_name && !strcmp (suggested_name, "_CONSOLE"))
	     || ui->moreflag)){
		/* output to pager */
		name = "_CONSOLE";
		moreflag++;
	}
	/* XXX: If suggested_name is _CONSOLE, ask the user whether to show */

	if (type == PGPANN_PGPKEY_BEGIN && ui->addKeys) {
		/* we have a means to add keys.. Use it */
		if (!ui->commits) {
			/* Just dearmor key file */
			type = PGP_LITERAL_BINARY;
		} else {
			name = "Temporary PGP Keyfile";/* won't be used */
			moreflag++;
		}
	}

	/* If all else fails, ask the user where to store the file.
	   If batchmode, use the suggested name if available, else
	   give up. */
	while (!name || (!moreflag && !use_stdout && !nullflag &&
			 pgpTtyCheckOverwrite(ui->env, name))) {
		if (pgpenvGetInt (ui->env, PGPENV_BATCHMODE, NULL, NULL)) {
			if (suggested_name)
				len = 0;
			else
		 		return PGPERR_NO_FILE;
		}
		else {
		    if(suggested_name)
			InteractionOutput(TRUE,
					  "NEED_FILE_TO_SAVE",
					  suggested_name);
		    else
			InteractionOutput(TRUE, "NEED_FILE_TO_SAVE", "");

		    len = pgpTtyNeedFile (buffer, sizeof (buffer));
		}

		if (len)
			name = buffer;
		else
			name = suggested_name;
	}


	if (!type) {
	    StatusOutput(TRUE, "UNKNOWN_FILE_TYPE");
	    type = PGP_LITERAL_TEXT;
	}
	StatusOutput(TRUE,
		     "OPENING_FILE_WITH_TYPE",
		     name,
		     type == PGP_LITERAL_TEXT ? "text" : "binary");

	if (! *output || moreflag || use_stdout) {
		if (!moreflag) {
			if (use_stdout)
				fp = stdout;
			else {
				fp = fopen (name, type == PGP_LITERAL_TEXT ?
						"w" : "wb");
				/* Only use name from UI once */
				if (name == ui->outname)
					ui->outname = NULL;
			}

			if (!fp) {
				/* XXX: Try to re-open file? */
				return PGPERR_NO_FILE;
			}
		}

		if (*output) {
			int ret;

			ret = (*output)->sizeAdvise (*output, 0);
			if (ret)
			    ErrorOutput(TRUE,
					LEVEL_SEVERE,
					"ERROR_CLOSING_OLD_FILE",
					ret);
			/* *output can be reset from under us in close() */
			if (*output)
				(*output)->teardown (*output);
			*output = NULL;
		}

		if (type == PGPANN_PGPKEY_BEGIN && ui->addKeys) {
			PGPError ret;

			cui = (struct CloseUI *)pgpMemAlloc (sizeof (*cui));
			if (!cui)
				return PGPERR_NOMEM;
			cui->ui = ui;
			fp = pgpStdIOOpenTempFile(&cui->tmpFileRef, &ret);
			if (!fp)
				return ret;
			fprintf(fp, "Wubba!\n");
			pgpf = pgpFileProcWriteOpen (fp, DoCloseKeyAdd, cui);

		} else if (moreflag) {
#ifdef NO_POPEN
			if (!pgpMoreModCreate(output)) {
				return PGPERR_NOMEM;
			}
			fputs ("\nPlaintext message follows...\n\
------------------------------\n\n", ui->fp);
			return 0;
#else
			cui = (struct CloseUI *)pgpMemAlloc (sizeof (*cui));
			if (!cui)
				return PGPERR_NOMEM;
			cui->ui = ui;
			cui->tmpFileRef = NULL;
			pgpf = pgpFileProcWriteOpen (openPager (ui), DoClose,
					cui);

			if (pgpf)
				fputs ("\nPlaintext message follows...\n\
------------------------------\n\n", ui->fp);
#endif
			} else {
				pgpf = pgpFileWriteOpen (fp, NULL);
				if (!pgpf && !use_stdout)
					fclose (fp);
			}
			if (!pgpf)
				return PGPERR_NOMEM;

			if (!pgpFileWriteCreate (output, pgpf,
			    (use_stdout && !moreflag) ? 0 : 1)) {
				return PGPERR_NOMEM;
			}
			return 0;

		/* XXX: How do we save the data in case the user wants to
		* save it to a file and moreflag is set and the name
		* isn't _CONSOLE?
		*/
	} else {
		/* Only use name from UI once */
		if (name == ui->outname)
			ui->outname = NULL;
		return (*output)->annotate (*output, *output,
					PGPANN_NEWFILE_START,
					(byte const *)name,
					strlen (name));
	}
}

/*
 * Given the signature structure, sig, verify it against the hash
 * to see if this signature is valid. This requires looking up the
 * public key in the keyring and validating the key.
 *
 * Returns 0 on success or an error code.
 */
int
pgpTtySigVerify (void *arg, struct PgpSig const *sig, byte const *hash)
{
	struct PgpTtyUI *ui = (struct PgpTtyUI *)arg;
	union RingObject *ringobj = NULL; /* shut up the compiler */
	struct PgpPubKey *pubkey;
	word32 timestamp = pgpSigTimestamp (sig);
	byte pkalg;
	byte const *keyid;
	int err;

	keyid = pgpSigId8 (sig);
	pkalg = pgpSigPKAlg (sig);
	pubkey = NULL;
#if 0 /*Obsolete - BAT 19970609*/
	if (!memcmp (keyid, fixedKeyID, 8) && pkalg == PGP_PKALG_RSA)
		pubkey = fixedKeyPub ();
	else
#endif
	if (ui->ringset) {
		ringobj = ringKeyById8 (ui->ringset, pkalg, keyid);
		if (ringobj) {
			pubkey = ringKeyPubKey (ui->ringset, ringobj, 0);
			ringObjectRelease (ringobj);
		}
	}


	if (pubkey && !pubkey->verify) {
		/* Make sure we can use this key */
		pgpPubKeyDestroy (pubkey);
		pubkey = NULL;
	}

	if (!pubkey) {
	    InformationOutput(TRUE,
			      "UNKNOWN_SIGNATURE");
	    pgpTtyPutKeyID (keyid);
	    return PGPERR_SIG_NOKEY;
	}

	err = pgpSigCheck (sig, pubkey, hash);

	if (err >= 0)
	  pgpTtySigResult (arg, ringobj, timestamp, err);
	else
	  pgpTtySigResult (arg, ringobj, timestamp, err);

	pgpPubKeyDestroy (pubkey);
	return 0;
}

int
pgpTtyUnlockSeckey (void *arg, union RingObject *key,
		struct PgpSecKey *seckey, char const *prompt)
{
	struct PgpTtyUI *ui = (struct PgpTtyUI *)arg;
	int i = 3;
	int err;

	if (!seckey)
		return -1;

	if (!pgpSecKeyIslocked (seckey))
		return 0;

	if (ui->passcache) {
		err = pgpPassCacheTryKey (ui->passcache, seckey);
		if (err > 0)
			return 0;
	}

	/*XXX Add code to detect if we're in batch mode without a passphrase*/

	if (prompt)
	    InteractionOutput(TRUE, prompt);

	InteractionOutput(TRUE, "NEED_PASSPHRASE_TO_DECRYPT_KEY");
	ringKeyPrint(OUTPUT_INTERACTION, ui->ringset, key, 1);
	while (i--) {
		char pass[256];
		int len;

		len = pgpTtyGetPass (ui->showpass, pass, sizeof (pass));
		if (!len)
			break;
		err = pgpSecKeyUnlock (seckey, ui->env, pass, len);

		if (err < 0) {
		    StatusOutput(TRUE, "KEY_CORRUPTED", err);
		    PGPErrCodeOutput(TRUE, LEVEL_CRITICAL, err);
		    memset (pass, 0, sizeof (pass));
		    break;
		}

		if (err) {
		    StatusOutput(TRUE, "GOOD_PASSPHRASE");
		    if (ui->passcache)
			pgpPassCacheAdd (ui->passcache, pass, len);
		    memset (pass, 0, sizeof (pass));
		    return 0;
		}
		memset (pass, 0, sizeof (pass));
		StatusOutput(TRUE, "BAD_PASSPHRASE");
	}
	return -1;
}

/*
 * given a list of Encrypted Session Keys (esklist), try to decrypt
 * them to get the session key. Fills in keylen with the length of
 * the session key buffer.
 *
 * Returns 0 on success or PGPANN_PARSER_EATIT on failure.
 */
int
pgpTtyEskDecrypt (void *arg, struct PgpESK const *esklist, byte *key,
		size_t *keylen,
		int (*tryKey) (void *arg, byte const *key, size_t keylen),
		void *tryarg)
{
	struct PgpTtyUI *ui = (struct PgpTtyUI *)arg;
	struct PgpESK const *esk;
	union RingObject *ringobj = NULL; /* shut up the compiler */
	struct PgpSecKey *seckey;

⌨️ 快捷键说明

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