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

📄 pgpexit.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * pgpExit.c -- This code is for a runtime app.  It is *NOT* threaded,
 * in any sense of the word.  It stores state in static variables
 * and wipes system stack and heap when exiting from the application.
 *
 * Copyright (C) 1996,1997 Pretty Good Privacy, Inc.  All rights reserved.
 *
 * Written by:	Colin Plumb and Derek Atkins <warlord@MIT.EDU>
 *
 * $Id: pgpExit.c,v 1.4.2.4.2.7 1997/07/15 21:26:17 quark Exp $
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <signal.h>
#include <string.h>		/* For memset() */
#include <stdio.h>
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>		/* for getenv() */
#endif
#ifdef UNIX
#include <sys/types.h>		/* For sbrk() */
#elif defined(MSDOS)
#include <malloc.h>		/* For stackavail(), alloca() */
#if MSC_VER >= 800
/*
 * See flame elsewhere about Microsoft's stupid ideas about the name spaces
 * that are reserved by ANSI C if you do something undefined by ANSI like
 * include an undefined header (like <malloc.h>).
 */
#define alloca _alloca
#define stackavail _stackavail
#endif /* MSC_VER >= 800 */
#endif /* MSDOS */

#include "pgpExit.h"
#include "pgpKeyRings.h"
#include "pgpEnv.h"
#include "pgpRndPool.h"
#include "pgpRndSeed.h"
#include "pgpTimeDate.h"
#include "pgpVersion.h"
#include "pgpOutput.h"

static void *stack0 = NULL, *heap0 = NULL;
static struct PgpEnv *env0 = NULL;
static int program_name = 0;
static int newversion = 0;  /* whether keyrings should be rewritten as
			       latest version (1) or original version (0) */

/* Expiry date in days - defined for beta versions */
#define EXPIRY_DATE pgpDateFromYMD(1997, 12, 31)

/*
 * This usually returns, but will exit if this is an old beta version that
 * shouldn't be in use any more.
 */
void
exitExpiryCheck (struct PgpEnv *env)
{
#ifdef EXPIRY_DATE
	int tzFix = pgpenvGetInt (env, PGPENV_TZFIX, NULL, NULL);
        unsigned today = (unsigned)(pgpTimeStamp (tzFix)/86400);
        unsigned expires = EXPIRY_DATE;

        if (expires >= today) {
                expires -= today;
                if (expires < 30)
			fprintf (stderr,
"This beta version of PGP will expire in %u days\n", expires);
                return;
	}
	fputs ("\aThis beta evaluation version of PGP has expired.\n", stderr);
#if 0
        if (!getenv ("OVERRIDE_PGP_TIMEBOMB"))
                exitCleanup(PGPEXIT_VERSION);
#endif
#endif
}

void
exitUsage (int code)
{
	switch (program_name) {
	case EXIT_PROG_PGPE:
		fputs ("\n\
pgpe [[-r <recip1> -r <recip2>] [-s [-u <myid>]] | [-c]] [-afqtvz]\n\
     <file1> [-o outfile1] <file2> [-o <outfile2>]\n\
\n\
PGP Encrypt file(s)\n\
\n\
-a                ASCII armoring\n\
-c                Conventional Encryption (IDEA only; is mutually exclusive\n\
                  with -s, -u and -r)\n\
-f                Filter Mode; Read from stdin to stdout\n\
-o <output file>  Output file for most recent input file\n\
-q                Quiet mode\n\
-r <userid>       UserID to encrypt to.  May be specified multiple times.\n\
-s                Sign, as well as encrypt (use pgps to just sign).  If no\n\
                  userid is specified with -u, the default userid is used.\n\
-t                Text mode\n\
-u <userid>       UserID of the key you wish to sign with.  May only be\n\
                  specified once.\n\
-v                Verbose\n\
-z                Batch mode (assumes no user interaction; not yet\n\
                  implemented.\n\n\
--license         Display usage license\n\
Other programs in this suite include pgps to sign, pgpv to decrypt/verify,\n\
and pgpk for key management.\n", stdout);
		break;

	case EXIT_PROG_PGPS:
		fputs ("\n\
pgps [-u userid] [-bafqtvz] <file1> [-o <outfile> file2 [-o <outfile2>]]\n\
\n\
PGP Sign file(s)\n\
\n\
-a                ASCII armoring\n\
-b                Detached signature\n\
-f                Filter Mode; Read from stdin to stdout\n\
-o <output file>  Output file for most recent input file\n\
-q                Quiet mode\n\
-t                Text mode\n\
-u <userid>       UserID of the key you wish to sign with.  May only be\n\
                  specified once.  If not specified, your default signing\n\
                  key will be used.\n\
-v                Verbose\n\
-z                Batch mode (assumes no user interaction; not yet\n\
                  implemented.)\n\n\
--license         Display usage license\n\
Other programs in this suite include pgpe to encrypt, pgpv to\n\
decrypt/verify, and pgpk for key management.\n", stdout);
		break;

	    case EXIT_PROG_PGPV:
		fputs ("\n\
pgpv [-dfKmqvz] <file1> [-o <outfile> file2 -o <outfile2>]\n\
\n\
Decrypt/Verify PGP encrypted and/or signed file(s)\n\
\n\
-f                Filter Mode; Read from stdin to stdout\n\
-K                Do not process any keys that are present (normally pgpv\n\
                  will add keys to your keyring if found in an input file)\n\
-m                More Mode; display using pager rather than saving\n\
-o <output file>  Output file for most recent input file\n\
-q                Quiet mode\n\
-v                Verbose\n\
-z                Batch mode (assumes no user interaction; not yet\n\
                  implemented).\n\n\
--license         Display usage license\n\
Other programs in this suite include pgpe to encrypt, pgps to sign,\n\
and pgpk for key management.\n", stdout);
		break;

	    case EXIT_PROG_PGPO:
		fputs ("\n\
pgp_old [-dfKmqvz] <file1> [-o <outfile> file2 -o <outfile2>]\n\
\n\
Old-style PGP 2.6.2 emulation command-line\n\
\n\
--license         Display usage license\n\
Sadly, this isn't implemented yet.\n", stdout);
		break;

/*XXX Rewrite this to be more Unix-like*/
	case EXIT_PROG_PGPK:
		fputs ("\n"\
"Usage summary:  (for full details, see the User's guide)\n"\
"\n"\
"To generate your own unique public/private key pair:\n"\
"   pgpk -g [<userid> DSS|RSA <keysize> <userid> <validity> <passphrase>]\n"\
"To add a key file's contents to your public or private key ring:\n"\
"   pgpk -a keyfile [keyfile ...]\n"\
"To remove a key from your public and private key ring:\n"\
"   pgpk -r userid  (or pgpk -rk userid)\n"\
"To remove a user ID from your public and private key ring:\n"\
"   pgpk -ru userid\n"\
"To remove a signature from your public key ring:\n"\
"   pgpk -rs userid\n"\
"To edit your user ID or pass phrase:\n"\
"   pgpk -e your_userid\n"\
"To edit the confidence you have in a person as an introducer:\n"\
"   pgpk -e her_userid\n"\
"To extract (copy) a key from your public key ring:\n"\
"   pgpk -x userid -o keyfile\n"\
"To extract (copy) a key from your public key ring in ascii form:\n"\
"   pgpk -xa userid -o keyfile\n"\
"To list the contents of your key rings:\n"\
"   pgpk -l[l] [userid]\n"\
"To check signatures on your public key ring:\n"\
"   pgpk -c [userid]\n"\
"To sign someone else's public key on your public key ring:\n"\
"   pgpk -s her_userid [-u your_userid]\n"\
"To disable or re-enable some else's public key on your public key ring:\n"\
"   pgpk -d her_userid\n"\
"To permanently revoke your own key on your public and private key rings:\n"\
"   pgpk --revoke your_userid\n"\
"To revoke a signature you made on someone else's key on your pub key ring:\n"\
"   pgpk --revokes your_userid\n"\
"To view the license granted you:\n"\
"   pgpk --license\n"\
"", stdout);
		break;
	default:
		fputs ("\n\
Usage summary unavailable for this program.\n\
\n", stdout);
		break;
	}

	exitCleanup(code);
}

/* attribute(x) expands to nothing unless __GNUC__ is defined. */
static void exitWipe(int code) attribute((noreturn));
static void exitWipe1(int code, void *base) attribute((noreturn));

#ifdef MSDOS

#include <dos.h>	/* FOR MK_FP, FP_SEG and FP_OFF */
#include <malloc.h>	/* for alloca(), stackavail(), _heapwalk() */
/*
 * Now, Microsoft has recently developed a habit of prepending an underscore
 * to the beginning of everything.  They wave their arms and mutter about ANSI.
 * If they have a really broken linker then I can see how they might not be
 * able to deal with user code declaring functions that are also supplied in
 * the library, so they need to put the functions in a name space that user
 * code can't declare in, BUT THIS SURE DOESN'T APPLY TO MACROS.  For any
 * header *not* defined by ANSI (such as, say, <dos.h>, <conio.h>, <io.h>,
 * <unistd.h>, <sys/types.h>, etc.), any structures, unions, macros, enums,
 * and so on - anything not visible to the linker - can be defined any
 * way you like.
 *
 * So I don't understand Microsoft.  Defining prefix-prepended aliases
 * for library-internal calls is fine (so my extern variable "write"
 * won't get called when I call printf()), but to get rid of more convenient
 * names if I *do* include the relevant file?  Wierd.
 */

#ifndef MK_FP
#ifdef _MK_FP
#define MK_FP _MK_FP
#else
#define MK_FP(seg,off) ((void __far *)((seg)<<16 | (off)))
#endif
#endif /* !MK_FP */

#ifndef FP_SEG
#ifdef _FP_SEG
#define FP_SEG _FP_SEG
#else
#define FP_SEG(ptr) ((unsigned)((unsigned long)(ptr) >> 16))
#endif
#endif /* !FP_SEG */

#ifndef FP_OFF
#ifdef _FP_OFF
#define FP_OFF _FP_OFF
#else
#define FP_OFF(ptr) ((unsigned)(ptr))
#endif
#endif /* !FP_OFF */

#if MSC_VER >= 800
#define alloca _alloca
#define stackavail _stackavail
#endif

static void
exitWipe1(int code, void *base)
{
	int status;

	/* Wipe the stack */
	if (stack0)
		memset(base, 0, (char *)(stack0)-(char *)base);
#ifdef UNIX
	/* ACHTUNG!  This code might be dangerous */
	{
		struct _heapinfo info;
		/* Wipe the heap */
		/* First pass - initial wipe with 0xff */
		_heapset(0xff);
		info._pentry = 0;
		while (_heapwalk(&info) == _HEAPOK) {
			if (info._useflag == _USEDENTRY) {
				memset(info._pentry, 0xff, info._size);
				free(info._pentry);
				/* free() mucks up _heapwalk, so restart */
				info._pentry = 0;
			}
		}
		/* Second pass - wipe all free areas */
		_heapset(0);
	}
#endif /* UNIX */
	exit(code);
}

#if __BORLANDC__
#if __BORLANDC <= 0x0400
unsigned _stklen = 16384;
#else
unsigned const _stklen = 16384;
#endif
#endif

static void
exitWipe(int code)
{
	exitWipe1(code, alloca(stackavail()-500));
}

#else	/* !MSDOS */

static void
exitWipe1(int code, void *base)
{
	/* Wipe the stack */
	if (stack0)
		memset(base, 0, ((char *)(stack0)-(char *)base));

#if 0	/* Disabled until stdio problems can be resolved */
	/* Wipe the heap */
	if (heap0) {
		base = sbrk(0);
		memset(heap0, 0, (char *)base-(char *)heap0);
	}
#endif
#ifdef VMS /* On VMS, the bottom 3 bits are a severity */
	code = (1<<28) | (code << 3) | (1 + (code != 0));
#endif
	exit(code);

⌨️ 快捷键说明

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