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

📄 pgp.cpp

📁 pgpencrypt.rar
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -