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

📄 pgpnetservice.c

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

	$Id: pgpNetService.c,v 1.26 2002/08/06 20:10:26 dallen Exp $
____________________________________________________________________________*/

#include <errno.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpSockets.h"
#include "pgpPFLPriv.h"
#include "pgpNetPrefs.h"
#include "pgpNetService.h"


#define CKERR		if( IsPGPError( err ) ) goto done
#define CKNULL(x)	do { if( IsNull( x ) ) { err = kPGPError_OutOfMemory; goto done; } } while(0)
#define RETERR(x)	do { err = x; goto done; } while(0)

#define STARTUPSCRIPT	"/Library/StartupItems/PGPnet/PGPnet"

	static PGPError
sGetClientSockPath(
	char *				sockPath )
{
	struct passwd *		pw	= NULL;

	PGPValidatePtr( sockPath );
	
	pw = getpwuid( getuid() );
	sprintf( sockPath, "/tmp/.pgpnet-%s-%d-sock", pw->pw_name, getpid() );
	
	return kPGPError_NoErr;
}

	static PGPError
sConnectToService(
	PGPnetContextRef	netContext )
{
	PGPInt32			sock		= 0;
	struct sockaddr_un	sun;
	PGPInt32			retval		= 0;
		
	sock = socket( AF_LOCAL, SOCK_STREAM, 0 );
	if( sock < 0 )
		goto done;
		
	sun.sun_family = AF_LOCAL;
	memcpy( sun.sun_path, kPGPnetSocket, strlen( kPGPnetSocket ) + 1 );
	
	retval = connect( sock, (struct sockaddr *) &sun, sizeof( sun ) );
	if( retval < 0 )
		goto done;
		
	netContext->sockToService = sock;
	
done:
	if( retval < 0 )
	{
		if( sock > 0 )
			(void) close( sock );
		return kPGPError_SocketsNotConnected;
	}
	return kPGPError_NoErr;
}

	static PGPError
sCreateIPCSocket(
	char *				sockPath,
	PGPInt32 *			outSock )
{
	PGPError			err			= kPGPError_NoErr;
	struct sockaddr_un	sun;
	PGPInt32			sock		= 0;
	PGPInt32			retval		= 0;

	sock = socket( AF_LOCAL, SOCK_STREAM, 0 );
	if( sock < 0 )
		RETERR( kPGPError_UnknownError );
		
	/* In case the sock is sitting around from a previous run */
	(void) unlink( sockPath );
	
	sun.sun_family = AF_LOCAL;
	pgpCopyMemory( sockPath, sun.sun_path, strlen( sockPath ) + 1 );
	
	retval = bind( sock, (struct sockaddr *) &sun, SUN_LEN( &sun ) );
	if( retval < 0 )
		RETERR( kPGPError_UnknownError );
		
	retval = listen( sock, 10 );
	if( retval < 0 )
		RETERR( kPGPError_UnknownError );
	
	*outSock = sock;

done:
	return err;
}

	static PGPError
sNewContextInternal(
	PGPContextRef		context,
	PGPnetContextRef	*outNetContext,
	PGPBoolean			getMessagesFromService )
{
	PGPError			err				= kPGPError_NoErr;
	PGPnetContextRef	netContext		= kInvalidPGPnetContextRef;
	PGPInt32			sock			= 0;
	struct sockaddr_un	sun;
	PGPInt32			len				= 0;
	PGPInt32			retval			= 0;
	struct timeval		tv;
	fd_set				sockSet;
	char				sockPath[PATH_MAX];
	time_t				startTime		= 0;
	
	netContext = PGPNewData( PGPPeekContextMemoryMgr( context ),
		sizeof( PGPnetContextPriv ),
		kPGPMemoryMgrFlags_Clear );
	CKNULL( netContext );
	pgpClearMemory( netContext, sizeof( PGPnetContextPriv ) );
	
	err = sConnectToService( netContext );
	if( err == kPGPError_SocketsNotConnected )
	{
		/* PGPnetService isn't running.  Start it.  */
		system( STARTUPSCRIPT " >& /dev/null" );
	}
	
	/* Loop for 10 seconds, trying to connect */
	startTime = time( NULL );
	do
	{
		usleep( 500000 );
		err = sConnectToService( netContext );
	} while( IsPGPError( err ) && ( time( NULL ) < ( startTime + 5 ) ) );
	
	CKERR;

	if( getMessagesFromService )
	{
		(void) sGetClientSockPath( sockPath );
		(void) unlink( sockPath );
		err = sCreateIPCSocket( sockPath, &sock ); CKERR;
	}
	else
		sockPath[0] = '\0';

	err = PGPrpcPackAndWrite( context, netContext->sockToService,
		kPGPnet_MT_ClientConnect, "bs", getMessagesFromService, sockPath ); CKERR;
		
	if( getMessagesFromService )
	{
		/* Only wait 30 seconds for service to respond */
		tv.tv_sec = 30;
		tv.tv_usec = 0;
		
		FD_ZERO( &sockSet );
		FD_SET( sock, &sockSet );
		retval = select( sock + 1, &sockSet, NULL, NULL, &tv );
		if( retval <= 0 )
			RETERR( kPGPError_UnknownError );
	
		len = sizeof( sun );
		netContext->sockFromService = accept( sock, (struct sockaddr *) &sun, &len );
		if( netContext->sockFromService < 0 )
			RETERR( kPGPError_UnknownError );
	}
	else
		netContext->sockFromService = -1;

	netContext->context = context;
	
	*outNetContext = netContext;
	
done:
	if( IsPGPError( err ) )
	{
		(void) sGetClientSockPath( sockPath );
		(void) unlink( sockPath );

		if( IsntNull( netContext ) )
		{
			if( netContext->sockToService )
				(void) close( netContext->sockToService );
			if( netContext->sockFromService )
				(void) close( netContext->sockFromService );

			(void) PGPFreeData( netContext );
		}
	}
	return err;
}

	PGPError
PGPnetNewContext(
	PGPContextRef		context,
	PGPnetContextRef	*outNetContext )
{
	return sNewContextInternal( context, outNetContext, TRUE );
}
	
	PGPError
PGPnetFreeContext(
	PGPnetContextRef	netContext )
{
	char				sockPath[PATH_MAX];

	PGPnetValidateContextRef( netContext );

	if( netContext->sockToService > 0 )
		(void) close( netContext->sockToService );
	if( netContext->sockFromService > 0 )
		(void) close( netContext->sockFromService );

	(void) sGetClientSockPath( sockPath );
	(void) unlink( sockPath );

	(void) PGPFreeData( netContext );

	return kPGPError_NoErr;
}

	PGPContextRef
PGPnetPeekContextPGPContext(
	PGPnetContextRef	netContext )
{
	return netContext->context;
}

	PGPError
PGPnetRereadConfig(
	PGPnetContextRef	netContext )
{
	PGPError			err			= kPGPError_NoErr;
	
	PGPnetValidateContextRef( netContext );

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_RereadConfig, "" ); CKERR;

done:
	return err;
}

	PGPError
PGPnetTellServiceToClearLogFile(
	PGPnetContextRef	netContext )
{
	PGPError			err			= kPGPError_NoErr;
	
	PGPnetValidateContextRef( netContext );

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_ClearLogFile, "" ); CKERR;

done:
	return err;
}

	PGPError
PGPnetConnectToHost(
	PGPnetContextRef			netContext,
	PGPNetPrefHostEntry *		hostEntry )
{
	PGPError		err			= kPGPError_NoErr;
	PGPByte *		buf			= NULL;
	PGPnetSAIdent	said;

	PGPnetValidateContextRef( netContext );

	said.ipAddress		= hostEntry->ipAddrStart;
	said.ipAddrStart	= hostEntry->ipAddrStart;
	said.ipMaskEnd		= hostEntry->ipMaskEnd;
	said.destIsRange	= hostEntry->destIsRange;

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_Connect, "B", &said, sizeof( PGPnetSAIdent ) ); CKERR;

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

	return err;
}

	PGPError
PGPnetDisconnectFromHost(
	PGPnetContextRef		netContext,
	PGPipsecSA *			sa )
{
	PGPError			err			= kPGPError_NoErr;
	
	PGPnetValidateContextRef( netContext );

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_Disconnect, "B", sa->transform[0].inSPI, sizeof( PGPipsecSPI ) ); CKERR;

done:
	return err;
}

	PGPError
PGPnetGetSAList(
	PGPnetContextRef		netContext,
	PGPipsecSA **			sa,
	PGPSize *				numSAs )
{
	PGPError			err					= kPGPError_NoErr;
	PGPByte *			buf					= NULL;
	PGPSize				len					= 0;
	PGPUInt32			numSAsFromService	= 0;
	PGPipsecSA *		tempSAList			= NULL;
	
	PGPnetValidateContextRef( netContext );
	PGPValidatePtr( sa );
	PGPValidatePtr( numSAs );

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_GetSAList, "" ); CKERR;

	err = PGPrpcReadAndUnpack( netContext->context, netContext->sockToService,
		kPGPnet_MT_SendSAList, "uB", &numSAsFromService, &buf, &len ); CKERR;
		
	if( numSAsFromService * sizeof( PGPipsecSA ) != len )
	{
		/* Service said we have X SAs, but didn't send us the right size of data */
		RETERR( kPGPError_CorruptData );
	}
	
	tempSAList = PGPNewData( PGPPeekContextMemoryMgr( netContext->context ),
		len,
		kPGPMemoryMgrFlags_Clear );
	CKNULL( tempSAList );
	
	pgpCopyMemory( buf, tempSAList, len );
	
	*sa = tempSAList;
	*numSAs = numSAsFromService;

done:
	if( IsntNull( buf ) )
		(void) PGPFreeData( buf );
	return err;
}

	PGPError
PGPnetGetRemoteAuthKey(
	PGPnetContextRef		netContext,
	PGPipsecSA *			sa,
	PGPByte **				remoteAuthKey,
	PGPSize *				remoteAuthKeySize )
{
	PGPError			err					= kPGPError_NoErr;
	PGPByte *			buf					= NULL;
	PGPSize				len					= 0;
	
	PGPnetValidateContextRef( netContext );
	PGPValidatePtr( sa );
	PGPValidatePtr( remoteAuthKey );
	PGPValidatePtr( remoteAuthKeySize );

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_GetRemoteAuthKey, "B", sa->transform[0].inSPI, sizeof( PGPipsecSPI ) ); CKERR;

	err = PGPrpcReadAndUnpack( netContext->context, netContext->sockToService,
		kPGPnet_MT_SendRemoteAuthKey, "B", &buf, &len ); CKERR;
		
	*remoteAuthKey = buf;
	*remoteAuthKeySize = len;

done:
	return err;
}

	PGPError
PGPnetFlushPassphrases(
	PGPnetContextRef		netContext )
{
	PGPError			err			= kPGPError_NoErr;
	
	PGPnetValidateContextRef( netContext );

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_FlushPassphrases, "" ); CKERR;

done:
	return err;
}

	PGPError
PGPnetLogTraffic(
	PGPnetContextRef		netContext,
	PGPBoolean				allowed,
	PGPBoolean				blocked )
{
	PGPError			err			= kPGPError_NoErr;
	
	PGPnetValidateContextRef( netContext );

	err = PGPrpcPackAndWrite( netContext->context, netContext->sockToService,
		kPGPnet_MT_LogTraffic, "bb", allowed, blocked ); CKERR;

done:
	return err;

}

#if PGP_OSX
	PGPError
PGPnetAddMessageCallbackToCFRunLoop(
	PGPnetContextRef	netContext,
	CFRunLoopRef		rl,
	CFSocketCallBack	callback,
	PGPUserValue		userValue )
{
	CFSocketRef				socket;
	CFRunLoopSourceRef		source;
	CFSocketContext			socketContext;

	socketContext.version = 1;
	socketContext.info = userValue;
	socketContext.retain = NULL;
	socketContext.release = NULL;
	socketContext.copyDescription = NULL;
	
	socket = CFSocketCreateWithNative( kCFAllocatorDefault,
		netContext->sockFromService,

⌨️ 快捷键说明

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