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

📄 pgpuserio.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 3 页
字号:
	char pass[256];
	int i, err, len;
	byte pkalg;
	byte const *keyid;

	StatusOutput(TRUE, "MESSAGE_IS_ENCRYPTED");
	for (esk = esklist; esk; esk = pgpEskNext (esk)) {
		switch (pgpEskType (esk)) {
		case PGP_ESKTYPE_PASSPHRASE:
			if (ui->passcache) {
				err = pgpPassCacheTryEsk (ui->passcache,
							esk, tryKey, tryarg,
					 		key, keylen);
				if (err > 0)
					return 0; /* success */

				/* Ignore errors, err < 0 */
			}

			/*XXX Add code to get passphrase in batchmode*/
			i = 3;
			while (i--) {
			    len = pgpTtyGetPass(ui->showpass,
						pass,
						sizeof (pass));
				err = pgpEskConvDecrypt (esk, ui->env,
							 pass, len, key);
				*keylen = err;

				if (err >= 0)
					err = tryKey (tryarg, key, *keylen);

				if (!err) {
					if (ui->passcache)
						pgpPassCacheAdd (ui->passcache,
								pass, len);
					memset (pass, 0, sizeof (pass));
					return 0;
				}
				memset (pass, 0, sizeof (pass));
				InteractionOutput(TRUE,
						  "PASSPHRASE_INCORRECT");

				if (i) {
				    InteractionOutputString(FALSE, "  ");
				    InteractionOutput(FALSE, "TRY_AGAIN");
				}
				InteractionOutputString(FALSE, "\n");
			}
			break;

		case PGP_ESKTYPE_PUBKEY:
			keyid = pgpEskId8 (esk);
			pkalg = pgpEskPKAlg (esk);
#if 0 /*Obsolete - BAT 19970609*/
			if (!memcmp (keyid, fixedKeyID, 8))
				seckey = fixedKeySec ();
			else
#endif
			if (ui->ringset) {
				ringobj = ringKeyById8 (ui->ringset,
							pkalg,
							keyid);
				if (!ringobj)
					break;
				seckey = ringSecSecKey (ui->ringset,
							ringobj,
							PGP_PKUSE_ENCRYPT);
				ringObjectRelease (ringobj);
			}
			else
				break;

			if (!seckey)
				break;

			if (! seckey->decrypt) {
				/* Can't decrypt with this key */
				pgpSecKeyDestroy (seckey);
				break;
			}

			/* XXX need to make sure seckey is unlocked */
			err = pgpTtyUnlockSeckey (arg, ringobj, seckey, NULL);
			if (err) {
				pgpSecKeyDestroy (seckey);
				break;
			}

			err = pgpEskPKdecrypt (esk, ui->env, seckey, key);
			*keylen = err;
			pgpSecKeyDestroy (seckey);

			if (err <= 0)
				break;

			err = tryKey (tryarg, key, *keylen);
			if (!err)
				return 0;

			break;

		default:
		    ErrorOutput(TRUE,
				LEVEL_INFORMATION,
				"UNKNOWN_ESK",
				pgpEskType(esk));
		    break;
		}
	}
	/*
	 * At this point, none of the PgpESKs have been decrypted, so let's
	 * inform the user that we failed.
	 */

	InformationOutput(TRUE, "CANNOT_DECRYPT");

	for (esk = esklist; esk; esk = pgpEskNext (esk)) {
		switch (pgpEskType (esk)) {
		case PGP_ESKTYPE_PASSPHRASE:
		    InformationOutputString(FALSE, "  ");
		    InformationOutput(FALSE, "A_PASSPHRASE");
			break;
		case PGP_ESKTYPE_PUBKEY:
			keyid = pgpEskId8 (esk);
			pkalg = pgpEskPKAlg (esk);
			if (ui->ringset) {
				ringobj = ringKeyById8 (ui->ringset, pkalg,
							keyid);
				if (ringobj) {
					ringKeyPrint(OUTPUT_INFORMATION,
						     ui->ringset,
						     ringobj, 1);
					ringObjectRelease (ringobj);
				} else {
					pgpTtyPutKeyID (keyid);
				}
			} else {
			    InformationOutputString(FALSE, "  ");
			    InformationOutput(FALSE, "KEY_ID");
			    pgpTtyPutKeyID (keyid);
			}
		}
	}
	InformationOutputString(FALSE, "\n");
	return PGPANN_PARSER_EATIT;
}

/* Check if file already exists, and whether it is OK to overwrite it.
   If +force, no check is made and any existing file will be overwritten.
   If +batchmode (but not +force), the default answer is always do not
   overwrite. */

int
pgpTtyCheckOverwrite (struct PgpEnv const *env, char const *name)
{
        FILE *fp;
	int status = 0;

	if (!pgpenvGetInt (env, PGPENV_FORCE, NULL, NULL)) {
	        fp = fopen (name, "r");
		if (fp) {
		        fclose (fp);

			if (pgpenvGetInt (env, PGPENV_BATCHMODE,
					  NULL, NULL)) {
			    WarningOutput(TRUE,
					  LEVEL_INFORMATION,
					  "USE_FORCE_TO_ALLOW_OVERWRITING");
			    status = PGPERR_NO_FILE;
			}
			else {
			    InteractionOutput(TRUE,
					      "FORCE_OVERWRITE",
					      name);
			    if (!pgpTtyGetBool (0, 1))
				  status = PGPERR_NO_FILE;
			}

		}
	}
	if (status)
	    ErrorOutput(TRUE,
			LEVEL_SEVERE,
			"UNABLE_TO_OVERWRITE_FILE",
			name);
	
	return status;
}

/*This checks for existance of /dev/random (or whatever is configured in the
 *appropriate PGP variable).  We place the name of the device we checked in
 *in RandomDevice (allocating, first); the caller is responsible for
 *deallocation with pgpFree().  Returns TRUE if /dev/random is there, FALSE
 *if it is not.  RandomDevice may be NULL if you don't care what the device
 *is, only if it exists.  Note also that this function will alert the user if
 *the requested device is world-writable.
 */
static Boolean CheckDevRandom(char **RandomDevice, PgpTtyUI *ui)
{
    char *DeviceToUse, *prefDevRandom;
    Boolean HasDevRandom = TRUE;
    FILE *fDev = NULL;
#ifdef HAVE_SYS_STAT_H
    /*This is the preferred method, but it may not be universally portable,
     *so I've implemented a less-than-desirable check below using definitely
     *available functions.
     */
    struct stat stat_buf;
#endif

    prefDevRandom = (char *)
	pgpenvGetString(ui->env, PGPENV_RANDOMDEVICE, NULL, NULL);

    if(!prefDevRandom)
	prefDevRandom = (char *) "/dev/random";

    if(strcmp(prefDevRandom, "/dev/random") != 0) {
	WarningOutput(TRUE,
		      LEVEL_INFORMATION,
		      "RANDOM_DEVICE_NOT_DEFAULT",
		      "/dev/random");
    }

    if(RandomDevice) {
	*RandomDevice = pgpAlloc(sizeof(char) * (strlen(prefDevRandom) + 1));
	strcpy(*RandomDevice, prefDevRandom);
    }

    if(RandomDevice && *RandomDevice) {
	DeviceToUse = *RandomDevice;
    }
    else {
	DeviceToUse = (char *) prefDevRandom;
    }

#ifdef HAVE_SYS_STAT_H
    if(stat(DeviceToUse, &stat_buf) == 0) {
	/*Check for world-writable /dev/random and warn the user:*/
	if(((stat_buf.st_mode & S_IRWXO) == S_IRWXO) ||
	   ((stat_buf.st_mode & S_IRWXG) == S_IRWXG)) {
	    WarningOutput(TRUE,
			  LEVEL_SEVERE,
			  "RANDOM_DEVICE_WRITABLE",
			  DeviceToUse);
	}
    }
    else {
	HasDevRandom = FALSE;
    }
#endif

    /*People who don't have sys/stat.h miss out on the check of permissions,
     *above. People who do have sys/stat.h still execute this code, to make
     *sure we can actually READ the random device. sys/stat.h people who
     *have random devices they can't read get a warning.
     *
     *People who don't have sys/stat.h are just generally in trouble.
     */
    if(HasDevRandom) {
	if((fDev = fopen(DeviceToUse, "r"))) {
	    fclose(fDev);
	    HasDevRandom = TRUE;
	}
	else {
#if HAVE_SYS_STAT_H
	    ErrorOutput(TRUE,
			LEVEL_INFORMATION,
			"RANDOM_DEVICE_UNREADABLE",
			DeviceToUse);
#endif
	    HasDevRandom = FALSE;
	}
    }

    return(HasDevRandom);
}

/* /dev/random did basically what /dev/urandom does now in Linux
 *kernels < 1.3.33. My best research to date indicates that the
 *modern /dev/random, with no bugs large enough to limit its
 *cryptographic utility, cames to be in this kernel version. Note
 *that I haven't examined every patch from 1.3.33 - 1.2.0, but
 *this is my current information (and I'd love to hear about it
 *if I'm incorrect).
 *
 *Basically, what we want to do is check what Linux version we're
 *running (from /proc/version).  I'm sure there is some more Linux-
 *specific way to do this, but checking /proc/version will work on
 *systems that aren't Linux (since the check will just fail).
 *
 */
static Boolean
VerifyRandomDevOSVersion(void)
{
    FILE *inf;
    Boolean VersionIsOK = TRUE;
    char VersionBuf[256], *p;
    unsigned short major = 0, minor = 0, release = 0;

    if((inf = fopen("/proc/version", "r"))) {
	fgets(VersionBuf, sizeof(VersionBuf), inf);
	/*This string is of the form "Linux version Major.Minor.Release.*/
	if(strncasecmp(VersionBuf, "Linux version ", 14) == 0) {

	    p = VersionBuf;
	    /*Skip the leading text:*/
	    while(*p && !isdigit(*p))
		++p;

	    major = atoi(p);

	    /*If major >= 2, we know we're OK, if it's 0, we know we're not.*/
	    if(major == 1) {
		/*Skip the major number and dot:*/
		while(*p && isdigit(*p))
		    ++p;

		if(*p) {
		    ++p;
		    minor = atoi(p);

		    /*If here, we know it's 1.x.y.  If x < 3, we know it's
		     *bad; if > 3, we know it's good.*/
		    if(minor == 3) {
			/*Ok, it's 1.3.y, so we have to actually find out the
			 *minor version to see if it's OK.*/
			/*Skip the minor number and dot:*/

			while(*p && isdigit(*p)) {
			    ++p;
			}
			if(*p) {
			    release = atoi(p);
			}
		    }
		}
	    }

	    if(major <= 1 && minor <= 3 && release <= 32) {
		VersionIsOK = FALSE;
	    }
	}
    }

    return(VersionIsOK);
}


/*This adds count bytes from RandomDevice (usually "/dev/random") to the
 *random pool.
 */
static unsigned
pgpDevRandomAccum(int fd, unsigned count)
{
    char RandBuf;
    unsigned short i = 0;

    pgpAssert(count);
    pgpAssert(fd >= 0);

    for(i = 0; i <= count; ++i) {
	RandBuf = read(fd, &RandBuf, count);
	pgpRandomAddBytes(&pgpRandomPool, (byte *)&RandBuf, sizeof(RandBuf));
	pgpRandPoolAddEntropy(256);
    }

    return(i);
}

/* Assumes the message string is in printf format */
int
pgpTtyMessage (void *arg, int type, int msg, unsigned numargs, ...)
{
	struct PgpTtyUI *ui = (struct PgpTtyUI *)arg;
	struct PgpUICbArg const *msgarg;
	char const *string, *ptr;
        va_list ap;

	if (type > ui->verbose)
		return 0;

	string = pgpmsgString (msg);
	va_start (ap, numargs);

	while ((ptr = strchr(string, '%')) != NULL) {
		/* Print part of string leading up to % */
		fwrite (string, 1, ptr-string, ui->fp);

		if (*++ptr == '%') {
			putc ('%', ui->fp);
			string = ptr+1;
			continue;
		}
		pgpAssert (numargs--);
		msgarg = va_arg (ap, struct PgpUICbArg const *);
		switch (*ptr++) {
		case 'd': /* int */
			pgpAssert (msgarg->type == PGP_UI_ARG_INT);
			fprintf (ui->fp, "%d", msgarg->val.i);
			break;
		case 'l': /* unsigned long (word32) */
			pgpAssert(*ptr == 'u');
			ptr++;
			pgpAssert (msgarg->type == PGP_UI_ARG_WORD32);
			fprintf (ui->fp, "%lu",
					(unsigned long)msgarg->val.w32);
			break;
		case 'u': /* unsigned */
			pgpAssert (msgarg->type == PGP_UI_ARG_UNSIGNED);
			fprintf (ui->fp, "%u", msgarg->val.u);
			break;
		case 's': /* string */
			pgpAssert (msgarg->type == PGP_UI_ARG_STRING);
			fprintf (ui->fp, "%s", msgarg->val.s);
			break;
		case '.': /* buffer (%.*s) */
			pgpAssert (*ptr == '*' && ptr[1] == 's');
			ptr += 2;
			pgpAssert (msgarg->type == PGP_UI_ARG_BUFFER);
			fprintf (ui->fp, "%.*s",
				 (int)msgarg->val.buf.len,
				 msgarg->val.buf.buf);
			break;
		default:
			pgpAssert (0);
		}
		string = ptr;
	}
	/* Print trailing segment of string */
	fputs (string, ui->fp);
	putc('\n', ui->fp);

	return 0;
}	

⌨️ 快捷键说明

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