add error handling for using sqlsrv_query without sqltype in a column encryption enabled connection

This commit is contained in:
v-kaywon 2017-09-14 17:42:28 -07:00
parent 5f7eb415a4
commit 6c5ef7ad9e
4 changed files with 151 additions and 3 deletions

View file

@ -353,7 +353,8 @@ enum SS_ERROR_CODES {
SS_SQLSRV_ERROR_CONNECT_BRACES_NOT_ESCAPED,
SS_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE,
SS_SQLSRV_ERROR_PARAM_VAR_NOT_REF,
SS_SQLSRV_ERROR_INVALID_AUTHENTICATION_OPTION
SS_SQLSRV_ERROR_INVALID_AUTHENTICATION_OPTION,
SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED
};
extern ss_error SS_ERRORS[];

View file

@ -1222,6 +1222,9 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
value_z = var;
}
else {
CHECK_CUSTOM_ERROR( !stmt->prepared && stmt->conn->ce_option.enabled, stmt, SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED ) {
throw ss::SSException();
}
value_z = param_z;
}
// bind the parameter
@ -1974,9 +1977,11 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
sql_type = sqlsrv_sql_type.typeinfo.type;
}
// else the sql type and size are uknown, so tell the core layer to use its defaults
// else the sql type and size are unknown, so tell the core layer to use its defaults
else {
CHECK_CUSTOM_ERROR( !stmt->prepared && stmt->conn->ce_option.enabled, stmt, SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED ) {
throw ss::SSException();
}
sql_type_param_was_null = true;
sql_type = SQL_UNKNOWN_TYPE;

View file

@ -370,6 +370,10 @@ ss_error SS_ERRORS[] = {
SS_SQLSRV_ERROR_INVALID_AUTHENTICATION_OPTION,
{ IMSSP, (SQLCHAR*)"Invalid option for the Authentication keyword. Only SqlPassword or ActiveDirectoryPassword is supported.", -62, false }
},
{
SS_SQLSRV_ERROR_AE_QUERY_SQLTYPE_REQUIRED,
{ IMSSP, (SQLCHAR*)"Using sqlsrv_query for binding parameters in a Column Encryption enabled connection requires the sqltype to be provided.", -63, false }
},
// internal warning definitions
{

View file

@ -0,0 +1,138 @@
--TEST--
Test using sqlserv_query for binding parameters with ColumnEncryption enabled and a custome keystore provider
--SKIPIF--
<?php require('skipif_server_old.inc'); ?>
--FILE--
<?php
function CreatePatientsTable()
{
global $conn;
$tablename = 'Patients';
$stmt = sqlsrv_query( $conn, "IF OBJECT_ID('$tablename', 'U') IS NOT NULL DROP TABLE $tablename" );
sqlsrv_free_stmt( $stmt );
$tsql = "CREATE TABLE $tablename (
[PatientId] [int] IDENTITY(1,1) NOT NULL,
[SSN] [char](11) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = CustomCEK, ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
[FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = CustomCEK, ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL,
[LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = CustomCEK, ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL,
[BirthDate] [date] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = CustomCEK, ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL)";
$stmt = sqlsrv_query( $conn, $tsql );
if (! $stmt )
{
echo "Failed to create test table!\n";
die( print_r( sqlsrv_errors(), true ));
}
return $tablename;
}
function SelectData()
{
global $conn, $tablename;
$stmt = sqlsrv_query($conn, "SELECT * FROM $tablename");
while ($obj = sqlsrv_fetch_object( $stmt ))
{
echo $obj->PatientId . "\n";
echo $obj->SSN . "\n";
echo $obj->FirstName . "\n";
echo $obj->LastName . "\n";
echo $obj->BirthDate . "\n\n";
}
}
function PrintError()
{
$errors = sqlsrv_errors();
foreach ( $errors as $error )
{
echo " SQLSTATE: " . $error['SQLSTATE'] . "\n";
echo " code: " . $error['code'] . "\n";
echo " message: " . $error['message'] . "\n\n";
}
}
sqlsrv_configure( 'WarningsReturnAsErrors', 1 );
sqlsrv_configure( 'LogSeverity', SQLSRV_LOG_SEVERITY_ALL );
require_once( 'MsSetup.inc' );
require_once( 'AE_Ksp.inc' );
$ksp_path = getKSPpath();
$connectionInfo = array( "Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
"ReturnDatesAsStrings"=>true, "ColumnEncryption"=>'Enabled',
"CEKeystoreProvider"=>$ksp_path,
"CEKeystoreName"=>$ksp_name,
"CEKeystoreEncryptKey"=>$encrypt_key);
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Failed to connect.\n";
PrintError();
}
else
{
echo "Connected successfully with ColumnEncryption enabled.\n\n";
}
$tablename = CreatePatientsTable();
$tsql = "INSERT INTO $tablename (SSN, FirstName, LastName, BirthDate) VALUES (?, ?, ?, ?)";
$inputs = array( '748-68-0245', 'Jeannette', 'McDonald', '2002-11-28' );
//expects an error in Column Encryption enabled connection
print_r( "Using sqlsrv_query and binding parameters with literal values:\n" );
$stmt = sqlsrv_query( $conn, $tsql, $inputs );
if ( !$stmt)
PrintError();
//expects an error in Column Encryption enabled connection
print_r( "Using sqlsrv_query and binding parameters with parameter arrays and no sqltypes provided:\n" );
$stmt = sqlsrv_query( $conn, $tsql, array( array( $inputs[0], SQLSRV_PARAM_IN ),
array( $inputs[1], SQLSRV_PARAM_IN ),
array( $inputs[2], SQLSRV_PARAM_IN ),
array( $inputs[3], SQLSRV_PARAM_IN )));
if ( !$stmt)
PrintError();
//no error is expected
print_r( "Using sqlsrv_query and binding parameters with parameter arrays and sqltypes provided:\n" );
$stmt = sqlsrv_query( $conn, $tsql, array( array( $inputs[0], null, null, SQLSRV_SQLTYPE_CHAR(11) ),
array( $inputs[1], null, null, SQLSRV_SQLTYPE_NVARCHAR(50) ),
array( $inputs[2], null, null, SQLSRV_SQLTYPE_NVARCHAR(50) ),
array( $inputs[3], null, null, SQLSRV_SQLTYPE_DATE ) ));
if ( !$stmt)
PrintError();
SelectData();
echo "Done\n";
?>
--EXPECT--
Connected successfully with ColumnEncryption enabled.
Using sqlsrv_query and binding parameters with literal values:
SQLSTATE: IMSSP
code: -63
message: Using sqlsrv_query for binding parameters in a Column Encryption enabled connection requires the sqltype to be provided.
Using sqlsrv_query and binding parameters with parameter arrays and no sqltypes provided:
SQLSTATE: IMSSP
code: -63
message: Using sqlsrv_query for binding parameters in a Column Encryption enabled connection requires the sqltype to be provided.
Using sqlsrv_query and binding parameters with parameter arrays and sqltypes provided:
1
748-68-0245
Jeannette
McDonald
2002-11-28
Done