ptupdate.c

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

C
1,105
字号
	}
}


//	______________________________________________
//
//	thread function that waits for timeouts and then
//	performs updates as appropriate

static DWORD WINAPI 
sAutoUpdateThread (
		LPVOID		lpVoid)
{
	BOOL				bKilled			= FALSE;
	PGPKeyDBRef			keydbMain		= kInvalidPGPKeyDBRef;
	PGPKeyDBRef			keydb			= kInvalidPGPKeyDBRef;
	PGPContextRef		context			= kInvalidPGPContextRef;
	PGPtlsContextRef	tlscontext		= kInvalidPGPtlsContextRef;
	PGPUInt32			uTomorrow		= 0;

	PGPUInt32	uUpdateSkipCounter			= 0;
	PGPUInt32	uPrefsUpdateErrors			= 0;
	PGPUInt32	uAllKeysUpdateErrors		= 0;
	PGPUInt32	uIntroducersUpdateErrors	= 0;
	PGPUInt32	uCRLUpdateErrors			= 0;
	PGPUInt32	uCRLUpdateSuccesses			= 0;

	BOOL			bConnectedToInternet;
	BOOL			bUpdatePrefs;
	BOOL			bUpdateAllKeys;
	BOOL			bUpdateIntroducers;
	BOOL			bUpdateCRLs;
	BOOL			bRetrieveCert;
	BOOL			bDoSomething;
	BOOL			bCertRetrieved;

	PGPError		err;
	PGPPrefRef		prefref;
	PGPBoolean		bUpdate;
	PGPUInt32		uNextCRLUpdate;
	PGPUInt32		uLastCertRequest;
	DWORD			dw;

	if (IsPGPError (PGPNewContext (kPGPsdkAPIVersion, &context)))
		goto done;

	if (IsPGPError (PGPNewTLSContext (context, &tlscontext)))
		goto done;

	if (IsPGPError (PTInitPrefs (context)))
		goto done;

	PGPlnLicenseCheck (context);

	while (!bKilled)
	{
		dw = WaitForSingleObject (s_heventKill, THREAD_INTERVAL);

		if (dw != WAIT_TIMEOUT)
		{
			bKilled = TRUE;
		}
		else
		{
			bConnectedToInternet = PGPclIsLocalMachineOnline ();
			bUpdatePrefs		= FALSE;
			bUpdateAllKeys		= FALSE;
			bUpdateIntroducers	= FALSE;
			bUpdateCRLs			= FALSE;
			bRetrieveCert		= FALSE;
			bDoSomething		= FALSE;
			bCertRetrieved		= FALSE;

			// once-per-day operations
			if (PGPGetTime () > uTomorrow)
			{	
				uPrefsUpdateErrors			= 0;
				uAllKeysUpdateErrors		= 0;
				uIntroducersUpdateErrors	= 0;
				uCRLUpdateErrors			= 0;
				uCRLUpdateSuccesses			= 0;

				if (IsntPGPError (PGPclOpenDefaultKeyrings (context, 
						kPGPOpenKeyDBFileOptions_Mutable, &keydbMain)))
				{
					sScheduleNextCRLUpdate (context, keydbMain);
					PGPFreeKeyDB (keydbMain);
				}

				uTomorrow = PGPGetTime () + TOMORROW_INTERVAL;
			}

			// now see if any thing needs to be done
			err = PTPeekPrefRefs (&prefref, NULL);
			if (IsntPGPError (err))
			{
				// use the skip counter to reduce the frequency of
				// some operations
				if (uUpdateSkipCounter > 0)
					uUpdateSkipCounter--;

				if ((uUpdateSkipCounter == 0) &&
					bConnectedToInternet)
				{
					uUpdateSkipCounter = UPDATE_INTERVAL;

					// check for prefs updating
					if (uPrefsUpdateErrors < MAX_ERROR_COUNT)
					{
						err = PGPGetPrefBoolean (prefref, 
								kPGPPrefUpdatePrefs, &bUpdate);

						if (IsntPGPError (err))
						{
							if (bUpdate)
							{
								if (sCheckForUpdate (prefref,
										kPGPPrefDaysUpdatePrefs,
										kPGPPrefLastPrefsUpdate))
								{
									bUpdatePrefs = TRUE;
									bDoSomething = TRUE;
								}
							}
						}
					}


					// check if updating all keys is due
					if (uAllKeysUpdateErrors < MAX_ERROR_COUNT)
					{
						err = PGPGetPrefBoolean (prefref, 
								kPGPPrefUpdateAllKeys, &bUpdate);
						if (IsntPGPError (err))
						{
							if (bUpdate)
							{
								if (sCheckForUpdate (prefref,
										kPGPPrefDaysUpdateAllKeys,
										kPGPPrefLastAllKeysUpdate))
								{
									bUpdateAllKeys = TRUE;
									bDoSomething = TRUE;
								}
							}
						}
					}

					// check if update introducers is due
					if (uIntroducersUpdateErrors < MAX_ERROR_COUNT)
					{
						err = PGPGetPrefBoolean (prefref, 
								kPGPPrefUpdateTrustedIntroducers, &bUpdate);
						if (IsntPGPError (err))
						{
							if (bUpdate)
							{
								if (sCheckForUpdate (prefref,
										kPGPPrefDaysUpdateTrustedIntroducers,
										kPGPPrefLastTrustedIntroducersUpdate))
								{
									bUpdateIntroducers = TRUE;
									bDoSomething = TRUE;
								}
							}
						}
					}

					// check if CRL updating is due
					if ((uCRLUpdateErrors < MAX_ERROR_COUNT) &&
						(uCRLUpdateSuccesses == 0))
					{
						err = PGPGetPrefBoolean (prefref, 
								kPGPPrefAutoUpdateX509CRL, &bUpdate);
						if (IsntPGPError (err))
						{
							if (bUpdate)
							{
								err = PGPGetPrefNumber (prefref,
										kPGPPrefNextAutoCRLUpdate, 
										&uNextCRLUpdate);

								if (uNextCRLUpdate > 0)
								{
									if ((INT)uNextCRLUpdate <= PGPGetTime ())
									{
										bUpdateCRLs = TRUE;
										bDoSomething = TRUE;
									}
								}
							}
						}
					}
				}

				// check if auto cert retrieval is due
				if (!s_bAutoRetrieveSuspended)
				{
					err = PGPGetPrefNumber (prefref, 
							kPGPPrefLastCertRequest, &uLastCertRequest);

					if (IsntPGPError (err))
					{
						if (uLastCertRequest != 0)
						{
							bRetrieveCert = TRUE;
							bDoSomething = TRUE;
						}
					}
				}
			}

			if (bDoSomething && bConnectedToInternet)
			{
				BOOL	bAllKeysUpdated				= FALSE;
				BOOL	bIntrosUpdated				= FALSE;
				BOOL	bPrefsUpdated				= FALSE;
				BOOL	bCRLsUpdated				= FALSE;
				BOOL	bDefaultKeysImported		= FALSE;

				keydb		= kInvalidPGPKeyDBRef;
				keydbMain	= kInvalidPGPKeyDBRef;

				// If PGPkeys is installed, open the default keyring.
				
				if (PGPclIsComponentInstalled(kPGPclPGPkeys))
				{
					err = PGPclOpenDefaultKeyrings (context, 
						kPGPOpenKeyDBFileOptions_Mutable, &keydbMain); CKERR;
					
					// do all our operations on a temporary keydb so that
					// we can then merge all changes into default keyring in one
					// fell swoop (to avoid continuous reloads of keyring in 
					// PGPkeys)
					err = PGPNewKeyDB (context, &keydb); CKERR;
					err = PGPCopyKeys (PGPPeekKeyDBRootKeySet (keydbMain), 
						keydb, NULL); CKERR;
				}

				// Otherwise, it's probably a PGPfire-only install,
				// which does not have keyrings, so kill any key updates

				else
				{
					bUpdateAllKeys = FALSE;
					bUpdateIntroducers = FALSE;
					bUpdateCRLs = FALSE;
					bRetrieveCert = FALSE;
				}
				
				// update prefs if update is due
				if (bUpdatePrefs)
				{
					PGPPrefRef	prefrefNet	= kInvalidPGPPrefRef;

					if (PGPclIsComponentInstalled (kPGPclPGPnet))
						err = PTPeekPrefRefs (&prefref, &prefrefNet);
					else
						err = PTPeekPrefRefs (&prefref, NULL);

					if (IsntPGPError (err))
					{
						if (IsntPGPError (PGPclGetPrefsFromServer (
								context, tlscontext, NULL,
								prefref, prefrefNet)))
						{
							err = PTFlushPrefs (prefref, prefrefNet);
							if (IsntPGPError (err))
							{
								bPrefsUpdated = TRUE;
								PGPlnLicenseCheck (context);
							}
						}

						// Only get the default keys if PGPkeys is installed
						if (PGPclIsComponentInstalled(kPGPclPGPkeys))
						{
							if (IsntPGPError (PGPclGetDefaultKeysFromServer (
								context, tlscontext, NULL, keydb)))
							{
								bDefaultKeysImported = TRUE;
							}
						}

						if (!bPrefsUpdated)
							uPrefsUpdateErrors++;
					}
				}

				// update all keys if update is due
				if (bUpdateAllKeys)
				{
					err = PTPeekPrefRefs (&prefref, NULL);
					if (IsntPGPError (err))
					{
						if (IsntPGPError (sAutoUpdateAllKeys (
								context, tlscontext, keydb)))
						{
							bAllKeysUpdated = TRUE;
						}

						if (!bDefaultKeysImported)
						{
							if (IsntPGPError (
									PGPclGetDefaultKeysFromServer (
										context, tlscontext, NULL, keydb)))
							{
								bDefaultKeysImported = TRUE;
							}
						}
					}

					if (!bAllKeysUpdated)
						uAllKeysUpdateErrors++;
				}

				// update introducers if update is due
				if (bUpdateIntroducers)
				{
					err = PTPeekPrefRefs (&prefref, NULL);
					if (IsntPGPError (err))
					{
						if (!bDefaultKeysImported)
						{
							if (IsntPGPError (
									PGPclGetDefaultKeysFromServer (
										context, tlscontext, NULL, keydb)))
							{
								bDefaultKeysImported = TRUE;
							}
						}

						if (IsntPGPError (PGPclAutoUpdateIntroducers (
								context, tlscontext, NULL, keydb, TRUE)))
						{
							bIntrosUpdated = TRUE;
						}
					}

					if (!bIntrosUpdated)
						uIntroducersUpdateErrors++;
				}

				// update CRLs if update is due
				if (bUpdateCRLs)
				{
					err = PGPclGetCertificateRevocationsFromServer (
							context, tlscontext, NULL, keydb);

					if (IsntPGPError (err))
					{
						bCRLsUpdated = TRUE;
						uCRLUpdateSuccesses++;
					}
					else
						uCRLUpdateErrors++;
				}

				// attempt cert retrieval if request is outstanding
				if (bRetrieveCert)
				{
					PGPKeyDBRef		keydbCert;
					PGPKeyDBObjRef	cert;

					// attempt cert retrieval
					// use main keydb instead of copy in order to take
					// advantage of possibly cached passphrase
					err = sAttemptRetrieval (context, tlscontext, 
							keydbMain, &keydbCert);

					if (IsntPGPError (err))
					{
						if (s_pPasskey)
						{
							PGPFreeData (s_pPasskey);
							s_pPasskey = NULL;
						}
						if (s_pszPhrase)
						{
							PGPFreeData (s_pszPhrase);
							s_pszPhrase = NULL;
						}

						err = sGetRetrievedCertFromDB (keydbCert, &cert);
						if (IsntPGPError (err))
						{
							PGPKeySetRef	keysetCopied;

							bCertRetrieved = TRUE;

							PGPCopyKeys (PGPPeekKeyDBRootKeySet (keydbCert), 
									keydb, &keysetCopied);

							PGPCheckKeyRingSigs (PGPPeekKeyDBRootKeySet (keydb),
									NULL, FALSE, NULL, NULL );

							sFinishUpRetrieval (context, cert);

							PGPFreeKeySet (keysetCopied);
						}
						PGPFreeKeyDB (keydbCert);
					}
				}

				if (bAllKeysUpdated || bIntrosUpdated || 
					bCRLsUpdated || bDefaultKeysImported || bCertRetrieved)
				{
					// merge new keys into default keyring
					PGPCopyKeys (
						PGPPeekKeyDBRootKeySet (keydb), keydbMain, NULL);
				}

				// save the time of this update
				err = PTPeekPrefRefs (&prefref, NULL);
				if (IsntPGPError (err))
				{
					if (bAllKeysUpdated)
					{
						PGPSetPrefNumber (prefref, 
								kPGPPrefLastAllKeysUpdate, PGPGetTime());
					}

					if (bIntrosUpdated)
					{
						PGPSetPrefNumber (prefref, 
								kPGPPrefLastTrustedIntroducersUpdate, 
								PGPGetTime());
					}

					if (bPrefsUpdated)
					{
						PGPSetPrefNumber (prefref, 
								kPGPPrefLastPrefsUpdate, PGPGetTime());
					}

					if (bCertRetrieved)
					{
						PGPSetPrefNumber (prefref, 
								kPGPPrefLastCertRequest, 0);
					}

					if (bAllKeysUpdated || bIntrosUpdated || 
						bPrefsUpdated || bCertRetrieved)
					{
						PTFlushPrefs (prefref, NULL);
					}

					if (bCRLsUpdated)
					{
						sScheduleNextCRLUpdate (context, keydb);
					}
				}

				if (PGPKeyDBRefIsValid (keydb))
					PGPFreeKeyDB (keydb);

				if (PGPKeyDBRefIsValid (keydbMain))
					PGPFreeKeyDB (keydbMain);
			}

			// take care of the case where the time interval for cert
			// retrievals has elapsed
			if (bRetrieveCert && !bCertRetrieved)
			{
				if (uLastCertRequest < (PGPGetTime()-REQUEST_TIMEOUT))
				{
					if (sContinueAutoRetrieval ())
						uLastCertRequest = PGPGetTime ();
					else
						uLastCertRequest = 0;

					err = PTPeekPrefRefs (&prefref, NULL);
					if (IsntPGPError (err))
					{
						if (s_pPasskey)
						{
							PGPFreeData (s_pPasskey);
							s_pPasskey = NULL;
						}
						if (s_pszPhrase)
						{
							PGPFreeData (s_pszPhrase);
							s_pszPhrase = NULL;
						}
						

						PGPSetPrefNumber (prefref, 
								kPGPPrefLastCertRequest, uLastCertRequest);
						PTFlushPrefs (prefref, NULL);
					}
				}
			}
		}
	}

	PTClosePrefs ();

done:
	if (s_pPasskey)
	{
		PGPFreeData (s_pPasskey);
		s_pPasskey = NULL;
	}
	if (s_pszPhrase)
	{
		PGPFreeData (s_pszPhrase);
		s_pszPhrase = NULL;
	}

	if (PGPtlsContextRefIsValid (tlscontext))
		PGPFreeTLSContext (tlscontext);

	if (PGPContextRefIsValid (context))
		PGPFreeContext (context);

	return 0;
}


//	________________________
//
//	startup the auto-update thread

VOID
PTStartAutoUpdater (VOID)
{
	DWORD	dwID;

	s_heventKill = CreateEvent (
			NULL, FALSE, FALSE, NULL);
	s_hthreadUpdate = (HANDLE)_beginthreadex (
			NULL, 0, sAutoUpdateThread, NULL, 0, &dwID);
}


//	________________________
//
//	shutdown the auto-update thread

VOID
PTStopAutoUpdater (VOID)
{
	if (s_hthreadUpdate)
	{
		SetEvent (s_heventKill);
		WaitForSingleObject (s_hthreadUpdate, INFINITE);
		CloseHandle (s_hthreadUpdate);
	}
}


⌨️ 快捷键说明

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