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

📄 pgpfiledb.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		rdb->bwriteable = FALSE;
		rdb->openFlags &= ~kPGPKeyRingOpenFlags_Mutable;
	}

	if ( IsntNull( newRingFile ) )
	{
		if( IsPGPError( ringFileClose( newRingFile ) ) )
				pgpDebugMsg( "Failed to close newRingFile" );
	}
	if ( IsntNull( newPGPFile ) )
		pgpFileClose( newPGPFile );
	if ( newFileRef != kInvalidPFLFileSpecRef )
		PFLFreeFileSpec( newFileRef );

	if ( IsntNull( tempPGPFile ) )
		pgpFileClose( tempPGPFile );
	if ( IsntNull( tempStdFile ) )
		PFLFileSpecDelete( tempFileRef );
	if ( tempFileRef != kInvalidPFLFileSpecRef )
		PFLFreeFileSpec( tempFileRef );

	if ( IsntNull( mainFileName ) )
		PGPFreeData( mainFileName );

	return err;
}

	static PGPError
CloseKeyRing( RingDB *	rdb )
{
	PGPContextRef	context;

	pgpAssertAddrValid( rdb, RingDB );
	context	= rdb->context;

	if (rdb->frozenSet)
	{
		ringSetDestroy (rdb->frozenSet);
		rdb->frozenSet = 0;
	}
	rdb->immutableSet = 0;
	if (rdb->mutableSet)
		ringSetDestroy (rdb->mutableSet);
	rdb->mutableSet = 0;
	if( IsPGPError( ringFileClose (rdb->ringFile) ) )
		pgpDebugMsg( "Failed to close rdb->ringFile" );
	rdb->ringFile = 0;
	pgpFileClose (rdb->pgpFile);
	rdb->pgpFile = 0;

	if ( IsntNull( rdb->mainStdFile ) )
		pgpStdIOClose( rdb->mainStdFile );

	if ( rdb->mainFileRef != kInvalidPFLFileSpecRef )
	{
		if ( rdb->bwriteable || !PFL_PLATFORM_UNSAFE_DELETE )
			PurgeOldBackups( rdb->mainFileRef );
		PFLFreeFileSpec( rdb->mainFileRef );
		rdb->mainFileRef = kInvalidPFLFileSpecRef;
	}
	if ( rdb->readFileRef != kInvalidPFLFileSpecRef )
	{
		if ( rdb->btempfile )
			PFLFileSpecDelete( rdb->readFileRef );
		PFLFreeFileSpec( rdb->readFileRef );
		rdb->readFileRef = kInvalidPFLFileSpecRef;
	}
	
	return kPGPError_NoErr;
}




/********************  Virtual Functions  ************************/


	static PGPBoolean
rdbIsMutable (PGPKeyDBRef kdb) {
	RingDB         *rdb = (RingDB *)kdb->priv;

	return rdb->bwriteable;
}

	static PGPBoolean
rdbObjIsMutable (PGPKeyDBRef kdb, RingObject *testObj)
{	
	RingDB         *rdb = (RingDB *)kdb->priv;

	return rdb->bwriteable && ringSetIsMember (rdb->mutableSet, testObj);
}

	static PGPBoolean
rdbIsDirty (PGPKeyDBRef kdb)
{
	RingDB         *rdb = (RingDB *)kdb->priv;

	return rdb->bdirty;
}

/* Mark as dirty */
	static void
rdbDirty (RingDB *rdb)
{
	rdb->bdirty = TRUE;
	if (rdb->frozenSet) {
		ringSetDestroy (rdb->frozenSet);
		rdb->frozenSet = 0;
	}
}

	static const RingSet *
rdbGetRingSet (PGPKeyDBRef kdb)
{
	RingDB         *rdb = (RingDB *)kdb->priv;
	RingSet        *rset;

	if (!rdb->bwriteable) {
		return rdb->immutableSet;
	} else if (!(rset = rdb->frozenSet)) {
		rset = ringSetCreate (ringSetPool (rdb->mutableSet));
		ringSetAddSet (rset, rdb->mutableSet);
		ringSetFreeze (rset);
		rdb->frozenSet = rset;
	}
	return rset;
}

	static PGPError
rdbAdd (PGPKeyDBRef kdb, RingSet *toAdd)
{
	RingDB         *rdb = (RingDB *)kdb->priv;
	RingIterator   *riAdd;		/* Iterator over toAdd set */
	RingObject     *robj;		/* Object we are adding */
	int             level;		/* Level of iterator in hierarchy */
	int				type;		/* Type of robj */
	int             added;		/* Number of objects added */
	int             skipped;	/* Number of objects skipped */
	PGPBoolean		skipparts;  /* True if skipping, obj not for us */

	if (!rdb->bwriteable)
		return kPGPError_ItemIsReadOnly;

	riAdd = ringIterCreate (toAdd);
	if (!riAdd) {
		return ringSetError(toAdd)->error;
	}

	added = 0;
	skipped = 0;
	skipparts = FALSE;

	while ((level = ringIterNextObjectAnywhere(riAdd)) > 0) {
		robj = ringIterCurrentObject (riAdd, level);
		type = ringObjectType (robj);
		if (type==RINGTYPE_KEY) {
			/*
			 * If key lacks secret object, put it only on the public
			 * ring, and if key comes only from a source where it is a
			 * secret key, put it only on the secret ring.  This is
			 * important to prevent propagation of the 2.6.2 "version bug",
			 * where changing passphrase on a V2 secret key turns it into
			 * V3.  We must not let that get into the public keyring.
			 */
			if (rdb->bprivate) {
				skipparts = !ringKeyIsSec (toAdd, robj);
				if (skipparts && !ringKeyIsSubkey (toAdd, robj)) {
					/* Don't skip if any subkey has a secret part */
					unsigned levelx;
					RingObject *robjx;
					while ((levelx = ringIterNextObjectAnywhere(riAdd)) > 1) {
						robjx = ringIterCurrentObject (riAdd, levelx);
						if (ringObjectType(robjx) == RINGTYPE_KEY &&
									ringKeyIsSec (toAdd, robjx)) {
							skipparts = FALSE;
							break;
						}
					}
					ringIterSeekTo (riAdd, robj);
				}
			} else {
				skipparts = ringKeyIsSecOnly (toAdd, robj);
				/* Go ahead and add to pubring if key has a signature */
				if (skipparts) {
					unsigned levelx;
					RingObject *robjx;
					int typex;
					while ((levelx = ringIterNextObjectAnywhere(riAdd)) > 1) {
						robjx = ringIterCurrentObject (riAdd, levelx);
						typex = ringObjectType (robjx);
						if (typex == RINGTYPE_KEY)
							break;
						if (typex == RINGTYPE_SIG) {
							skipparts = FALSE;
							break;
						}
					}
					ringIterSeekTo (riAdd, robj);
				}
			}
		}
		if (skipparts) {
			skipped += 1;
		} else if ((type==RINGTYPE_SEC) && !rdb->bprivate) {
			/* Secrets only go to private keyrings */
			skipped += 1;
		} else if ((type==RINGTYPE_SIG) && rdb->bprivate &&
				   !ringSigIsSelfSig( toAdd, robj )) {
			/*
			 * Signatures only go to public keyrings, normally.  The
			 * exception is your own self-sigs.  If you lose the one
			 * on your subkey, people won't be able to encrypt to you.
			 * If you lose the one on your username, you'll lose expiration
			 * or preferred algorithms.
			 */
			skipped += 1;
		} else if ((type==RINGTYPE_CRL) && rdb->bprivate) {
			/* CRLs only on public keyring */
			skipped += 1;
		} else {
			ringSetAddObject (rdb->mutableSet, robj);
			added += 1;
		}
	}
	ringIterDestroy (riAdd);

	rdbDirty (rdb);
	return kPGPError_NoErr;
}


	static PGPError
rdbRemove (PGPKeyDBRef kdb, RingObject *toRemove)
{
	RingDB         *rdb = (RingDB *)kdb->priv;

	if (!rdb->bwriteable)
		return kPGPError_ItemIsReadOnly;

	if (ringSetIsMember (rdb->mutableSet, toRemove))
		rdbDirty (rdb);
	return (PGPError)ringSetRemObject (rdb->mutableSet, toRemove);
}

/*
 * Note that unions don't pass this call down, they take care of it
 * themselves
 */
	static PGPError
rdbChanged (PGPKeyDBRef kdb, RingSet *changedkeys)
{
	RingDB         *rdb = (RingDB *)kdb->priv;

	if (!rdb->bwriteable)
		return kPGPError_ItemIsReadOnly;

	rdbDirty (rdb);
	return pgpReSortKeys (kdb, changedkeys);
}

	static PGPError
rdbCommit (PGPKeyDBRef kdb)
{
	RingDB         *rdb = (RingDB *)kdb->priv;
	RingPool	   *ringpool = ringSetPool (rdb->immutableSet);
	PGPError        error;

	if (!rdb->bwriteable)
		return kPGPError_NoErr;

	/*  Don't check for trust changed if untrusted file */
	if (!rdb->bdirty &&	(!rdb->btrusted || 
				 (rdb->btrusted && !ringFileIsTrustChanged(rdb->ringFile))))
		return kPGPError_NoErr;

	/* Must use frozen set for writing */

	ringSetFreeze (rdb->mutableSet);
	if (rdb->frozenSet) {
		ringSetDestroy (rdb->frozenSet);
		rdb->frozenSet = 0;
	}
	error = WriteKeyRing (rdb);

	if (error) {
		/*
		 * Sometimes on error we have fixed rdb->mutableSet, but possibly it
		 * may still be frozen as above.  To be safe we will always make a
		 * copy here so it is writeable in the future.
		 */
		RingSet *rset = ringSetCreate (ringpool);
		pgpAssert (rset);
		pgpAssert (rdb->mutableSet);
		ringSetAddSet (rset, rdb->mutableSet);
		ringSetDestroy (rdb->mutableSet);
		rdb->mutableSet = rset;
		return error;
	}

	rdb->immutableSet = ringFileSet (rdb->ringFile);
	rdb->mutableSet = ringSetCreate (ringpool);
	ringSetAddSet (rdb->mutableSet, rdb->immutableSet);
	rdb->bdirty = 0;

	return kPGPError_NoErr;
}


	static PGPError
rdbRevert (PGPKeyDBRef kdb)
{
	RingDB         *rdb = (RingDB *)kdb->priv;

	if (!rdb->bdirty)
		return kPGPError_NoErr;
	rdb->bdirty = 0;
	if (rdb->mutableSet) {
		ringSetDestroy (rdb->mutableSet);
		rdb->mutableSet = ringSetCreate (ringSetPool(rdb->immutableSet));
		if (!rdb->mutableSet) {
			return ringSetError( rdb->immutableSet )->error;
		}
		ringSetAddSet (rdb->mutableSet, rdb->immutableSet);
	}
	if (rdb->frozenSet) {
		ringSetDestroy (rdb->frozenSet);
		rdb->frozenSet = 0;
	}
	return kPGPError_NoErr;
}

	static PGPError
rdbReload (PGPKeyDBRef kdb)
{
	RingDB         *rdb = (RingDB *)kdb->priv;
	PFLFileSpecRef     	fileRef;
	PGPError        err	= kPGPError_NoErr;
	PGPContextRef	cdkContext	= pgpGetKeyDBContext( kdb );
	RingPool	   *pool = ringSetPool (rdb->immutableSet);
	
	if (rdb->bmembuf)
		return kPGPError_NoErr;
	if ( IsPGPError(err = PFLCopyFileSpec(rdb->mainFileRef, &fileRef)))
		return kPGPError_OutOfMemory;
	err = CloseKeyRing (rdb);
	if (err) {
		PFLFreeFileSpec(fileRef);
		return err;
	}
	err = OpenKeyRing ( cdkContext, fileRef, rdb->openFlags, pool, rdb);
	rdb->bdirty = 0;
	PFLFreeFileSpec(fileRef);
	return err;
}

	static void
rdbDestroy (PGPKeyDBRef kdb)
{
	RingDB         *rdb = (RingDB *)kdb->priv;
	PGPContextRef	context;

	pgpAssertAddrValid( kdb, RingDB );
	context	= rdb->context;

	CloseKeyRing (rdb);
	kdb->typeMagic	= ~ kdb->typeMagic;		/* mark as invalid */
	kdb->fixedMagic	= ~ kdb->fixedMagic;	/* mark as invalid */
	pgpContextMemFree( context, rdb);
}


/****************************  Constructor  **************************/

	PGPKeyDBRef 
pgpCreateFileKeyDB (PGPContextRef context, PFLConstFileSpecRef fileRef,
	PGPKeyRingOpenFlags openFlags, RingPool *ringpool,
	PGPError *error)
{
	PGPKeyDBRef    kdb;
	RingDB         *rdb;

	*error = kPGPError_NoErr;
	kdb = pgpKeyDBCreateInternal (context);
	if (!kdb) {
		*error = kPGPError_OutOfMemory;
		return NULL;
	}
	rdb = (RingDB *) pgpContextMemAlloc( context,
		sizeof (RingDB), kPGPMemoryMgrFlags_Clear);
	if (!rdb) {
		*error = kPGPError_OutOfMemory;
		pgpKeyDBDestroyInternal (kdb);
		return NULL;
	}

	rdb->context	= context;
	
	*error = OpenKeyRing ( context, fileRef, openFlags, ringpool, rdb);
	if (*error) {
		pgpContextMemFree( context, rdb);
		pgpKeyDBDestroyInternal (kdb);
		return NULL;
	}

	kdb->priv    		= rdb;
	kdb->typeMagic			= PGPKDBFILEMAGIC;
	kdb->fixedMagic			= kPGPKeyDBMagic;
	kdb->isMutable			= rdbIsMutable;
	kdb->objIsMutable		= rdbObjIsMutable;
	kdb->isDirty    		= rdbIsDirty;
	kdb->getRingSet			= rdbGetRingSet;
	kdb->add        		= rdbAdd;
	kdb->remove     		= rdbRemove;
	kdb->changed			= rdbChanged;
	kdb->commit     		= rdbCommit;
	kdb->revert     		= rdbRevert;
	kdb->reload     		= rdbReload;
	kdb->destroy			= rdbDestroy;

	pgpKeyDBInitInternal(kdb);

	return kdb;
}

/*
 * Create a File type KeyDB from a memory buffer.  This will be an
 * immutable KeyDB since we can't save our changes anywhere.
 * We make a copy of the buffer passed in, so caller can free it.
 */
	PGPKeyDBRef 
pgpCreateMemFileKeyDB (
	PGPContextRef	context,
	PGPByte *		buf,
	size_t 			length,
	RingPool *		ringpool,
	PGPError *		error)
{
	PGPKeyDBRef		kdb;
	RingDB         *rdb;

	*error = kPGPError_NoErr;
	kdb = pgpKeyDBCreateInternal (context);
	if (!kdb) {
		*error = kPGPError_OutOfMemory;
		return NULL;
	}
	rdb = (RingDB *) pgpContextMemAlloc( context,
		sizeof (RingDB), kPGPMemoryMgrFlags_Clear);
	if (!rdb) {
		*error = kPGPError_OutOfMemory;
		pgpKeyDBDestroyInternal (kdb);
		return NULL;
	}

	rdb->context	= context;

	/* Memfile keydb's are immutable */
	rdb->mutableSet = NULL;

	rdb->pgpFile = pgpFileMemOpen ( context, buf, length);
	if (!rdb->pgpFile) {
		pgpContextMemFree( context, rdb);
		pgpKeyDBDestroyInternal (kdb);
		*error = kPGPError_OutOfMemory;
		return NULL;
	}

	rdb->ringFile = ringFileOpen (ringpool, rdb->pgpFile, 0, error);
	if (!rdb->ringFile) {
		pgpFileClose (rdb->pgpFile);
		pgpContextMemFree( context, rdb);
		pgpKeyDBDestroyInternal (kdb);
		*error	= ringPoolError(ringpool)->error;
		if (!*error)
			*error = kPGPError_OutOfMemory;
		return NULL;
	}

	rdb->immutableSet = ringFileSet (rdb->ringFile);
	rdb->bmembuf = TRUE;
	rdb->mainStdFile = NULL;
	rdb->mainFileRef = rdb->readFileRef = NULL;

	kdb->priv    			= rdb;
	kdb->typeMagic			= PGPKDBFILEMAGIC;
	kdb->fixedMagic			= kPGPKeyDBMagic;
	kdb->isMutable			= rdbIsMutable;
	kdb->objIsMutable		= rdbObjIsMutable;
	kdb->isDirty    		= rdbIsDirty;
	kdb->getRingSet			= rdbGetRingSet;
	kdb->add        		= rdbAdd;
	kdb->remove     		= rdbRemove;
	kdb->changed			= rdbChanged;
	kdb->commit     		= rdbCommit;
	kdb->revert     		= rdbRevert;
	kdb->reload     		= rdbReload;
	kdb->destroy			= rdbDestroy;

	pgpKeyDBInitInternal(kdb);

	return kdb;
}

/*
 * Local Variables:
 * tab-width: 4
 * End:
 * vi: ts=4 sw=4
 * vim: si
 */

⌨️ 快捷键说明

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