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

📄 pgpremoteprefs.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpRemotePrefs.c,v 1.16 2002/08/06 20:10:16 dallen Exp $
____________________________________________________________________________*/
#include <string.h>

#include "pgpRemotePrefs.h"
#include "pgpClientPrefs.h"
#include "pgpNetPrefs.h"
#include "pgpMem.h"
#include "pgpUtilities.h"
#include "pgpStrings.h"
#include "pgpHash.h"
#include "pgpPFLPriv.h"
#include "pgpLDAP.h"

#define kPGPRemotePGPPrefsDN		"pgpelementtype=pgpprefs"
#define kPGPRemotePGPnetPrefsDN		"pgpElementType=pgpnetprefs"
#define kPGPRemoteObjectclass		"objectclass"
#define kPGPRemoteObjectclassAny	"(objectclass=*)"
#define kPGPRemotePGPDataAttr		"pgpData"
#define kPGPRemotePGPProfile		"pgpprofile"
#define kPGPRemotePGPElement		"pgpelement"
#define kPGPOwnerAttr				"owner"
#define kPGPRemotePrefSpaceDN		"baseClientPrefDN"
#define kPGPRemoteVersionDN			"version"
#define kPGPServerInfoCN			"cn=PGPServerInfo"

#define kPGPSHAPrefix				"{SSHA}"

/*
 *	(kPGPSHANullLength + kPGPSHASaltLength + kPGPSHAHashLength) % 3 must = 0
 */
#define kPGPSHASaltLength			8		/* no NULLs in this count */
#define kPGPSHAHashLength			20		/* size of a SHA hash in bytes */
#define kPGPSHANullLength			2
#define kPGPSSHAOutputLength		( kPGPSHASaltLength + kPGPSHAHashLength )

#define MAX(a,b)					( (a) > (b) ? (a) : (b) )

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

/* This is are table of 6-bit value -> character */
	static char const armorTable[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const PGPByte		kPGPSHASaltBytes[] =
{
	0xA0, 0xAA, 0x5C, 0x1E,
	0xED, 0x57, 0x7B, 0xC7,
	0x00, 0x00
};


	static PGPError
sSendTLSEvent(
	PGPContextRef				context,
	PGPEventHandlerProcPtr		handler,
	PGPUserValue				userValue,
	PGPKeyServerState			state,
	PGPtlsSessionRef			tlsSession)
{
	PGPEvent					event;

	if( IsNull( handler ) )
		return kPGPError_NoErr;

	pgpClearMemory( &event, sizeof( PGPEvent ) );

	event.type = kPGPEvent_KeyServerTLSEvent;
	event.data.keyServerTLSData.state = state;
	event.data.keyServerTLSData.tlsSession = tlsSession;

	return handler( context, &event, userValue );
}

	static PGPError
sSendEvent(
	PGPContextRef				context,
	PGPEventHandlerProcPtr		handler,
	PGPUserValue				userValue,
	PGPKeyServerState			state )
{
	PGPEvent					event;

	if( IsNull( handler ) )
		return kPGPError_NoErr;

	pgpClearMemory( &event, sizeof( PGPEvent ) );

	event.type = kPGPEvent_KeyServerEvent;
	event.data.keyServerData.state = state;

	return handler( context, &event, userValue );
}

	static PGPError
sSendPrefsToServer(
	PGPContextRef		context,
	PGPldapContextRef	ldap,
	char *				DN,
	char *				username,
	PGPPrefRef			prefs )
{
	PGPldapMod				modData;
	PGPldapMod				objectclassData;
	PGPldapMod				ownerData;
	char *					ownerAttr[2];
	char *					element[2]		= { kPGPRemotePGPElement, NULL };
	PGPldapMod *			mod[4];
	PGPberValue				berData;
	PGPberValue *			bvalue[2];
	PGPSize					prefBufferSize	= 0;
	void *					prefBuffer		= NULL;
	PGPError				err				= kPGPError_NoErr;

	(void) context;

	ownerAttr[0] = username;	ownerAttr[1] = NULL;
	mod[0] = &modData;	mod[1] = mod[2] = mod[3] = NULL;
	bvalue[0] = &berData;	bvalue[1] = NULL;
	
	err = PGPExportPrefsToBuffer( prefs, &prefBufferSize, &prefBuffer ); CKERR;
	//prefBuffer = PGPNewData( PGPPeekContextMemoryMgr( context ), strlen( "Test buffer" ) + 1, kPGPMemoryMgrFlags_Clear );
	//strcpy( prefBuffer, "Test buffer" );
	//prefBufferSize = strlen( "Test buffer" );

	mod[0]->op = (PGPldapModOp) ( kPGPldapModOp_Replace | kPGPldapModOpMask_UseBERValues );
	mod[0]->type = kPGPRemotePGPDataAttr;

	bvalue[0]->value = prefBuffer;
	bvalue[0]->length = prefBufferSize;
	bvalue[1] = NULL;

	mod[0]->bvalue = bvalue;

	mod[1] = &ownerData;
	mod[1]->op = kPGPldapModOp_Replace;
	mod[1]->type = kPGPOwnerAttr;
	mod[1]->value = ownerAttr;

	mod[2] = NULL;

	/*
	 * First, assume that it already exists on the server and we can
	 * just modify it.
	 */
	err = PGPldapModifySync( ldap, DN, mod );
	if( err == kPGPError_LDAPNoSuchObject )
	{
		/*
		 * Oops.  The object doesn't exist on the server, so we need
		 * to create it first.  In order to tell the LDAP server to accept
		 * the "pgpData" attribute, we need to tell it we're creating an
		 * object with objectclass=pgpelement (and the server administrator
		 * has to have added the correct schema, of course).
		 *
		 * We can leave mod[0] to be the pgpData=<blob>, and set mod[1]
		 * to be the request to create the right objectclass.
		 */
		mod[0]->op = (PGPldapModOp) ( kPGPldapModOp_Add | kPGPldapModOpMask_UseBERValues );

		mod[1] = &objectclassData;
		mod[1]->op = kPGPldapModOp_Add;
		mod[1]->type = kPGPRemoteObjectclass;
		mod[1]->value = element;

		mod[2] = &ownerData;
		mod[2]->op = kPGPldapModOp_Replace;
		mod[2]->type = kPGPOwnerAttr;
		mod[2]->value = ownerAttr;

		mod[3] = NULL;

		err = PGPldapAddSync( ldap, DN, mod );
	}
	CKERR;

done:
	if( IsntNull( prefBuffer ) )
		(void) PGPFreeData( prefBuffer );

	return err;
}

	static PGPError
sGetPrefsFromServer(
	PGPContextRef				context,
	PGPldapContextRef			ldap,
	char *						DN,
	PGPEventHandlerProcPtr		handler,
	PGPUserValue				userValue,
	const PGPPrefDefinition *	prefDef,
	PGPUInt32					prefSize,
	PGPPrefRef *				prefs )
{
	PGPError			err			= kPGPError_NoErr;
	PGPldapMessageRef	message		= kInvalidPGPldapMessageRef;
	PGPldapMessageRef	dataMessage	= kInvalidPGPldapMessageRef;
	PGPberValue **		bval		= NULL;

	err = sSendEvent( context, handler, userValue, kPGPKeyServerState_Querying ); CKERR;

	err = PGPNewLDAPMessage( ldap, &message ); CKERR;

	err = PGPldapSearchSync( ldap, DN, kPGPldapScope_Base,
				kPGPRemoteObjectclassAny, NULL, FALSE,
				message ); CKERR;

	err = sSendEvent( context, handler, userValue,
				kPGPKeyServerState_ProcessingResults ); CKERR;

	err = PGPldapFirstEntry( ldap, message, &dataMessage ); CKERR;

	err = PGPldapGetValuesLen( ldap, dataMessage, kPGPRemotePGPDataAttr, &bval ); CKERR;

	err = PGPImportBufferToMemoryPrefs( PGPPeekContextMemoryMgr( context ),
				bval[0]->value, bval[0]->length, prefDef, prefSize, prefs ); CKERR;

done:

	if( PGPldapMessageRefIsValid( message ) )
		(void) PGPFreeLDAPMessage( message );

	if( IsntNull( bval ) )
		(void) PGPFreeLDAPValuesLen( bval );

	return err;
}

	static PGPError
sEstablishTLSSession(
	PGPContextRef		pgpContext,
	PGPldapContextRef	ldap,
	PGPtlsContextRef *	tlsContext,
	PGPtlsSessionRef *	tlsSession )
{
	PGPSocketRef		sock		= kInvalidPGPSocketRef;
	PGPError			err			= kPGPError_NoErr;

	err = PGPldapGetOption( ldap, kPGPldapOpt_Desc, &sock ); CKERR;

	err = PGPNewTLSContext( pgpContext, tlsContext ); CKERR;

	err = PGPNewTLSSession( *tlsContext, tlsSession ); CKERR;

	err = PGPSocketsEstablishTLSSession( sock, *tlsSession ); CKERR;

done:
	return err;
}


	static PGPError
sParseURL(
	PGPContextRef			context,
	PGPldapContextRef		ldap,
	char *					url,
	PGPtlsContextRef *		tlsContext,
	PGPtlsSessionRef *		tlsSession,
	PGPEventHandlerProcPtr	handler,
	PGPUserValue			userValue,
	PGPBoolean *			isKeyserver,
	PGPldapURLDesc **		urlDesc )
{
	PGPError				err			= kPGPError_NoErr;
	char *					fixedURL	= NULL;
	PGPMemoryMgrRef			mgr			= kInvalidPGPMemoryMgrRef;
	PGPldapMessageRef		message		= kInvalidPGPldapMessageRef;
	char *					attr[]		= { kPGPRemotePrefSpaceDN,
											kPGPRemoteVersionDN,
											NULL };
	char **					values		= NULL;

	PGPValidatePtr( url );
	PGPValidatePtr( tlsContext );
	PGPValidatePtr( tlsSession );
	PGPValidatePtr( isKeyserver );
	PGPValidatePtr( urlDesc );

	mgr = PGPPeekContextMemoryMgr( context );

	*isKeyserver = FALSE;

	err = PGPldapURLParse( ldap, url, urlDesc ); 
	if( err == kPGPError_LDAPNoDN )
	{
		fixedURL = PGPNewData( mgr, strlen( url ) + 2, kPGPMemoryMgrFlags_Clear );
		if( IsNull( fixedURL ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		pgpCopyMemory( url, fixedURL, strlen( url ) + 1 );
		strcat( fixedURL, "/" );

		err = PGPldapURLParse( ldap, fixedURL, urlDesc ); CKERR;

		if( (*urlDesc)->port == 0 )
		{
			if( strstr( url, "ldaps://" ) != NULL )
				(*urlDesc)->port = kPGPldap_DefaultSecurePort;
			else
				(*urlDesc)->port = kPGPldap_DefaultPort;
		}

		/* Query cn=PGPServerInfo */
		err = PGPldapOpen( ldap, (*urlDesc)->host, (*urlDesc)->port ); CKERR;

		if( strstr( url, "ldaps://" ) != NULL )
		{
			/* Try to use TLS */
			err = sEstablishTLSSession( context, ldap, tlsContext, tlsSession );
			if( IsPGPError( err ) )
			{
				(void) sSendTLSEvent( context, handler, userValue,
					kPGPKeyServerState_TLSUnableToSecureConnection, *tlsSession );
				goto done;
			}
			else
			{
				err = sSendTLSEvent( context, handler, userValue,
					kPGPKeyServerState_TLSConnectionSecured, *tlsSession ); CKERR;
			}
		}

		err = PGPldapSimpleBindSync( ldap, NULL, NULL ); CKERR;
		
		err = PGPNewLDAPMessage( ldap, &message ); CKERR;

		err = PGPldapSearchSync( ldap, 
				kPGPServerInfoCN,
				kPGPldapScope_Base,
				kPGPRemoteObjectclassAny,
				attr,
				FALSE,
				message ); CKERR;

		err = PGPldapGetValues( ldap, message, kPGPRemotePrefSpaceDN, &values ); CKERR;
		if( IsNull( values ) || IsNull( *values ) )
		{
			err = kPGPError_LDAPNoSuchAttribute;
			goto done;
		}

		if( IsntNull( (*urlDesc)->dn ) )
			(void) PGPFreeData( (*urlDesc)->dn );

		(*urlDesc)->dn = PGPNewData( mgr, strlen( values[0] ) + 1, kPGPMemoryMgrFlags_Clear );
		if( IsNull( (*urlDesc)->dn ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}

		pgpCopyMemory( values[0], (*urlDesc)->dn, strlen( values[0] ) + 1 );

		*isKeyserver = TRUE;
	}
	CKERR;

	if( IsNull( (*urlDesc)->host ) )
	{
		err = kPGPError_LDAPNotLDAPURL;
		goto done;
	}

	if( (*urlDesc)->port == 0 )
	{
		if( strstr( url, "ldaps://" ) != NULL )
			(*urlDesc)->port = kPGPldap_DefaultSecurePort;
		else
			(*urlDesc)->port = kPGPldap_DefaultPort;
	}

done:
	if( IsntNull( values ) )
		(void) PGPFreeLDAPValues( values );

	return err;
}


	static PGPError
sFreeTLSSession(
	PGPtlsContextRef *	tlsContext,
	PGPtlsSessionRef *	tlsSession )
{
	(void) PGPFreeTLSContext( *tlsContext );
	*tlsContext = kInvalidPGPtlsContextRef;

⌨️ 快捷键说明

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