📄 pgp.cpp
字号:
#include <fmail.h>
#include <pgp.h>
#include "addrbook_util.h"
static char *get_pgp263_command_line(int, struct pgpargs *, char *, int);
static char *get_pgp500_command_line(int, struct pgpargs *, char *, int);
static char *get_pgp651_command_line(int, struct pgpargs *, char *, int);
static char *get_gpg_command_line(int, struct pgpargs *, char *, int);
char *phrase = NULL; /* scrambled passphrase */
static int pgpext; /* PGP exit status */
void pgp_timer_cb() {
char *p;
if(phrase) {
p = phrase;
while(*p)
*p++ = '\0';
free(phrase);
phrase = NULL;
}
}
void pgp_cleanup(struct _proc_info *pinfo) {
pgpext = pinfo->status;
}
void scramble(char *string) {
unsigned char *p;
if(!string)
return;
p = (unsigned char *) string;
while(*p != '\0') {
if(*p != 0xaa)
*p = *p ^ 0xaa;
p++;
}
return;
}
void init_pgpargs(struct pgpargs *pargs) {
pargs->userid = NULL;
pargs->recp = NULL;
pargs->passphrase = NULL;
pargs->msg = NULL;
}
void pgp_init(struct _proc_info *pinfo) {
putenv("PGPPASSFD=0"); /* see pgp/doc/appnote.doc */
}
int pgp_fetch_key_from_http(char *host, unsigned int keyid) {
int sock, n, res = 0, keyfound = 0;
char buf[256], kfile[256], pbuf[32];
FILE *kfd;
if((sock = ConMan.host_connect(host, "11371", NULL)) == -1)
return -1;
/* HKP (Horowitz Key Protocol) */
snprintf(buf, sizeof(buf),
"GET /pks/lookup?op=get&exact=on&search=0x%X HTTP/1.0\n",
keyid);
strcat(buf, "User-Agent: XFMail (Unix)\n\r\n\r");
if(send(sock, buf, strlen(buf), 0) == -1)
return -1;
strcpy(kfile, get_temp_file("pgphttp"));
if((kfd = fopen(kfile, "w")) == NULL) {
display_msg(MSG_WARN, "PGP keyserver (HKP)",
"Can not create temp. file %-.64s", kfile);
ConMan.del_cinfo(sock);
return -1;
}
*pbuf = '\0';
do {
if((n = my_check_io_forms(sock, 0, SOCKET_TIMEOUT)) < 0) {
if(n == -2)
display_msg(MSG_WARN, "PGP keyserver (HKP)",
"transfer aborted");
res = -1;
break;
}
if((n = recv(sock, buf, sizeof(buf), 0)) == -1) {
display_msg(MSG_WARN, "PGP keyserver (HKP)", "recv() failed");
res = -1;
break;
}
if(n > 0) {
fwrite(buf, n, 1, kfd);
buf[n] = '\0';
if(!keyfound) {
if(strstr(buf, "BEGIN PGP")) {
keyfound = 1;
*pbuf = '\0';
continue;
} else {
strncat(pbuf, buf, 10);
if(strstr(pbuf, "BEGIN PGP")) {
keyfound = 1;
*pbuf = '\0';
continue;
}
strcpy(pbuf, buf + (n > 10 ? n - 10 : n));
}
}
}
} while(n > 0);
ConMan.del_cinfo(sock);
fclose(kfd);
if((res == 0) && (keyfound == 0)) {
display_msg(MSG_WARN, "PGP keyserver (HKP)",
"Key 0x%X was not found in public keyring(s) and on server %s",
keyid, host);
unlink(kfile);
return -1;
}
if(res == 0) {
if(pgp_action(kfile, EXTKEY, NULL) == -1) {
unlink(kfile);
return -1;
}
display_msg(MSG_MSG, "PGP keyserver (HKP)",
"Fetched and extracted PGP public key 0x%X from %s",
keyid, host);
}
unlink(kfile);
return res;
}
static char *get_pgp_command_line(int mode, struct pgpargs *pargs,
char *inbuf, int t) {
switch(Config.getInt("pgpversion", PGP_DEFAULT_VERS)) {
case 263:
return get_pgp263_command_line(mode, pargs, inbuf, t);
break;
case 500:
return get_pgp500_command_line(mode, pargs, inbuf, t);
break;
case 651:
return get_pgp651_command_line(mode, pargs, inbuf, t);
break;
case 95:
return get_gpg_command_line(mode, pargs, inbuf, t);
break;
default:
display_msg(MSG_WARN, "PGP", "Unknown PGP version: %d",
Config.getInt("pgpversion", PGP_DEFAULT_VERS));
}
return NULL;
}
static char *get_pgp500_command_line(int mode, struct pgpargs *pargs,
char *inbuf, int t) {
char args[1024];
const char pgpparm[] = "+language=en +verbose=1 +clearsig=on";
char pubring[255] = "";
char *pgpprg;
struct _mail_addr *addr, *addr1;
if(!(t & NORMAL) && (t & KEYRING))
snprintf(pubring, sizeof(pubring), "+pubring=%s",
Config.get("pgpkeyring", "").c_str());
pgpprg = strdup(Config.get("pgp", _PATH_PGP).c_str());
if(pargs && (pargs->userid == NULL)) {
if((mode & (SIGN | SIGNFL)) && pargs->msg
&& pargs->msg->header->From) {
addr = pargs->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
pargs->userid = addr->pgpid;
}
if(pargs->userid == NULL)
pargs->userid = const_cast<char *>(Config.get("pgpuser", user_n).c_str());
}
if((mode & ENCODE) && (mode & SIGN))
snprintf(args, sizeof(args),
"%se %s +batchmode +NoBatchInvalidKeys=off -fat %s -su %s ",
pgpprg, pgpparm, pargs->recp, pargs->userid);
else if(mode & ENCODE)
snprintf(args, sizeof(args),
"%se %s +batchmode +NoBatchInvalidKeys=off -fat %s",
pgpprg, pgpparm, pargs->recp);
else if(mode & SIGN)
snprintf(args, sizeof(args), "%ss %s +batchmode -fatu %s ", pgpprg,
pgpparm, pargs->userid);
if(mode & SIGNFL) {
snprintf(args, sizeof(args), "%ss %s +batchmode -fatbu %s", pgpprg,
pgpparm, pargs->userid);
if(pargs->recp == NULL) {
free(pgpprg);
return NULL;
}
}
if(mode & (DECODE | VERIFY))
snprintf(args, sizeof(args), "%sv %s +batchmode %s -f", pgpprg,
pgpparm, pubring);
if(mode & EXTKEY)
snprintf(args, sizeof(args), "%sk %s +batchmode -a %s", pgpprg,
pgpparm, inbuf);
if(mode & ADDKEY)
snprintf(args, sizeof(args), "%sk %s -xa %s", pgpprg, pgpparm,
pargs->recp);
if(mode & VRFYFL)
snprintf(args, sizeof(args), "%sv %s +batchmode %s %s -o %s",
pgpprg, pgpparm, pubring, pargs->recp, inbuf);
free(pgpprg);
return strdup(args);
}
static char *get_pgp651_command_line(int mode, struct pgpargs *pgpargs,
char *inbuf, int t) {
char args[1024];
char pubring[2048] = "";
const char pgpparm[] = "+language=en +verbose=1 +force +clearsig=on";
char *pgpprg;
struct _mail_addr *addr, *addr1;
if(!(t & NORMAL) && (t & KEYRING))
snprintf(pubring, sizeof(pubring), "+pubring=%s",
Config.get("pgpkeyring", "").c_str());
pgpprg = strdup(Config.get("pgp", _PATH_PGP).c_str());
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());
}
if((mode & ENCODE) && (mode & SIGN))
snprintf(args, sizeof(args), "%s %s +batchmode -fates %s -u %s",
pgpprg, pgpparm, pgpargs->recp, pgpargs->userid);
else if(mode & ENCODE) /* seems to work with 6.5.8 without +batchmode */
snprintf(args, sizeof(args), "%s %s -fate %s", pgpprg, pgpparm,
pgpargs->recp);
else if(mode & SIGN)
snprintf(args, sizeof(args), "%s %s +batchmode -fats -u %s", pgpprg,
pgpparm, pgpargs->userid);
if(mode & SIGNFL) {
snprintf(args, sizeof(args), "%s %s +batchmode -fatbs -u %s", pgpprg,
pgpparm, pgpargs->userid);
if(pgpargs->recp == NULL) {
free(pgpprg);
return NULL;
}
}
if(mode & (DECODE | VERIFY))
snprintf(args, sizeof(args), "%s %s +batchmode %s -f", pgpprg,
pgpparm, pubring);
if(mode & EXTKEY)
snprintf(args, sizeof(args), "%s %s +batchmode -fka", pgpprg,
pgpparm);
if(mode & ADDKEY)
snprintf(args, sizeof(args), "%s %s -f -kxa %s", pgpprg, pgpparm,
pgpargs->recp);
if(mode & VRFYFL)
snprintf(args, sizeof(args), "%s %s +batchmode %s %s %s",
pgpprg, pgpparm, pubring, pgpargs->recp, inbuf);
free(pgpprg);
return strdup(args);
}
static char *get_pgp263_command_line(int mode, struct pgpargs *pgpargs,
char *inbuf, int t) {
char args[1024];
char pubring[255] = "";
const char pgpparm[] = "+language=en +verbose=1 +clearsig=on";
char *pgpprg;
struct _mail_addr *addr, *addr1;
if(!(t & NORMAL) && (t & KEYRING))
snprintf(pubring, sizeof(pubring), "+pubring=%s",
Config.get("pgpkeyring", "").c_str());
pgpprg = strdup(Config.get("pgp", _PATH_PGP).c_str());
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());
}
if((mode & ENCODE) && (mode & SIGN))
snprintf(args, sizeof(args), "%s %s +batchmode -fate %s -su %s ",
pgpprg, pgpparm, pgpargs->recp, pgpargs->userid);
else if(mode & ENCODE)
snprintf(args, sizeof(args), "%s %s -fate %s", pgpprg, pgpparm,
pgpargs->recp);
else if(mode & SIGN)
snprintf(args, sizeof(args), "%s %s +batchmode -fatsu %s ", pgpprg,
pgpparm, pgpargs->userid);
if(mode & SIGNFL) {
snprintf(args, sizeof(args), "%s %s +batchmode -fatbsu %s", pgpprg,
pgpparm, pgpargs->userid);
if(pgpargs->recp == NULL) {
free(pgpprg);
return NULL;
}
}
if(mode & (DECODE | VERIFY))
snprintf(args, sizeof(args), "%s %s +batchmode %s -f", pgpprg,
pgpparm, pubring);
if(mode & EXTKEY)
snprintf(args, sizeof(args), "%s %s +batchmode -f -ka", pgpprg,
pgpparm);
if(mode & ADDKEY)
snprintf(args, sizeof(args), "%s %s -f -kxa %s", pgpprg, pgpparm,
pgpargs->recp);
if(mode & VRFYFL)
snprintf(args, sizeof(args), "%s %s +batchmode %s %s %s",
pgpprg, pgpparm, pubring, pgpargs->recp, inbuf);
free(pgpprg);
return strdup(args);
}
static char *get_gpg_command_line(int mode, struct pgpargs *pgpargs,
char *inbuf, int t) {
char args[1024];
const char pgpparm[] =
"-t --yes --always-trust --quiet --no-greeting --status-fd 2";
const char gpgsuppl[]= "--passphrase-fd 0";
/* --passphrase-fd 0 needed only when it's needed */
char pubring[255] = "";
char *pgpprg;
struct _mail_addr *addr, *addr1;
if(!(t & NORMAL) && (t & KEYRING))
snprintf(pubring, sizeof(pubring), "--keyring=%s",
Config.get("pgpkeyring", "").c_str());
pgpprg = strdup(Config.get("pgp", _PATH_PGP).c_str());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -