From 6c5ef7ad9e1ba65ad2bdd3395a9cedccc20ad62b Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Thu, 14 Sep 2017 17:42:28 -0700 Subject: [PATCH] add error handling for using sqlsrv_query without sqltype in a column encryption enabled connection --- source/sqlsrv/php_sqlsrv.h | 3 +- source/sqlsrv/stmt.cpp | 9 +- source/sqlsrv/util.cpp | 4 + .../sqlsrv_encrypted_query_nosqltype.phpt | 138 ++++++++++++++++++ 4 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 test/functional/sqlsrv/sqlsrv_encrypted_query_nosqltype.phpt diff --git a/source/sqlsrv/php_sqlsrv.h b/source/sqlsrv/php_sqlsrv.h index f2e128c7..baa0b2c1 100644 --- a/source/sqlsrv/php_sqlsrv.h +++ b/source/sqlsrv/php_sqlsrv.h @@ -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[]; diff --git a/source/sqlsrv/stmt.cpp b/source/sqlsrv/stmt.cpp index a515b394..a548bfc6 100644 --- a/source/sqlsrv/stmt.cpp +++ b/source/sqlsrv/stmt.cpp @@ -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; diff --git a/source/sqlsrv/util.cpp b/source/sqlsrv/util.cpp index ccf5c1ad..1d10f878 100644 --- a/source/sqlsrv/util.cpp +++ b/source/sqlsrv/util.cpp @@ -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 { diff --git a/test/functional/sqlsrv/sqlsrv_encrypted_query_nosqltype.phpt b/test/functional/sqlsrv/sqlsrv_encrypted_query_nosqltype.phpt new file mode 100644 index 00000000..362898de --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_encrypted_query_nosqltype.phpt @@ -0,0 +1,138 @@ +--TEST-- +Test using sqlserv_query for binding parameters with ColumnEncryption enabled and a custome keystore provider +--SKIPIF-- + +--FILE-- +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 \ No newline at end of file