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

📄 lib_dbms.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
		putMessageWord( bufPtr, argLength );
		if( argLength > 0 )
			memcpy( bufPtr + COMMAND_WORDSIZE, sentCmd.strArg[ i ],
					argLength );
		bufPtr += COMMAND_WORDSIZE + argLength;
		}

	/* Send the command to the server and read the server's message header */
	dispatchFunction( stateInfo, buffer );
	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 );
	resultLength = getMessageLength( header + COMMAND_WORDSIZE );
	if( !dbxCheckCommandInfo( cmd, resultLength ) || \
		cmd->type != COMMAND_RESULT )
		return( CRYPT_ERROR );
	if( ( cmd->noStrArgs && cmd->strArgLen[ 0 ] ) && \
		( sentCmd.type != DBX_COMMAND_QUERY && \
		  sentCmd.type != DBX_COMMAND_GETERRORINFO ) )
		/* Only these commands can return data */
		return( CRYPT_ERROR );

	/* Read the rest of the server's 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 ];
		}

	/* The first value returned is the status code, if it's nonzero return
	   it to the caller, otherwise move the other values down */
	if( cryptStatusError( cmd->arg[ 0 ] ) )
		return( cmd->arg[ 0 ] );
	assert( cryptStatusOK( cmd->arg[ 0 ] ) );
	for( i = 1; i < cmd->noArgs; i++ )
		cmd->arg[ i - 1 ] = cmd->arg[ i ];
	cmd->arg[ i ] = 0;
	cmd->noArgs--;

	/* Copy any string arg data back to the caller */
	if( cmd->noStrArgs && cmd->strArgLen[ 0 ] )
		{
		const int maxBufSize = ( sentCmd.type == DBX_COMMAND_QUERY ) ? \
							   MAX_QUERY_RESULT_SIZE : MAX_ERRMSG_SIZE;
		const int argIndex = sentCmd.noStrArgs;

		memcpy( sentCmd.strArg[ argIndex ], cmd->strArg[ 0 ],
				min( cmd->strArgLen[ 0 ], maxBufSize ) );
		cmd->strArg[ 0 ] = sentCmd.strArg[ argIndex ];
		}

	return( CRYPT_OK );
	}

/* Database access functions */

static int openDatabase( DBMS_INFO *dbmsInfo, const char *name,
						 const char *server, const char *user,
						 const char *password, const int options )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_OPEN, COMMAND_FLAG_NONE, 1, 1 };
	COMMAND_INFO cmd;
	int status;

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	cmd.arg[ 0 ] = options;
	cmd.strArg[ 0 ] = ( void * ) name;
	cmd.strArgLen[ 0 ] = strlen( name );
	status = dispatchCommand( &cmd, dbmsInfo->stateInfo,
							  dbmsInfo->dispatchFunction );
	if( cryptStatusOK( status ) )
		dbmsInfo->hasBinaryBlobs = ( cmd.arg[ 0 ] & DBMS_FLAG_BINARYBLOBS ) ? \
								   TRUE : FALSE;
	return( status );
	}

static void closeDatabase( DBMS_INFO *dbmsInfo )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_CLOSE, COMMAND_FLAG_NONE, 0, 0 };
	COMMAND_INFO cmd;

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	dispatchCommand( &cmd, dbmsInfo->stateInfo, dbmsInfo->dispatchFunction );
	}

static void performErrorQuery( DBMS_INFO *dbmsInfo )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_GETERRORINFO, COMMAND_FLAG_NONE, 0, 0 };
	COMMAND_INFO cmd;
	int status;

	/* Clear the return values */
	memset( dbmsInfo->errorMessage, 0, MAX_ERRMSG_SIZE );
	*dbmsInfo->errorCode = 0;

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	cmd.strArg[ 0 ] = dbmsInfo->errorMessage;
	cmd.strArgLen[ 0 ] = 0;
	status = dispatchCommand( &cmd, dbmsInfo->stateInfo,
							  dbmsInfo->dispatchFunction );
	if( cryptStatusOK( status ) )
		{
		*dbmsInfo->errorCode = cmd.arg[ 0 ];
		dbmsInfo->errorMessage[ cmd.strArgLen[ 0 ] ] = '\0';
		}
	}

static int performUpdate( DBMS_INFO *dbmsInfo, const char *command,
						  const BOOLEAN hasBoundData,
						  const time_t boundDate,
						  const DBMS_UPDATE_TYPE updateType )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_UPDATE, COMMAND_FLAG_NONE, 1, 0 };
	COMMAND_INFO cmd;
	BYTE encodedDate[ 8 ];
	int argIndex = 1, status;

	/* If we're trying to abort a transaction which was never begun, don't
	   do anything */
	if( updateType == DBMS_UPDATE_ABORT && !dbmsInfo->updateActive )
		return( CRYPT_OK );

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	cmd.arg[ 0 ] = updateType;
	if( command != NULL )
		{
		cmd.noStrArgs = 1;
		cmd.strArg[ 0 ] = ( void * ) command;
		cmd.strArgLen[ 0 ] = strlen( command );
		}
	if( boundDate )
		{
#ifndef _BIG_WORDS
		assert( sizeof( time_t ) <= 4 );
#endif /* !_BIG_WORDS */

		/* Encode the date as a 64-bit value */
		memset( encodedDate, 0, 8 );
#ifdef _BIG_WORDS
		encodedDate[ 3 ] = ( BYTE )( ( boundDate >> 32 ) & 0xFF );
#endif /* _BIG_WORDS */
		encodedDate[ 4 ] = ( BYTE )( ( boundDate >> 24 ) & 0xFF );
		encodedDate[ 5 ] = ( BYTE )( ( boundDate >> 16 ) & 0xFF );
		encodedDate[ 6 ] = ( BYTE )( ( boundDate >> 8 ) & 0xFF );
		encodedDate[ 7 ] = ( BYTE )( ( boundDate ) & 0xFF );
		cmd.noStrArgs++;
		cmd.strArg[ argIndex ] = encodedDate;
		cmd.strArgLen[ argIndex++ ] = 8;
		}
	if( hasBoundData )
		{
		cmd.noStrArgs++;
		cmd.strArg[ argIndex ] = dbmsInfo->boundCertData;
		cmd.strArgLen[ argIndex++ ] = dbmsInfo->boundCertDataLen;
		}
	status = dispatchCommand( &cmd, dbmsInfo->stateInfo,
							  dbmsInfo->dispatchFunction );
	if( cryptStatusError( status ) )
		performErrorQuery( dbmsInfo );
	else
		{
		/* If we're starting or ending an update, record the update state */
		if( updateType == DBMS_UPDATE_BEGIN )
			dbmsInfo->updateActive = TRUE;
		if( updateType == DBMS_UPDATE_COMMIT || \
			updateType == DBMS_UPDATE_ABORT )
			dbmsInfo->updateActive = FALSE;
		}
	return( status );
	}

static int performStaticUpdate( DBMS_INFO *dbmsInfo, const char *command )
	{
	return( performUpdate( dbmsInfo, command, FALSE, 0,
						   DBMS_UPDATE_NORMAL ) );
	}

static int performQuery( DBMS_INFO *dbmsInfo, const char *command,
						 char *data, int *dataLength, const time_t date,
						 const DBMS_QUERY_TYPE queryType )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_QUERY, COMMAND_FLAG_NONE, 1, 1 };
	COMMAND_INFO cmd;
	BYTE encodedDate[ 8 ];
	int argIndex = 1, status;

	/* Clear return value */
	if( data != NULL )
		{
		memset( data, 0, 16 );
		*dataLength = -1;
		}

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	cmd.arg[ 0 ] = queryType;
	if( command != NULL )
		{
		cmd.strArg[ 0 ] = ( void * ) command;
		cmd.strArgLen[ 0 ] = strlen( command );
		}
	else
		{
		cmd.noStrArgs = 0;
		argIndex = 0;
		}
	if( date )
		{
#ifndef _BIG_WORDS
		assert( sizeof( time_t ) <= 4 );
#endif /* !_BIG_WORDS */

		/* Encode the date as a 64-bit value */
		memset( encodedDate, 0, 8 );
#ifdef _BIG_WORDS
		encodedDate[ 3 ] = ( BYTE )( ( date >> 32 ) & 0xFF );
#endif /* _BIG_WORDS */
		encodedDate[ 4 ] = ( BYTE )( ( date >> 24 ) & 0xFF );
		encodedDate[ 5 ] = ( BYTE )( ( date >> 16 ) & 0xFF );
		encodedDate[ 6 ] = ( BYTE )( ( date >> 8 ) & 0xFF );
		encodedDate[ 7 ] = ( BYTE )( ( date ) & 0xFF );
		cmd.strArg[ 1 ] = encodedDate;
		cmd.strArgLen[ 1 ] = 8;
		cmd.noStrArgs++;
		argIndex++;
		}
	cmd.strArg[ argIndex ] = data;
	cmd.strArgLen[ argIndex ] = 0;
	status = dispatchCommand( &cmd, dbmsInfo->stateInfo,
							  dbmsInfo->dispatchFunction );
	if( cryptStatusOK( status ) )
		{
		if( dataLength != NULL )
			*dataLength = cmd.strArgLen[ 0 ];
		}
	else
		performErrorQuery( dbmsInfo );
	return( status );
	}

static int performStaticQuery( DBMS_INFO *dbmsInfo, const char *command,
							   const DBMS_QUERY_TYPE queryType )
	{
	return( performQuery( dbmsInfo, command, NULL, NULL, 0, queryType ) );
	}

/****************************************************************************
*																			*
*								Utility Routines							*
*																			*
****************************************************************************/

/* Format input parameters into SQL queries suitable for submission to the
   DBMS backend.  We could use sprintf() but there are problems with
   potential buffer overruns for long args, so we use the following function
   which acts as a (very minimal) string formatter in which all '$'s in the
   input are replaced by the next input string */

static void formatSQL( char *buffer, const char *format, ... )
	{
	va_list argPtr;
	char *formatPtr = ( char * ) format;
	int bufPos = 0;

	va_start( argPtr, format );
	while( *formatPtr )
		{
		if( *formatPtr == '$' )
			{
			char *strPtr = va_arg( argPtr, char * );

			assert( strPtr != NULL );	/* Catch a shortage of args */

			/* Copy the string to the output buffer with conversion of any
			   special characters which are used by SQL */
			while( *strPtr )
				{
				int ch = *strPtr++;

				/* If it's a control character, skip it */
				if( ( ch & 0x7F ) < ' ' )
					continue;

				/* Escape metacharacters which could be misused in queries,
				   for example by specifying a key 'foo; DROP TABLE bar' or
				   similar shenanigans.  We catch the obvious ' and ;, as 
				   well as the less obvious %, which could be used to hide 
				   other metacharacters.  Note that none of these characters 
				   are valid in base64, which makes it safe to escape them 
				   in the few instances where they do occur */
				if( ch == '\'' || ch == '\\' || ch == ';' || ch == '%' )
					/* Escape the character */
					buffer[ bufPos++ ] = '\'';

#ifdef __WINDOWS__
				/* Bypass a Microsoft ODBC "enhancement" in which the driver
				   will execute anything delimited by '|'s as an expression
				   (an example being '|shell("cmd /c echo " & chr(124) &
				   " format c:")|').  Because of this we strip gazintas if
				   we're running under Windoze */
				if( ch != '|' )
#endif /* __WINDOWS__ */
				buffer[ bufPos++ ] = ch;

				/* Make sure we haven't overflowed the input buffer.  We
				   check for MAX_SQL_QUERY_SIZE - 3 rather than
				   MAX_SQL_QUERY_SIZE - 2 in case the next character needs
				   escaping which expands it to two chars (MAX_SQL_QUERY_SIZE
				   - 1 is used for the '\0') */
				if( bufPos > MAX_SQL_QUERY_SIZE - 3 )
					{
					bufPos = 0;
					formatPtr = "";	/* Force exit on outer loop */
					break;
					}
				}

			formatPtr++;
			}
		else
			{
			/* Just copy the char over, with a length check */
			if( bufPos > MAX_SQL_QUERY_SIZE - 1 )
				{
				bufPos = 0;
				break;
				}
			buffer[ bufPos++ ] = *formatPtr++;
			}
		}
	buffer[ bufPos++ ] = '\0';	/* Add der terminador */

	va_end( argPtr );
	}

/* Format input parameters into SQL queries, replacing meta-values with
   actual column names */

static int formatQuery( char *output, const char *input, const int inputLength,

⌨️ 快捷键说明

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