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

📄 dbxdbms.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 2 页
字号:
	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( queryType == DBMS_QUERY_START  )
			dbmsInfo->flags |= DBMS_FLAG_QUERYACTIVE;
		if( queryType == DBMS_QUERY_CANCEL )
			dbmsInfo->flags &= ~DBMS_FLAG_QUERYACTIVE;
		if( dataLength != NULL )
			*dataLength = cmd.strArgLen[ 0 ];
		}
	else
		{
		if( ( queryType == DBMS_QUERY_CONTINUE ) && \
			( status == CRYPT_ERROR_COMPLETE ) )
			dbmsInfo->flags &= ~DBMS_FLAG_QUERYACTIVE;
		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							*
*																			*
****************************************************************************/

/* The escape char used to escape potentially dangerous values in SQL
   strings */

#define	SQL_ESCAPE	'\''

/* Format input parameters into SQL queries suitable for submission to the
   DBMS backend, with assorted safety checks of the query data */

void dbmsFormatSQL( 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++ ] = SQL_ESCAPE;

#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 = "\x00\x00";	/* 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 */

int dbmsFormatQuery( char *output, const char *input, const int inputLength,
					 const int maxLength )
	{
	int inPos = 0, outPos = 0, status = CRYPT_OK;

	while( inPos < inputLength )
		{
		if( input[ inPos ] == '$' )
			{
			const int fieldPos = inPos + 1;
			const char *fieldName = input + fieldPos;
			const char *outputFieldName;
			int length;

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

			/* Extract the field name and translate it into the table
			   column name */
			while( isAlpha( input[ inPos ] ) )
				inPos++;
			length = inPos - fieldPos;
			if( length <= 0 || length > 7 )
				{
				status = CRYPT_ERROR_BADDATA;
				break;
				}
			if( !strCompare( fieldName, "C", length ) )
				outputFieldName = "C";
			else
			if( !strCompare( fieldName, "SP", length ) )
				outputFieldName = "SP";
			else
			if( !strCompare( fieldName, "L", length ) )
				outputFieldName = "L";
			else
			if( !strCompare( fieldName, "O", length ) )
				outputFieldName = "O";
			else
			if( !strCompare( fieldName, "OU", length ) )
				outputFieldName = "OU";
			else
			if( !strCompare( fieldName, "CN", length ) )
				outputFieldName = "CN";
			else
			if( !strCompare( fieldName, "email", length ) )
				outputFieldName = "email";
			else
			if( !strCompare( fieldName, "date", length ) )
				outputFieldName = "validTo";
			else
				{
				status = CRYPT_ERROR_BADDATA;
				break;
				}
			length = strlen( outputFieldName );

			/* Copy the translated name to the output buffer */
			if( outPos + length >= maxLength - 1 )
				{
				status = CRYPT_ERROR_OVERFLOW;
				break;
				}
			memcpy( output + outPos, outputFieldName, length );
			outPos += length;
			}
		else
			{
			const char ch = input[ inPos++ ];

			/* Just copy the char over, with a length check */
			if( outPos > maxLength - 1 )
				{
				status = CRYPT_ERROR_OVERFLOW;
				break;
				}

			/* Safety checks from formatSQL */
			if( ( ch & 0x7F ) < ' ' )
				continue;
			if( ch == '\\' || ch == ';' || ch == '%' )
				/* Escape the character */
				output[ outPos++ ] = SQL_ESCAPE;
#ifdef __WINDOWS__
			if( ch != '|' )
#endif /* __WINDOWS__ */
			output[ outPos++ ] = ch;
			}
		}
	if( cryptStatusError( status ) )
		outPos = 0;
	output[ outPos++ ] = '\0';	/* Add der terminador */

	return( status );
	}

/* 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 backend 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 we have to handle is ODBC, which identifies the database 
   by name rather than server */

int dbmsParseName( DBMS_NAME_INFO *nameInfo, const char *name,
				   const int lengthMarker )
	{
	const char *namePtr, *argEndPtr;
	int length;

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

	/* Check for a complex database name */
	if( ( namePtr = strchr( name, ':' ) ) == NULL && \
		( namePtr = strchr( name, '@' ) ) == NULL )
		{
		/* It's a straightforward name, use it directly */
		nameInfo->name = ( char * ) name;
		nameInfo->nameLen = lengthMarker ? lengthMarker : strlen( name );
		return( CRYPT_OK );
		}

	/* Extract the user name */
	length = min( namePtr - name, CRYPT_MAX_TEXTSIZE );
	if( length <= 0 )
		return( CRYPT_ERROR_OPEN );
	memcpy( nameInfo->userBuffer, name, length );
	nameInfo->userBuffer[ length ] = '\0';
	nameInfo->user = nameInfo->userBuffer;
	nameInfo->userLen = lengthMarker ? lengthMarker : length;

	/* Extract the password if there is one */
	if( *namePtr++ == ':' )
		{
		argEndPtr = strchr( namePtr, '@' );
		if( argEndPtr == NULL )
			argEndPtr = strchr( namePtr, '\0' );
		length = min( argEndPtr - namePtr, CRYPT_MAX_TEXTSIZE );
		if( length <= 0 )
			return( CRYPT_ERROR_OPEN );
		memcpy( nameInfo->passwordBuffer, namePtr, length );
		nameInfo->passwordBuffer[ length ] = '\0';
		nameInfo->password = nameInfo->passwordBuffer;
		nameInfo->passwordLen = lengthMarker ? lengthMarker : length;
		if( !*argEndPtr )
			return( CRYPT_OK );
		namePtr = argEndPtr + 1;
		}

	/* Separate the server and database name if necessary */
	argEndPtr = strchr( namePtr, '/' );
	if( argEndPtr != NULL )
		{
		/* There's a distinction between the server name and database name,
		   extract the server name */
		length = min( argEndPtr - namePtr, CRYPT_MAX_TEXTSIZE );
		if( length <= 0 )
			return( CRYPT_ERROR_OPEN );
		memcpy( nameInfo->serverBuffer, namePtr, length );
		nameInfo->serverBuffer[ length ] = '\0';
		nameInfo->server = nameInfo->serverBuffer;
		nameInfo->serverLen = lengthMarker ? lengthMarker : length;
		namePtr = argEndPtr + 1;
		}

	/* Extract the database name if there is one */
	if( *namePtr )
		{
		length = strlen( namePtr );
		memcpy( nameInfo->nameBuffer, namePtr, length );
		nameInfo->nameBuffer[ length ] = '\0';
		nameInfo->name = nameInfo->nameBuffer;
		nameInfo->nameLen = lengthMarker ? lengthMarker : length;
		}
	
	return( CRYPT_OK );
	}

/* Initialise and shut down a session with a database backend */

int initDbxSession( KEYSET_INFO *keysetInfo, const CRYPT_KEYSET_TYPE type )
	{
	DBMS_INFO *dbmsInfo = keysetInfo->keysetDBMS;

	/* Select the appropriate dispatch function for the keyset type */
	switch( type )
		{
		case CRYPT_KEYSET_ODBC:
		case CRYPT_KEYSET_ODBC_STORE:
			dbmsInfo->dispatchFunction = odbcProcessCommand;
			break;
		case CRYPT_KEYSET_DATABASE:
		case CRYPT_KEYSET_DATABASE_STORE:
			dbmsInfo->dispatchFunction = databaseProcessCommand;
			break;
		case CRYPT_KEYSET_PLUGIN:
		case CRYPT_KEYSET_PLUGIN_STORE:
			dbmsInfo->dispatchFunction = netProcessCommand;
			break;
		default:
			assert( NOTREACHED );
		}
	if( dbmsInfo->dispatchFunction == NULL )
		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( ( keysetInfo->keyData = \
			clAlloc( "initDbxSession", sizeof( DBMS_STATE_INFO ) ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( keysetInfo->keyData, 0, sizeof( DBMS_STATE_INFO ) );
	keysetInfo->keyDataSize = sizeof( DBMS_STATE_INFO );
	dbmsInfo->stateInfo = keysetInfo->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 );
	}

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

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

⌨️ 快捷键说明

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