ptupdate.c

来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C语言 代码 · 共 1,105 行 · 第 1/2 页

C
1,105
字号
/*__________________________________________________________________________
 Copyright (C) 2002 PGP Corporation
 All rights reserved.
 
 $Id: PTupdate.c,v 1.42 2002/10/31 04:13:36 pbj Exp $
__________________________________________________________________________*/
#include "pgpPFLConfig.h"
#include "precomp.h"
#include <time.h>
#include <process.h>

#include "PTupdate.h"
#include "PTprefs.h"
#include "pgpClientLib.h"
#include "pgpClientPrefs.h"
#include "pgpNetPrefs.h"
#include "pgpUtilities.h"
#include "pgpThreads.h"
#include "pgpFileSpec.h"
#include "pgpWin32Errors.h"

#define CKERR		if (IsPGPError (err)) goto done

#define THREAD_INTERVAL			120000		// 2 minutes in milliseconds
#define UPDATE_INTERVAL			8			// 16 minutes in 2 minute intervals
#define REQUEST_TIMEOUT			345600		// 4 days in seconds
#define TOMORROW_INTERVAL		86400		// 1 day in seconds
#define MAX_ERROR_COUNT			3			// max number of errors before 
											//  we suspend further attempts

static HANDLE		s_heventKill				= NULL;
static HANDLE		s_hthreadUpdate				= NULL;
static LPSTR		s_pszPhrase					= NULL;
static PGPByte*		s_pPasskey					= NULL;
static PGPSize		s_sizePasskey				= 0;
static BOOL			s_bAutoRetrieveSuspended	= FALSE;


//	__________________________________________________________
//
//  Schedule the next CRL update

static PGPError
sScheduleNextCRLUpdate (
		PGPContextRef	context, 
		PGPKeyDBRef		keydbMain)
{
	PGPError	err					= kPGPError_NoErr;

	PGPPrefRef			prefref		= kInvalidPGPPrefRef;

	PGPKeyDBObjRef		keyRootCA;
	PGPKeyDBObjRef		sigRootCA;
	PGPBoolean			bAutoUpdate;
	PGPBoolean			bHasCRL;
	PGPUInt32			uNextUpdate;

	if(PGPlnEnterprise())
	{
		err = PTPeekPrefRefs (&prefref, NULL); CKERR;
		err = PGPGetPrefBoolean (prefref, 
				kPGPPrefAutoUpdateX509CRL, &bAutoUpdate); CKERR;
		if (bAutoUpdate)
		{
			err = PGPclGetRootCACertPrefs (context, 
					prefref, keydbMain, &sigRootCA); CKERR;
			keyRootCA = PGPPeekKeyDBObjKey (sigRootCA);

			err = PGPGetKeyDBObjBooleanProperty (keyRootCA, 
					kPGPKeyProperty_HasCRL, &bHasCRL); CKERR;

			if (bHasCRL)
			{
				err = PGPGetKeyDBObjTimeProperty (keyRootCA, 
						kPGPKeyProperty_CRLNextUpdate, &uNextUpdate); CKERR;

				err = PGPSetPrefNumber (prefref, 
						kPGPPrefNextAutoCRLUpdate, uNextUpdate); CKERR;

				err = PTFlushPrefs (prefref, NULL);
			}
			CKERR;
		}
	}
done:
	return err;
}


//	____________________________________
//
//	Auto update all keys in keyring

static PGPError 
sAutoUpdateAllKeys (
		PGPContextRef		context,
		PGPtlsContextRef	tlscontext,
		PGPKeyDBRef			keydbMain) 
{
	PGPError		err					= kPGPError_NoErr;
	PGPKeyDBRef		keydbUpdated		= kInvalidPGPKeyDBRef;
	PGPKeySetRef	keysetUpdated		= kInvalidPGPKeySetRef;

	// update entire keyset from key-based server
	err = PGPclUpdateKeySetFromServer (context, tlscontext, NULL, 
			PGPPeekKeyDBRootKeySet (keydbMain), kPGPclUserIDBasedServer, 
			keydbMain, &keydbUpdated);

	// if we got updated keys, query user and commit the changes
	if (IsntPGPError (err) &&
		PGPKeyDBRefIsValid (keydbUpdated)) 
	{
		keysetUpdated = PGPPeekKeyDBRootKeySet (keydbUpdated);

		err = PGPCopyKeys (keysetUpdated, keydbMain, NULL);
	}

	if (PGPKeyDBRefIsValid (keydbUpdated))
		PGPFreeKeyDB (keydbUpdated);

	return err;
}


//	____________________________________
//
//	check if update is due

static BOOL 
sCheckForUpdate (
		PGPPrefRef			prefref,
		PGPUInt32			uIndexDays,
		PGPUInt32			uIndexLastUpdate)
{
	PGPUInt32		uDays			= 0;
	PGPUInt32		uLastUpdate		= 0;

	time_t			tLastUpdate;
	time_t			tToday;
	struct tm 		tmToday;
	struct tm 		tmLastUpdate;

	PGPGetPrefNumber (prefref, uIndexDays, &uDays);

	if (uDays > 0)
	{
		tToday = PGPGetStdTimeFromPGPTime (PGPGetTime());

		PGPGetPrefNumber (prefref, uIndexLastUpdate, &uLastUpdate);
		tLastUpdate = PGPGetStdTimeFromPGPTime (uLastUpdate);

		if (tToday < tLastUpdate)
			return TRUE;

		memcpy (&tmToday, localtime(&tToday), sizeof(struct tm));
		memcpy (&tmLastUpdate, localtime (&tLastUpdate),
					sizeof(struct tm));

		if (tmToday.tm_year > tmLastUpdate.tm_year)
			tmToday.tm_yday += 366;

		if ((tmToday.tm_yday - tmLastUpdate.tm_yday) >= (INT)uDays)
			return TRUE;
	}

	return FALSE;
}


//	____________________________________
//
//	check if user wants to continue auto cert retrieval attempts

static BOOL 
sContinueAutoRetrieval (VOID)
{
	CHAR	szText[512];
	CHAR	szCaption[32];

	LoadString (g_hinst, IDS_CONTINUERETRIEVALS, szText, sizeof(szText));
	LoadString (g_hinst, IDS_CAPTION, szCaption, sizeof(szCaption));

	return (IDYES == MessageBox (NULL, 
			szText, szCaption, 
			MB_YESNO|MB_DEFBUTTON2|MB_ICONINFORMATION|MB_SYSTEMMODAL));
}


//	___________________________________________________
//
//	attempt the certificate retrieval

static PGPError
sAttemptRetrieval (
	PGPContextRef		context,
	PGPtlsContextRef	tlscontext,
	PGPKeyDBRef			keydbMain,
	PGPKeyDBRef*		pkeydb)
{
	PGPError		err;
	PGPKeySetRef	keyset;
	PGPKeyDBObjRef	key;
	PGPKeyDBObjRef	userid;
	PGPPrefRef		prefref;
	PGPByte*		pbyte;
	PGPSize			size;


	err = PTPeekPrefRefs (&prefref, NULL);
	if (IsntPGPError (err))
	{
		err = PGPGetPrefData (prefref, 
				kPGPPrefRequestedCertKeyID, &size, &pbyte);

		if (IsntPGPError (err))
		{
			err = PGPFindKeyByKeyID (keydbMain, (PGPKeyID*)pbyte, &key);
			PGPFreeData (pbyte);

			if (IsntPGPError (err))
			{
				if (s_pPasskey == NULL)
				{
					if (!PGPPassphraseIsValid (key, PGPOLastOption (context)))
					{
						PTMessageBox (NULL, IDS_CAPTION, 
								IDS_NEEDPHRASE, 
								MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);
						do
						{
							err = PGPclGetKeyPhrase (context, tlscontext, 
									NULL, NULL, keydbMain, key, &s_pszPhrase, 
									&s_pPasskey, &s_sizePasskey);

							if (err == kPGPError_UserAbort)
							{
								if (PTMessageBox (NULL, IDS_CAPTION, 
										IDS_CANCELCONFIRM, 
										MB_YESNO|MB_ICONEXCLAMATION) 
									== IDYES)
								{
									s_bAutoRetrieveSuspended = TRUE;
									break;
								}
							}
						} while (IsPGPError (err));
					}
				}

				if (IsntPGPError (err))
					err = PGPNewOneKeySet (key, &keyset);

				if (IsntPGPError (err))
				{
					err = PGPGetPrimaryUserID (key, &userid);
					if (IsntPGPError (err))
					{
						err = PGPclRetrieveCertificateFromServer (
								context, tlscontext, NULL,
								keydbMain, keyset, userid, 
								s_pPasskey, s_sizePasskey, pkeydb); 

						if( IsntPGPError(err) && PGPKeyDBRefIsValid (*pkeydb))  {
							PGPBoolean bOnToken; 

							PGPGetKeyDBObjBooleanProperty (key,
								kPGPKeyProperty_IsOnToken, &bOnToken);
							
							if (bOnToken)
								err = PGPclCopyX509CertToToken (
									context, 
									tlscontext, 
									NULL, 
									s_pszPhrase,
									keydbMain, key, 
									PGPPeekKeyDBRootKeySet (*pkeydb));
						}
					}
				}
			}
		}
	}

	return err;
}


//	____________________________________
//
//	open the PGPnet keyring files 

static PGPError
sOpenNetKeyRings (
		PGPContextRef	context,
		PGPKeyDBRef*	pkeydbNet)
{
	PGPError		err				= kPGPError_FileNotFound;
	PFLFileSpecRef	filerefPriv		= NULL;
	PFLFileSpecRef	filerefPub		= NULL;

	CHAR			szPriv[MAX_PATH];
	CHAR			szPub[MAX_PATH];

	PGPclGetPath (kPGPclNetPrivateKeyringFile, szPriv, sizeof(szPriv));
	PGPclGetPath (kPGPclNetPublicKeyringFile, szPub, sizeof(szPub));

	if ((lstrlen (szPriv) > 0) &&
		(lstrlen (szPub) > 0))
	{
		err = PFLNewFileSpecFromFullPath (
					PGPPeekContextMemoryMgr (context),
					szPub, &filerefPub);
		if (IsPGPError (err))
			return err;

		err = PFLNewFileSpecFromFullPath (
					PGPPeekContextMemoryMgr (context),
					szPriv, &filerefPriv);
		if (IsPGPError (err))
			return err;

		err = PGPOpenKeyDBFile (context, kPGPOpenKeyDBFileOptions_Mutable,
						(PGPFileSpecRef)filerefPub,
						(PGPFileSpecRef)filerefPriv,
						pkeydbNet);

		PFLFreeFileSpec (filerefPub);
		PFLFreeFileSpec (filerefPriv);
	}

	return err;
}


//	____________________________________
//
//	get the export format of a cert

static PGPError
sSetNetAuthCert(
	PGPContextRef	context,
	PGPKeyDBObjRef	cert)
{
	PGPError		err			= kPGPError_NoErr;
	PGPByte*		pIASN		= NULL;
	PGPKeyDBObjRef	key;
	PGPSize			size;
	PGPKeyID		keyid;
	PGPKeyDBRef		keydbNet;

	if (PGPKeyDBObjRefIsValid (cert))
	{
		key = PGPPeekKeyDBObjKey (cert);

		// copy downloaded cert to PGPnet keydb
		if (IsntPGPError (sOpenNetKeyRings (context, &keydbNet)))
		{
			PGPCopyKeyDBObj (key, keydbNet, NULL);
			PGPFreeKeyDB (keydbNet);
		}

		err = PGPGetKeyID (key, &keyid); CKERR;

		PGPGetKeyDBObjDataProperty (cert,
				kPGPSigProperty_X509IASN, NULL, 0, &size);

		if (size > 0)
		{
			pIASN = (PGPByte *)PGPNewData (
						PGPPeekContextMemoryMgr (context),
						size, kPGPMemoryMgrFlags_Clear);

			if (pIASN)
			{
				err = PGPGetKeyDBObjDataProperty (cert,
						kPGPSigProperty_X509IASN, pIASN,
						size, &size); CKERR;
			}
		}
		else
			err = kPGPError_ItemNotFound;
	}

	if (IsntPGPError (err))
	{
		PGPPrefRef		prefrefNet		= kInvalidPGPPrefRef;

		err = PTPeekPrefRefs (NULL, &prefrefNet);

		if (IsntPGPError (err))
		{
			err = PGPSetPrefData (prefrefNet, 
					kPGPNetPrefX509AuthKeyID, sizeof(keyid), &keyid); 

			if (IsntPGPError (err))
			{
				err = PGPSetPrefData (prefrefNet, 
						kPGPNetPrefX509AuthCertIASN, size, pIASN);

				if (IsntPGPError (err))
					PTFlushPrefs (NULL, prefrefNet);
			}
		}
	}

done:
	if (pIASN)
		PGPFreeData (pIASN);

	return err;
}


//	___________________________________________________
//
//	get the newly retrieved cert from a keydb

static PGPError
sGetRetrievedCertFromDB (
	PGPKeyDBRef			keydb,
	PGPKeyDBObjRef*		pcert)
{
	PGPTime			tmCert		= 0;
	PGPError		err;
	PGPKeyIterRef	keyiter;
	PGPBoolean		bX509;
	PGPKeyDBObjRef	cert;
	PGPTime			tmThis;

	*pcert = kInvalidPGPKeyDBObjRef;

	err = PGPNewKeyIterFromKeySet (PGPPeekKeyDBRootKeySet (keydb), &keyiter);
	if (IsntPGPError (err))
	{
		while (IsntPGPError (err))
		{
			// search for signatures ...
			err = PGPKeyIterNextKeyDBObj (keyiter,
					kPGPKeyDBObjType_Signature, &cert);

			if (IsntPGPError (err))
			{
				// ... which are X.509 ...
				err = PGPGetKeyDBObjBooleanProperty (cert,
						kPGPSigProperty_IsX509, &bX509);

				if (IsntPGPError (err) && bX509)
				{
					PGPKeyDBObjRef	certSigner;

					//  ... and are not self-signatures (not CAs) ...
					certSigner = kInvalidPGPKeyDBObjRef;
					PGPGetSigX509CertifierSig (
							cert, kInvalidPGPKeyDBRef, &certSigner);

					if (certSigner != cert)
					{
						//  ... and take the most recent one.
						PGPGetKeyDBObjTimeProperty (cert, 
								kPGPSigProperty_Creation, &tmThis);

						if (tmThis > tmCert)
						{
							tmCert = tmThis;
							*pcert = cert;
						}
					}
				}
			}

			else if (err == kPGPError_EndOfIteration)
			{
				err = PGPKeyIterNextKeyDBObj (keyiter,
						kPGPKeyDBObjType_Key, &cert);
			}
		}

		PGPFreeKeyIter (keyiter);
	}

	if (PGPKeyDBObjRefIsValid (*pcert))
		err = kPGPError_NoErr;
	else
		err = kPGPError_ItemNotFound;

	return err;
}


//	____________________________________
//
//	handle retrieval post-processing

static VOID 
sFinishUpRetrieval (
		PGPContextRef	context,
		PGPKeyDBObjRef	cert)
{
	BOOL			bNetInstalled				= FALSE;
	BOOL			bNetCertPreviouslySet		= FALSE;
	PGPError		err							= kPGPError_UnknownError;
	PGPPrefRef		prefrefNet;
	PGPSize			size;
	PGPByte*		pbyte;

	CHAR			szUserID[kPGPMaxUserIDSize];
	UINT			u;

	// first check if PGPnet authentication cert is already set
	bNetInstalled = PGPclIsComponentInstalled (kPGPclPGPnet);
	if (bNetInstalled)
	{
		err = PTPeekPrefRefs (NULL, &prefrefNet);

		if (IsntPGPError (err))
		{
			err = PGPGetPrefData (prefrefNet,
					kPGPNetPrefX509AuthKeyID, &size, &pbyte);
			if (IsntPGPError (err))
			{
				PGPFreeData (pbyte);

				err = PGPGetPrefData (prefrefNet,
						kPGPNetPrefX509AuthCertIASN,
						&size, &pbyte);

				if (IsntPGPError (err))
				{
					PGPFreeData (pbyte);
					bNetCertPreviouslySet = TRUE;
				}
			}
		}
	}

	PGPclGetUserIDNameUTF8 (PGPPeekKeyDBObjUserID (cert),
			szUserID, sizeof(szUserID), &u);

	if(!PGPlnIsAuthorized())
	{
		PGPclCertCongrats (NULL, kPGPclManualRetrieval, szUserID);
	}
	else
	{
		if (!bNetInstalled)
			err = PGPclCertCongrats (NULL, kPGPclManualRetrieval, szUserID);
		else if (bNetCertPreviouslySet)
			err = PGPclCertCongrats (NULL, kPGPclAutoRetrievalQueryUse, szUserID);
		else
			err = PGPclCertCongrats (NULL, kPGPclAutoRetrievalUsingCert, szUserID);

		if (bNetInstalled && IsntPGPError (err))
			PGPclErrorBox (NULL, sSetNetAuthCert (context, cert));

⌨️ 快捷键说明

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