📄 pgpuserio.c
字号:
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 + -