📄 pgp.cpp
字号:
if(pgpargs && (pgpargs->userid == NULL)) {
if((mode & (SIGN | SIGNFL)) && pgpargs->msg
&& pgpargs->msg->header->From) {
addr = pgpargs->msg->header->From;
if(addr->pgpid == NULL) {
if((addr1 = find_addr(addr)) != NULL)
addr = addr1;
}
if(addr->pgpid && *addr->pgpid && strncmp(addr->pgpid, "0x", 2))
display_msg(MSG_WARN, "PGP", "Invalid PGP Id: %s", addr->pgpid);
else
pgpargs->userid = addr->pgpid;
}
if(pgpargs->userid == NULL)
pgpargs->userid = const_cast<char *>(Config.get("pgpuser", user_n).c_str());
}
/* sign & encode needs passphrase */
if((mode & ENCODE) && (mode & SIGN))
snprintf(args, sizeof(args), "%s %s %s --batch -a -se %s -u %s ",
pgpprg, pgpparm, gpgsuppl, pgpargs->recp, pgpargs->userid);
else if(mode & ENCODE)
snprintf(args, sizeof(args), "%s %s --batch -a -e %s", pgpprg,
pgpparm, pgpargs->recp);
else if(mode & SIGN) /* sign needs passphrase */
snprintf(args, sizeof(args), "%s %s %s --batch --clearsign -u %s ",
pgpprg, pgpparm, gpgsuppl, pgpargs->userid);
if(mode & SIGNFL) { /* signfl needs passphrase */
snprintf(args, sizeof(args), "%s %s %s --batch -ab -u %s", pgpprg,
pgpparm, gpgsuppl, pgpargs->userid);
if(pgpargs->recp == NULL) {
free(pgpprg);
return NULL;
}
}
if(mode & DECODE) /* decode needs passphrase */
snprintf(args, sizeof(args), "%s %s %s --batch --decrypt %s", pgpprg,
pgpparm, gpgsuppl, pubring);
if(mode & VERIFY)
snprintf(args, sizeof(args), "%s %s --batch --decrypt %s", pgpprg,
pgpparm, pubring);
if(mode & EXTKEY)
snprintf(args, sizeof(args), "%s %s --batch --import %s", pgpprg,
pgpparm, inbuf);
if(mode & ADDKEY)
snprintf(args, sizeof(args), "%s %s --batch -a --export %s",
pgpprg, pgpparm, pgpargs->recp);
if(mode & VRFYFL)
snprintf(args, sizeof(args), "%s %s --batch --verify %s %s %s", pgpprg,
pgpparm, pubring, pgpargs->recp, inbuf);
free(pgpprg);
return strdup(args);
}
/*
* inbuf: file with text to encode/decode
* mode: ENCODE|SIGN or DECODE
* recp: if mode&(ENCODE|SIGN), the list of recipient(s)
* passphrase: if mode==DECODE, or mode==SIGN, the pass phrase
* see also "pgp/doc/appnote.doc"
*/
int pgp_action(char *inbuf, int mode, struct pgpargs *pgpargs) {
char buf[1024];
char nfile[64];
char *args, *p, *q, *r;
int n, move_result = 0, errfd;
int t = NORMAL, tries = 0;
unsigned int keyid = 0;
struct _proc_info pinfo;
FILE *file;
struct stat sb;
int pgpvers = Config.getInt("pgpversion", PGP_DEFAULT_VERS);
strcpy(nfile, (mode & SIGNFL) ? pgpargs->recp : get_temp_file("pgp"));
while(t) {
n = 0;
move_result = 1;
init_pinfo(&pinfo);
pinfo.handle = pgp_cleanup;
pinfo.init = pgp_init;
pinfo.fd_in[0] = pinfo.fd_out[0] = pinfo.fd_err[0] = 0;
/* init pgp exit status */
pgpext = -100;
if(!(t & (NORMAL | KEYRING)) && (t & HTTP)) {
if(pgp_fetch_key_from_http
(const_cast<char *>(Config.get("pgpkeyserver", "wwwkeys.pgp.net").c_str()),
keyid) == -1) { /* if we can not find signature during decode - still procede */
if(mode & DECODE)
break;
unlink(nfile);
return -1;
}
}
if(!(args = get_pgp_command_line(mode, pgpargs, inbuf, t))) {
if(mode & DECODE)
break;
unlink(nfile);
return -1;
}
if(t & NORMAL)
t &= ~NORMAL;
else if(t & KEYRING)
t &= ~KEYRING;
else if(t & HTTP)
t &= ~HTTP;
/* log pgp/gpg args, just for debugging */
display_msg(MSG_LOG, "PGP_EXEC", "args: %s", args);
if(exec_child(args, &pinfo) == -1) {
free(args);
pgp_cleanup(&pinfo);
if(pinfo.fd_in[1] > 0)
close(pinfo.fd_in[1]);
if(pinfo.fd_out[0] > 0)
close(pinfo.fd_out[0]);
if(pinfo.fd_err[0] > 0)
close(pinfo.fd_err[0]);
unlink(nfile);
return -1;
}
free(args);
/* first line of stdin must contain passphrase */
/* endline should be written to stdin only when passphrase */
/* is written there */
if(pgpargs && pgpargs->passphrase && (mode & (DECODE | SIGN | SIGNFL))) {
write(pinfo.fd_in[1], pgpargs->passphrase, strlen(pgpargs->passphrase));
write(pinfo.fd_in[1], "\n", 1);
}
if((mode & EXTKEY) && (pgpvers == 500 || pgpvers == 95 || pgpvers == 651))
errfd = pinfo.fd_err[0];
else if(mode & VRFYFL)
errfd = (pgpvers == 263) ? pinfo.fd_out[0] : pinfo.fd_err[0];
else {
if((file = fopen(inbuf, "r")) != NULL) {
while((n = fread(buf, 1, sizeof(buf), file)) > 0)
write(pinfo.fd_in[1], buf, n);
close(pinfo.fd_in[1]);
pinfo.fd_in[1] = -1;
fclose(file);
}
if((file = fopen(nfile, "w")) != NULL) {
while(1) {
if((n =my_check_io_forms(pinfo.fd_out[0], 0, PGP_TIMEOUT)) < 0) {
if(n == -3) {
display_msg(MSG_WARN, "PGP Timeout", "Terminating process");
if(pinfo.pid > 0)
kill(pinfo.pid, SIGKILL);
}
break;
}
if((n = read(pinfo.fd_out[0], buf, sizeof(buf))) > 0)
fwrite(buf, 1, n, file);
else
break;
}
close(pinfo.fd_out[0]);
pinfo.fd_out[0] = -1;
fclose(file);
}
errfd = pinfo.fd_err[0];
}
usleep(500000);
while((n = read(errfd, buf, sizeof(buf) - 1)) > 0) {
buf[n] = '\0';
/* p should be buf for all versions except 263 */
/* now messy part of the code starts. I don't understand */
/* any single bit of it :-( */
if((pgpvers == 500) || (pgpvers == 95) || (pgpvers == 651))
p = buf;
else {
p = strstr(buf, "Current");
if(p)
p = strchr(p, '\n');
if(p && *p)
p++;
}
if(p && *p) {
while((q = strchr(p, '\n')) != NULL) {
*q = '\0';
if(strlen(p))
display_msg(MSG_LOG, "PGP", p);
*q = '\n';
p = q + 1;
}
if(*p)
display_msg(MSG_LOG, "PGP", p);
}
if((p = strstr(buf, "Good signature")) ||
(p = strstr(buf, "BAD signature")) ||
(p = strstr(buf, "VALIDSIG")) ||
(p = strstr(buf, "BADSIG")) ||
(p = strstr(buf, "VALIDSIG")) ||
(p = strstr(buf, "WARNING:"))) {
if(pgpvers == 95) {
if(strstr(buf, "gpg:") != NULL)
p = strstr(buf, "gpg:");
}
if(strlen(p) > 300)
p[300] = '\0';
if(strstr(p, "Can't find the right public key")) {
} else if((q = strchr(p, '\n')) != NULL) {
*q = '\0';
q++;
display_msg(MSG_MSG, p, q);
} else
display_msg(MSG_MSG,
"PGP messsage (see Log for more details)",
p);
}
if((p = strstr(buf, "ERROR:")) || (p = strstr(buf, "Error:"))
|| (p = strstr(buf, "You do not have the secret key"))
|| (p = strstr(buf, "No encryption keys found"))
|| (p = strstr(buf, "decryption failed"))
|| (p = strstr(buf, "Key matching expected"))
|| (p = strstr(buf, "unknown keyid"))
|| (p = strstr(buf, "ERRSIG"))
|| (p = strstr(buf, "SIGEXPIRED"))
|| (p = strstr(buf, "BADARMOR"))
|| (p = strstr(buf, "BAD_PASSPHRASE"))
|| (p = strstr(buf, "NO_PUBKEY"))
|| (p = strstr(buf, "NO_SECKEY"))
|| (p = strstr(buf, "CRC"))
|| (p = strstr(buf, "secret key not available"))
|| (p = strstr(buf, "public key not found"))
|| (p = strstr(buf, "malformed user id"))
|| (p = strstr(buf, "encryption failed"))
|| (p = strstr(buf, "sign+encrypt failed"))
|| (p = strstr(buf, "Encryption error"))) {
/* if we decoding encoded and signed message */
/* but no public key could be found - still show the results */
if(!(mode & DECODE) &&
(!strstr(buf, "Key matching expected") ||
!strstr(buf, "unknown keyid")))
move_result = 0;
/* can not find encryption key for one of the recipients */
if((mode & ENCODE) &&
(strstr(buf, "No encryption keys found") ||
strstr(buf, "NO_PUBKEY") ||
strstr(buf, "public key not found") ||
strstr(buf, "public key not found") ||
strstr(buf, "encryption failed") ||
strstr(buf, "sign+encrypt failed")))
move_result = 0;
if(strstr(buf, "Key matching expected") ||
strstr(buf, "encryption failed") ||
strstr(buf, "sign+encrypt failed") ||
strstr(buf, "unknown keyid") ||
strstr(buf, "NO_PUBKEY")) {
char *keystr;
if(!tries) {
if(Config.getInt("pgpusekeyring", 0))
t |= KEYRING;
if(Config.getInt("pgpusehttp", 0))
t |= HTTP;
}
if((keystr = strstr(p, "0x")) == NULL)
keystr = (pgpvers == 263) ? p + 29 : p + 15;
if(pgpvers!=95 && strncmp(keystr, "0x", 2)) {
buf[0] = '\0';
if((n = read(errfd, buf, sizeof(buf) - 1)) > 0)
buf[n] = '\0';
if((keystr = strstr(buf, "0x")) == NULL)
keystr = "";
}
if((keyid = strtoul(keystr, NULL, 16)) == 0)
t &= ~HTTP;
if((tries == 0) && !(t & KEYRING) && !(t & HTTP))
display_msg(MSG_WARN, "PGP",
"Can not find key %s in public keyring",
keystr);
if(tries > 0)
display_msg(MSG_WARN, "PGP",
"Can not find key %s in both public and additional keyrings",
keystr);
p = NULL;
}
if(p) {
if((q = strchr(p, '\n')) != NULL) {
*q++ = '\0';
if((r = strchr(q, '\n')) != NULL)
*r = '\0';
while((*q < 32) && (*q != '\0'))
q++;
while((*p < 32) && (*p != '\0'))
p++;
if(strlen(q) > 80)
q[80] = '\0';
if(strlen(p) > 80)
p[80] = '\0';
display_msg(MSG_WARN, p, q);
} else {
while((*p < 32) && (*p != '\0'))
p++;
if(strlen(p) > 80)
p[80] = '\0';
display_msg(MSG_WARN,
"PGP Error (See Log for more details)",
p);
}
}
}
/* forget the pass phrase */
if((mode & (DECODE | SIGN | SIGNFL)) &&
(strstr(buf, "pass phrase") ||
strstr(buf, "passphrase") ||
strstr(buf, "BAD_PASSPHRASE")))
pgp_timer_cb();
}
close(pinfo.fd_err[0]);
if(pinfo.fd_out[0] != -1)
close(pinfo.fd_out[0]);
if(pinfo.fd_in[1] != -1)
close(pinfo.fd_in[1]);
check_extprocs();
for(n = 0; (pgpext == -100) && (n < PGP_TIMEOUT); n++) {
check_extprocs();
sleep(1);
}
if(pgpext == -100) { /* pgp is still running */
display_msg(MSG_WARN, "PGP", "Stuck PGP process");
if(pinfo.pid > 0)
kill(pinfo.pid, SIGKILL); /* nuke it */
move_result = 0;
} else /* pgp exit status was not 0 and not 1 (??) */
if((pgpext != 0) && (pgpext != 1)) {
display_msg(MSG_WARN, "PGP", "PGP terminated with status %d",
pgpext);
move_result = 0;
}
tries++;
}
if(move_result) {
if(mode & VRFYFL || mode & VERIFY)
return 0;
if(mode & SIGNFL)
return 0;
if(mode & EXTKEY)
return 0;
if(stat(nfile, &sb) == -1)
return -1;
if(sb.st_size == 0) {
display_msg(MSG_WARN, "PGP", "PGP produced no output");
unlink(nfile);
return -1;
}
if(do_move(nfile, inbuf) != 0) {
unlink(nfile);
return -1;
}
return 0;
} else
unlink(nfile);
return -1;
}
int is_pgp(char *file) {
FILE *pfd;
char buf[255];
if((pfd = fopen(file, "r")) == NULL)
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -