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

📄 dbx_rpc.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
字号:
/****************************************************************************
*																			*
*						 cryptlib Database RPC Interface					*
*						Copyright Peter Gutmann 1997-2002					*
*																			*
****************************************************************************/

/* This file isn't a standalone module but is meant to be #included into
   whichever of the dbxXXXX.c database client files it's used with */

#include <stdlib.h>
#if defined( INC_ALL )
  #include "crypt.h"
  #include "keyset.h"
  #include "rpc.h"
#elif defined( INC_CHILD )
  #include "../crypt.h"
  #include "keyset.h"
  #include "../misc/rpc.h"
#else
  #include "crypt.h"
  #include "keyset/keyset.h"
  #include "misc/rpc.h"
#endif /* Compiler-specific includes */

/* Handlers for the various commands */

static int cmdClose( void *stateInfo, COMMAND_INFO *cmd )
	{
	assert( cmd->type == DBX_COMMAND_CLOSE );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 0 );
	assert( cmd->noStrArgs == 0 );

	closeDatabase( stateInfo );
	return( CRYPT_OK );
	}

static int cmdGetErrorInfo( void *stateInfo, COMMAND_INFO *cmd )
	{
	assert( cmd->type == DBX_COMMAND_GETERRORINFO );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 0 );
	assert( cmd->noStrArgs == 1 );

	performErrorQuery( stateInfo, &cmd->arg[ 0 ], cmd->strArg[ 0 ] );
	cmd->strArgLen[ 0 ] = strlen( cmd->strArg[ 0 ] );
	return( CRYPT_OK );
	}

static int cmdOpen( void *stateInfo, COMMAND_INFO *cmd )
	{
	int hasBinaryBlobs, status;

	assert( cmd->type == DBX_COMMAND_OPEN );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 1 );
	assert( cmd->arg[ 0 ] >= CRYPT_KEYOPT_NONE && \
			cmd->arg[ 0 ] < CRYPT_KEYOPT_LAST );
	assert( cmd->noStrArgs == 1 );

	status = openDatabase( stateInfo, cmd->strArg[ 0 ], cmd->arg[ 0 ],
						   &hasBinaryBlobs );
	if( cryptStatusOK( status ) )
		cmd->arg[ 0 ] = hasBinaryBlobs;
	return( status );
	}

static int cmdQuery( void *stateInfo, COMMAND_INFO *cmd )
	{
	const void *dataPtr = cmd->strArg[ 1 ];
	const int argIndex = cmd->noStrArgs - 1;
	time_t timeValue = 0;
	int dataLength, status;

	assert( cmd->type == DBX_COMMAND_QUERY );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 1 );
	assert( cmd->arg[ 0 ] >= DBMS_QUERY_NORMAL && \
			cmd->arg[ 0 ] <= DBMS_QUERY_CANCEL );
	assert( cmd->noStrArgs >= 1 && cmd->noStrArgs <= 3 );

	/* If one of the string args is a bound date, convert it into a time_t */
	if( cmd->noStrArgs >= 2 && cmd->strArgLen[ 1 ] == 8 )
		{
		const BYTE *timeValuePtr = cmd->strArg[ 1 ];

		/* Extract the time_t from the 64-bit time value */
#ifdef _BIG_WORDS
		timeValue = ( time_t ) timeValuePtr[ 3 ] << 32 | \
					( time_t ) timeValuePtr[ 4 ] << 24 | \
					( time_t ) timeValuePtr[ 5 ] << 16 | \
					( time_t ) timeValuePtr[ 6 ] << 8 | \
					( time_t ) timeValuePtr[ 7 ];
#else
		timeValue = ( time_t ) timeValuePtr[ 4 ] << 24 | \
					( time_t ) timeValuePtr[ 5 ] << 16 | \
					( time_t ) timeValuePtr[ 6 ] << 8 | \
					( time_t ) timeValuePtr[ 7 ];
#endif /* _BIG_WORDS */
		}

	status = performQuery( stateInfo, cmd->strArg[ 0 ],
						   cmd->strArg[ argIndex ], &dataLength, timeValue,
						   cmd->arg[ 0 ] );
	if( cryptStatusOK( status ) )
		cmd->strArgLen[ argIndex ] = \
								( cmd->arg[ 0 ] == DBMS_QUERY_NORMAL || \
								  cmd->arg[ 0 ] == DBMS_QUERY_CONTINUE ) ? \
								dataLength : 0;
	return( status );
	}

static int cmdUpdate( void *stateInfo, COMMAND_INFO *cmd )
	{
	const void *dataPtr = cmd->strArg[ 1 ];
	int dataLength = cmd->strArgLen[ 1 ];
	time_t timeValue = 0;

	assert( cmd->type == DBX_COMMAND_UPDATE );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 1 );
	assert( cmd->noStrArgs >= 0 && cmd->noStrArgs <= 3 );

	/* If one of the string args is a bound date, convert it into a time_t */
	if( cmd->noStrArgs >= 2 && cmd->strArgLen[ 1 ] == 8 )
		{
		const BYTE *timeValuePtr = cmd->strArg[ 1 ];

		/* Extract the time_t from the 64-bit time value */
#ifdef _BIG_WORDS
		timeValue = ( time_t ) timeValuePtr[ 3 ] << 32 | \
					( time_t ) timeValuePtr[ 4 ] << 24 | \
					( time_t ) timeValuePtr[ 5 ] << 16 | \
					( time_t ) timeValuePtr[ 6 ] << 8 | \
					( time_t ) timeValuePtr[ 7 ];
#else
		timeValue = ( time_t ) timeValuePtr[ 4 ] << 24 | \
					( time_t ) timeValuePtr[ 5 ] << 16 | \
					( time_t ) timeValuePtr[ 6 ] << 8 | \
					( time_t ) timeValuePtr[ 7 ];
#endif /* _BIG_WORDS */

		/* Since the first arg is the date, the data will be in the second
		   arg */
		dataPtr = cmd->strArg[ 2 ];
		dataLength = cmd->strArgLen[ 2 ];
		}

	return( performUpdate( stateInfo, cmd->strArg[ 0 ],
						   dataLength ? dataPtr : NULL, dataLength,
						   timeValue, cmd->arg[ 0 ] ) );
	}

/* Process a command from the client and send it to the appropriate handler */

static const COMMAND_HANDLER commandHandlers[] = {
	NULL, NULL, cmdOpen, cmdClose, cmdQuery, cmdUpdate, cmdGetErrorInfo };

void processCommand( void *stateInfo, BYTE *buffer )
	{
	COMMAND_INFO cmd = { 0 };
	BYTE header[ COMMAND_FIXED_DATA_SIZE ], *bufPtr;
	long totalLength;
	int i, status;

	/* Read the client's message header */
	memcpy( header, buffer, COMMAND_FIXED_DATA_SIZE );

	/* Process the fixed message header and make sure it's valid */
	getMessageType( header, cmd.type, cmd.flags, cmd.noArgs, cmd.noStrArgs );
	totalLength = getMessageLength( header + COMMAND_WORDSIZE );
	if( !dbxCheckCommandInfo( &cmd, totalLength ) || \
		cmd.type == COMMAND_RESULT )
		{
		assert( NOTREACHED );

		/* Return an invalid result message */
		putMessageType( buffer, COMMAND_RESULT, 0, 0, 0 );
		putMessageLength( buffer + COMMAND_WORDSIZE, 0 );
		return;
		}

	/* Read the rest of the clients message */
	bufPtr = buffer + COMMAND_FIXED_DATA_SIZE;
	for( i = 0; i < cmd.noArgs; i++ )
		{
		cmd.arg[ i ] = getMessageWord( bufPtr );
		bufPtr += COMMAND_WORDSIZE;
		}
	for( i = 0; i < cmd.noStrArgs; i++ )
		{
		cmd.strArgLen[ i ] = getMessageWord( bufPtr );
		cmd.strArg[ i ] = bufPtr + COMMAND_WORDSIZE;
		bufPtr += COMMAND_WORDSIZE + cmd.strArgLen[ i ];
		}
	if( !dbxCheckCommandConsistency( &cmd, totalLength ) )
		{
		assert( NOTREACHED );

		/* Return an invalid result message */
		putMessageType( buffer, COMMAND_RESULT, 0, 0, 0 );
		putMessageLength( buffer + COMMAND_WORDSIZE, 0 );
		return;
		}

	/* If it's a command which returns a string value, obtain the returned
	   data in the buffer.  Normally we limit the size to the maximum
	   attribute size, however encoded objects and data popped from
	   envelopes/sessions can be larger than this so we use the entire buffer
	   minus a safety margin */
	if( cmd.type == DBX_COMMAND_QUERY || \
		cmd.type == DBX_COMMAND_GETERRORINFO )
		{
		cmd.strArg[ cmd.noStrArgs ] = bufPtr;
		cmd.strArgLen[ cmd.noStrArgs ] = ( cmd.type == DBX_COMMAND_QUERY ) ? \
										 MAX_ENCODED_CERT_SIZE : MAX_ERRMSG_SIZE;
		cmd.noStrArgs++;
		}

	/* Null-terminate the first string arg if there's one present, either the
	   database name or the SQL command.  If there's something following it
	   in the buffer this is redundant (but safe) because it'll already be
	   followed by the MSB of the next string arg's length, if there's
	   nothing following it it's safe as well */
	if( cmd.type == DBX_COMMAND_OPEN || \
		( cmd.type == DBX_COMMAND_UPDATE && \
		  cmd.arg[ 0 ] != DBMS_UPDATE_ABORT ) || \
		( cmd.type == DBX_COMMAND_QUERY && \
		  ( cmd.arg[ 0 ] == DBMS_QUERY_NORMAL || \
		    cmd.arg[ 0 ] == DBMS_QUERY_CHECK || \
			cmd.arg[ 0 ] == DBMS_QUERY_START ) ) )
		( ( char * ) cmd.strArg[ 0 ] )[ cmd.strArgLen[ 0 ] ] = '\0';

	/* Process the command and copy any return information back to the
	   caller */
	status = commandHandlers[ cmd.type ]( stateInfo, &cmd );
	bufPtr = buffer;
	if( cryptStatusError( status ) )
		{
		/* The command failed, return a simple status value */
		putMessageType( bufPtr, COMMAND_RESULT, 0, 1, 0 );
		putMessageLength( bufPtr + COMMAND_WORDSIZE, COMMAND_WORDSIZE );
		putMessageWord( bufPtr + COMMAND_WORD1_OFFSET, status );
		return;
		}
	if( cmd.type == DBX_COMMAND_OPEN )
		{
		/* Return numeric value */
		putMessageType( bufPtr, COMMAND_RESULT, 0, 2, 0 );
		putMessageLength( bufPtr + COMMAND_WORDSIZE, COMMAND_WORDSIZE * 2 );
		putMessageWord( bufPtr + COMMAND_WORD1_OFFSET, CRYPT_OK );
		putMessageWord( bufPtr + COMMAND_WORD2_OFFSET, cmd.arg[ 0 ] );
		return;
		}
	if( cmd.type == DBX_COMMAND_QUERY )
		{
		const int argIndex = cmd.noStrArgs - 1;
		const long dataLength = cmd.strArgLen[ argIndex ];

		/* Return data and length.  In some cases (during ongoing queries
		   with no submitted SQL data) we can be called without any incoming
		   args, there's no space at the start of the shared input/output
		   buffer so we have to move the returned string back in the buffer
		   to avoid overwriting it with the other information we're about to
		   return */
		if( dataLength )
			memmove( bufPtr + COMMAND_WORD3_OFFSET,
					 cmd.strArg[ argIndex ], dataLength );
		putMessageType( bufPtr, COMMAND_RESULT, 0, 1, 1 );
		putMessageLength( bufPtr + COMMAND_WORDSIZE,
						  ( COMMAND_WORDSIZE * 2 ) + cmd.strArgLen[ argIndex ] );
		putMessageWord( bufPtr + COMMAND_WORD1_OFFSET, CRYPT_OK );
		putMessageWord( bufPtr + COMMAND_WORD2_OFFSET, dataLength );
		return;
		}
	if( cmd.type == DBX_COMMAND_GETERRORINFO )
		{
		const long dataLength = cmd.strArgLen[ 0 ];

		/* Return data and length.  Because we were called without any
		   incoming args, there's no space at the start of the shared input/
		   output buffer so we have to move the returned string back in the
		   buffer to avoid overwriting it with the other information we're
		   about to return */
		if( dataLength )
			memmove( bufPtr + COMMAND_WORD4_OFFSET, cmd.strArg[ 0 ],
					 dataLength );
		putMessageType( bufPtr, COMMAND_RESULT, 0, 2, 1 );
		putMessageLength( bufPtr + COMMAND_WORDSIZE,
						  ( COMMAND_WORDSIZE * 2 ) + cmd.strArgLen[ 0 ] );
		putMessageWord( bufPtr + COMMAND_WORD1_OFFSET, CRYPT_OK );
		putMessageWord( bufPtr + COMMAND_WORD2_OFFSET, cmd.arg[ 0 ] );
		putMessageWord( bufPtr + COMMAND_WORD3_OFFSET, dataLength );
		return;
		}
	putMessageType( bufPtr, COMMAND_RESULT, 0, 1, 0 );
	putMessageLength( bufPtr + COMMAND_WORDSIZE, COMMAND_WORDSIZE );
	putMessageWord( bufPtr + COMMAND_WORD1_OFFSET, CRYPT_OK );
	}

⌨️ 快捷键说明

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