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

📄 dbms.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
	*bufPos = position;

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
static int copyStringArg( OUT_BUFFER( bufMaxLen, *bufPos ) char *buffer, 
						  IN_LENGTH_SHORT_Z const int bufMaxLen, 
						  OUT_LENGTH_SHORT_Z int *bufPos, 
						  IN_BUFFER( stringLen ) const char *string,
						  IN_LENGTH_SHORT const int stringLen )
	{
	int index, position = 0;

	assert( isWritePtr( buffer, bufMaxLen ) );
	assert( isWritePtr( bufPos, sizeof( int ) ) );
	assert( isReadPtr( string, stringLen ) );

	REQUIRES( bufMaxLen >= 0 && bufMaxLen < MAX_INTLENGTH_SHORT );
	REQUIRES( stringLen > 0 && stringLen < MAX_INTLENGTH_SHORT );

	/* Make sure that there's room for at least one more character of 
	   output */
	if( bufMaxLen < 1 )
		return( CRYPT_ERROR_OVERFLOW );

	/* Copy the string to the output buffer with conversion of any special 
	   characters that are used by SQL */
	for( index = 0; index < stringLen && \
					index < FAILSAFE_ITERATIONS_MAX; index++ )
		{
		int charsWritten, status;

		status = copyChar( buffer + position, bufMaxLen - position, 
						   &charsWritten, string[ index ], TRUE );
		if( cryptStatusError( status ) )
			return( status );
		position += charsWritten;
		if( position > bufMaxLen )
			{
			/* Already checked in copyChar() but we double-check here to be 
			   safe */
			return( CRYPT_ERROR_OVERFLOW );
			}
		}
	ENSURES( index < FAILSAFE_ITERATIONS_MAX );
	*bufPos = position;

	return( CRYPT_OK );
	}

/* Format input parameters into SQL queries, replacing meta-values with
   actual column names, and null-terminate the resulting string so that
   it can be fed to the database backend */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
int dbmsFormatQuery( OUT_BUFFER( outMaxLength, *outLength ) char *output, 
					 IN_LENGTH_SHORT const int outMaxLength, 
					 OUT_LENGTH_SHORT_Z int *outLength,
					 IN_BUFFER( inputLength ) const char *input, 
					 IN_LENGTH_SHORT const int inputLength )
	{
	int inPos, outPos = 0, status = CRYPT_OK;

	assert( isWritePtr( output, outMaxLength ) );
	assert( isWritePtr( outLength, sizeof( int ) ) );
	assert( isReadPtr( input, inputLength ) );

	REQUIRES( outMaxLength >= 0 && outMaxLength < MAX_INTLENGTH_SHORT );
	REQUIRES( inputLength > 0 && inputLength < MAX_INTLENGTH_SHORT );

	/* Clear return values */
	memset( output, 0, min( 16, outMaxLength ) );
	*outLength = 0;

	for( inPos = 0; inPos < inputLength && inPos < FAILSAFE_ITERATIONS_MAX; )
		{
		int length;

		if( input[ inPos ] == '$' )
			{
			typedef struct {
				BUFFER_FIXED( sourceLength ) \
				char *sourceName;
				int sourceLength;
				BUFFER_FIXED( destLength ) \
				char *destName;
				int destLength;
				} NAMEMAP_INFO;
			static const NAMEMAP_INFO nameMapTbl[] = {
				{ "C", 1, "C", 1 }, { "SP", 2, "SP", 2 },
				{ "L", 1, "L", 1 }, { "O", 1, "O", 1 },
				{ "OU", 2, "OU", 2 }, { "CN", 2, "CN", 2 },
				{ "email", 5, "email", 5 }, { "uri", 3, "email", 5 },
				{ "date", 4, "validTo", 7 }, 
				{ NULL, 0, NULL, 0 }, { NULL, 0, NULL, 0 }
				};
			const int fieldPos = inPos + 1;
			const char *fieldName = input + fieldPos;
			int i;

			inPos++;	/* Skip '$' */

			/* Extract the field name and translate it into the table
			   column name */
			while( inPos < inputLength && isAlpha( input[ inPos ] ) )
				inPos++;
			length = inPos - fieldPos;
			if( length <= 0 || length > 5 )
				{
				status = CRYPT_ERROR_BADDATA;
				break;
				}
			for( i = 0; nameMapTbl[ i ].sourceName != NULL && \
						i < FAILSAFE_ARRAYSIZE( nameMapTbl, NAMEMAP_INFO ); 
				 i++ )
				{
				if( length == nameMapTbl[ i ].sourceLength && \
					!strCompare( fieldName, nameMapTbl[ i ].sourceName, \
								 length ) )
					break;
				}
			ENSURES( i < FAILSAFE_ARRAYSIZE( nameMapTbl, NAMEMAP_INFO ) );
			if( nameMapTbl[ i ].sourceName == NULL )
				{
				status = CRYPT_ERROR_BADDATA;
				break;
				}

			/* Copy the translated name to the output buffer */
			status = copyStringArg( output + outPos, outMaxLength - outPos, 
									&length, nameMapTbl[ i ].destName,
									nameMapTbl[ i ].destLength );
			}
		else
			{
			/* Just copy the character over, with a length check.  We don't 
			   escape single quotes in this case because we use these 
			   ourselves in SQL queries */
			status = copyChar( output + outPos, outMaxLength - outPos, 
							   &length, input[ inPos++ ], FALSE );
			}
		if( cryptStatusError( status ) )
			break;
		outPos += length;
		}
	ENSURES( inPos < FAILSAFE_ITERATIONS_MAX );
	if( cryptStatusError( status ) )
		outPos = 0;
	output[ outPos ] = '\0';	/* Add der terminador */
	*outLength = outPos;

	return( status );
	}

/****************************************************************************
*																			*
*							Back-end Interface Routines						*
*																			*
****************************************************************************/

/* Parse a user-supplied database name into individual components, used by
   the database back-end connect functions.  We don't do a syntax check
   (since the exact syntax is database-specific) but merely break the single
   string up into any recognisable components.  The database back-end can
   determine whether the format is valid or not.  The general format that we
   look for is:

	[generic name]
	user:pass
	user@server
	user:pass@server
	user:pass@server/name

   One distinction that we make is that if there's something after an '@'
   and there's no server/name separator present we treat it as a name rather 
   than a server.  In other words @foo results in name=foo while @foo/bar 
   results in server=foo, name=bar.  This is because the most common 
   situation that we have to handle is ODBC, which identifies the database 
   by name rather than by server */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int dbmsParseName( INOUT DBMS_NAME_INFO *nameInfo, 
				   IN_BUFFER( nameLen ) const char *name, 
				   IN_LENGTH_NAME const int nameLen )
	{
	int offset, offset2, length;

	assert( isWritePtr( nameInfo, sizeof( DBMS_NAME_INFO ) ) );
	assert( isReadPtr( name, nameLen ) );

	REQUIRES( nameLen >= MIN_NAME_LENGTH && \
			  nameLen < MAX_ATTRIBUTE_SIZE );

	memset( nameInfo, 0, sizeof( DBMS_NAME_INFO ) );

	/* Check for a complex database name */
	if( ( offset = strFindCh( name, nameLen, ':' ) ) < 0 && \
		( offset = strFindCh( name, nameLen, '@' ) ) < 0 )
		{
		/* It's a straightforward name, use it directly */
		nameInfo->name = ( char * ) name;
		nameInfo->nameLen = nameLen;

		return( CRYPT_OK );
		}

	/* Extract the user name */
	length = min( offset, CRYPT_MAX_TEXTSIZE );
	if( length <= 0 )
		return( CRYPT_ERROR_OPEN );
	memcpy( nameInfo->userBuffer, name, length );
	nameInfo->user = nameInfo->userBuffer;
	nameInfo->userLen = length;

	/* We're either at the server name or password, extract the password
	   if there is one */
	ENSURES( name[ offset ] == ':' || name[ offset ] == '@' );
	if( name[ offset++ ] == ':' )
		{
		offset2 = strFindCh( name + offset, nameLen - offset, '@' );
		if( offset2 < 0 )
			offset2 = nameLen - offset;	/* Password is rest of string */
		length = min( offset2, CRYPT_MAX_TEXTSIZE );
		if( length <= 0 )
			return( CRYPT_ERROR_OPEN );
		memcpy( nameInfo->passwordBuffer, name + offset, length );
		nameInfo->password = nameInfo->passwordBuffer;
		nameInfo->passwordLen = length;
		offset += offset2 + 1;
		if( offset >= nameLen )
			return( CRYPT_OK );
		}

	/* Separate the server and database name if necessary */
	offset2 = strFindCh( name + offset, nameLen - offset, '/' );
	if( offset2 >= 0 )
		{
		/* There's a distinction between the server name and database name,
		   extract the server name */
		length = min( offset2, CRYPT_MAX_TEXTSIZE );
		if( length <= 0 )
			return( CRYPT_ERROR_OPEN );
		memcpy( nameInfo->serverBuffer, name + offset, length );
		nameInfo->server = nameInfo->serverBuffer;
		nameInfo->serverLen = length;
		offset += offset2 + 1;
		}

	/* Extract the database name if there is one */
	if( offset < nameLen )
		{
		length = nameLen - offset;
		if( length <= 0 || length > CRYPT_MAX_TEXTSIZE )
			return( CRYPT_ERROR_OPEN );
		memcpy( nameInfo->nameBuffer, name + offset, length );
		nameInfo->name = nameInfo->nameBuffer;
		nameInfo->nameLen = length;
		}

	return( CRYPT_OK );
	}

/* Initialise and shut down a session with a database back-end */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int initDbxSession( INOUT KEYSET_INFO *keysetInfoPtr, 
					IN_ENUM( CRYPT_KEYSET ) const CRYPT_KEYSET_TYPE type )
	{
	DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
	int status = CRYPT_ERROR;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
	REQUIRES( type > CRYPT_KEYSET_NONE && type < CRYPT_KEYSET_LAST );

	/* Select the appropriate dispatch function for the keyset type */
	switch( type )
		{
		case CRYPT_KEYSET_ODBC:
		case CRYPT_KEYSET_ODBC_STORE:
			status = initDispatchODBC( dbmsInfo );
			break;

		case CRYPT_KEYSET_DATABASE:
		case CRYPT_KEYSET_DATABASE_STORE:
			status = initDispatchDatabase( dbmsInfo );
			break;

		case CRYPT_KEYSET_PLUGIN:
		case CRYPT_KEYSET_PLUGIN_STORE:
			status = initDispatchNet( dbmsInfo );
			break;

		default:
			retIntError();
		}
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_NUM1 );

	/* Set up the remaining function pointers */
	dbmsInfo->openDatabaseFunction = openDatabase;
	dbmsInfo->closeDatabaseFunction = closeDatabase;
	dbmsInfo->performUpdateFunction = performUpdate;
	dbmsInfo->performStaticUpdateFunction = performStaticUpdate;
	dbmsInfo->performQueryFunction = performQuery;
	dbmsInfo->performStaticQueryFunction = performStaticQuery;

	/* Allocate the database session state information */
	if( ( keysetInfoPtr->keyData = \
			clAlloc( "initDbxSession", sizeof( DBMS_STATE_INFO ) ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( keysetInfoPtr->keyData, 0, sizeof( DBMS_STATE_INFO ) );
	keysetInfoPtr->keyDataSize = sizeof( DBMS_STATE_INFO );
	dbmsInfo->stateInfo = keysetInfoPtr->keyData;
	if( type == CRYPT_KEYSET_ODBC_STORE || \
		type == CRYPT_KEYSET_DATABASE_STORE || \
		type == CRYPT_KEYSET_PLUGIN_STORE )
		dbmsInfo->flags |= DBMS_FLAG_CERTSTORE | DBMS_FLAG_CERTSTORE_FIELDS;

	return( CRYPT_OK );
	}

RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int endDbxSession( INOUT KEYSET_INFO *keysetInfoPtr )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );

	/* Free the database session state information if necessary */
	if( keysetInfoPtr->keyData != NULL )
		{
		memset( keysetInfoPtr->keyData, 0, keysetInfoPtr->keyDataSize );
		clFree( "endDbxSession", keysetInfoPtr->keyData );
		keysetInfoPtr->keyData = NULL;
		}

	return( CRYPT_OK );
	}
#endif /* USE_DBMS */

⌨️ 快捷键说明

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