зеркало из https://github.com/microsoft/msphpsql.git
Merge pull request #682 from yitam/ridKSP
Removed support for Custom Keystore provider
This commit is contained in:
Коммит
f2e82229bc
110
.travis.yml
110
.travis.yml
|
@ -1,58 +1,52 @@
|
|||
sudo: required
|
||||
|
||||
os: linux
|
||||
dist: trusty
|
||||
|
||||
group: edge
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
global:
|
||||
- REPORT_EXIT_STATUS=1
|
||||
- ACCEPT_EULA=Y
|
||||
- PHPSQLDIR=/REPO/msphpsql-dev
|
||||
- TEST_PHP_SQL_SERVER=sql
|
||||
- SQLSRV_DBNAME=msphpsql_sqlsrv
|
||||
- PDOSQLSRV_DBNAME=msphpsql_pdosqlsrv
|
||||
- TEST_PHP_SQL_UID=sa
|
||||
- TEST_PHP_SQL_PWD=Password123
|
||||
|
||||
before_install:
|
||||
- docker pull microsoft/mssql-server-linux:2017-latest
|
||||
|
||||
install:
|
||||
- docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Password123' -p 1433:1433 --name=$TEST_PHP_SQL_SERVER -d microsoft/mssql-server-linux:2017-latest
|
||||
- docker build --build-arg PHPSQLDIR=$PHPSQLDIR -t msphpsql-dev -f Dockerfile-msphpsql .
|
||||
|
||||
before_script:
|
||||
- sleep 30
|
||||
|
||||
script:
|
||||
- travis_retry docker run -e TRAVIS_JOB_ID -t -d -w $PHPSQLDIR --name=client --link $TEST_PHP_SQL_SERVER msphpsql-dev
|
||||
- docker ps -a
|
||||
- docker logs client
|
||||
- travis_retry docker exec client python ./test/functional/setup/setup_dbs.py -dbname $SQLSRV_DBNAME
|
||||
- travis_retry docker exec client python ./test/functional/setup/setup_dbs.py -dbname $PDOSQLSRV_DBNAME
|
||||
- docker exec client cp ./source/shared/msodbcsql.h ./test/functional/setup/
|
||||
- travis_retry docker exec client python ./test/functional/setup/build_ksp.py
|
||||
- docker exec client cp ./test/functional/setup/myKSP.so ./test/functional/sqlsrv/
|
||||
- docker exec client cp ./test/functional/setup/myKSP.so ./test/functional/pdo_sqlsrv/
|
||||
- travis_retry docker exec client python ./test/functional/setup/run_ksp.py -server $TEST_PHP_SQL_SERVER -dbname $SQLSRV_DBNAME -uid $TEST_PHP_SQL_UID -pwd $TEST_PHP_SQL_PWD
|
||||
- travis_retry docker exec client python ./test/functional/setup/run_ksp.py -server $TEST_PHP_SQL_SERVER -dbname $PDOSQLSRV_DBNAME -uid $TEST_PHP_SQL_UID -pwd $TEST_PHP_SQL_PWD
|
||||
- travis_retry docker exec client php ./source/pdo_sqlsrv/run-tests.php ./test/functional/pdo_sqlsrv/*.phpt
|
||||
- travis_retry docker exec client php ./source/sqlsrv/run-tests.php ./test/functional/sqlsrv/*.phpt
|
||||
- docker exec client bash -c 'for f in ./test/functional/sqlsrv/*.diff; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client bash -c 'for f in ./test/functional/sqlsrv/*.out; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client bash -c 'for f in ./test/functional/pdo_sqlsrv/*.diff; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client bash -c 'for f in ./test/functional/pdo_sqlsrv/*.out; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client python ./test/functional/setup/cleanup_dbs.py -dbname $SQLSRV_DBNAME
|
||||
- docker exec client python ./test/functional/setup/cleanup_dbs.py -dbname $PDOSQLSRV_DBNAME
|
||||
- docker exec client coveralls -e ./source/shared/ --gcov-options '\-lp'
|
||||
- docker stop client
|
||||
- docker ps -a
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
sudo: required
|
||||
|
||||
os: linux
|
||||
dist: trusty
|
||||
|
||||
group: edge
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
global:
|
||||
- REPORT_EXIT_STATUS=1
|
||||
- ACCEPT_EULA=Y
|
||||
- PHPSQLDIR=/REPO/msphpsql-dev
|
||||
- TEST_PHP_SQL_SERVER=sql
|
||||
- SQLSRV_DBNAME=msphpsql_sqlsrv
|
||||
- PDOSQLSRV_DBNAME=msphpsql_pdosqlsrv
|
||||
- TEST_PHP_SQL_UID=sa
|
||||
- TEST_PHP_SQL_PWD=Password123
|
||||
|
||||
before_install:
|
||||
- docker pull microsoft/mssql-server-linux:2017-latest
|
||||
|
||||
install:
|
||||
- docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Password123' -p 1433:1433 --name=$TEST_PHP_SQL_SERVER -d microsoft/mssql-server-linux:2017-latest
|
||||
- docker build --build-arg PHPSQLDIR=$PHPSQLDIR -t msphpsql-dev -f Dockerfile-msphpsql .
|
||||
|
||||
before_script:
|
||||
- sleep 30
|
||||
|
||||
script:
|
||||
- travis_retry docker run -e TRAVIS_JOB_ID -t -d -w $PHPSQLDIR --name=client --link $TEST_PHP_SQL_SERVER msphpsql-dev
|
||||
- docker ps -a
|
||||
- docker logs client
|
||||
- travis_retry docker exec client python ./test/functional/setup/setup_dbs.py -dbname $SQLSRV_DBNAME
|
||||
- travis_retry docker exec client python ./test/functional/setup/setup_dbs.py -dbname $PDOSQLSRV_DBNAME
|
||||
- travis_retry docker exec client php ./source/pdo_sqlsrv/run-tests.php ./test/functional/pdo_sqlsrv/*.phpt
|
||||
- travis_retry docker exec client php ./source/sqlsrv/run-tests.php ./test/functional/sqlsrv/*.phpt
|
||||
- docker exec client bash -c 'for f in ./test/functional/sqlsrv/*.diff; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client bash -c 'for f in ./test/functional/sqlsrv/*.out; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client bash -c 'for f in ./test/functional/pdo_sqlsrv/*.diff; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client bash -c 'for f in ./test/functional/pdo_sqlsrv/*.out; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
|
||||
- docker exec client python ./test/functional/setup/cleanup_dbs.py -dbname $SQLSRV_DBNAME
|
||||
- docker exec client python ./test/functional/setup/cleanup_dbs.py -dbname $PDOSQLSRV_DBNAME
|
||||
- docker exec client coveralls -e ./source/shared/ --gcov-options '\-lp'
|
||||
- docker stop client
|
||||
- docker ps -a
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
|
|
|
@ -150,12 +150,6 @@ test_script:
|
|||
- python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\setup_dbs.py -dbname %SQLSRV_DBNAME%
|
||||
- Echo setup test database for PDO_SQLSRV tests - %PDOSQLSRV_DBNAME%
|
||||
- python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\setup_dbs.py -dbname %PDOSQLSRV_DBNAME%
|
||||
#- copy %APPVEYOR_BUILD_FOLDER%\source\shared\msodbcsql.h %APPVEYOR_BUILD_FOLDER%\test\functional\setup\
|
||||
#- python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\build_ksp.py
|
||||
#- copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\
|
||||
#- copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\
|
||||
#- python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %SQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD%
|
||||
#- python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD%
|
||||
- ps: >-
|
||||
If ($env:SQL_INSTANCE -Match "SQL2016") {
|
||||
Write-Host "Running phpt tests via OpenCppCoverage..."
|
||||
|
|
|
@ -42,13 +42,9 @@ const char ApplicationIntent[] = "ApplicationIntent";
|
|||
const char AttachDBFileName[] = "AttachDbFileName";
|
||||
const char ConnectionPooling[] = "ConnectionPooling";
|
||||
const char Authentication[] = "Authentication";
|
||||
const char ColumnEncryption[] = "ColumnEncryption";
|
||||
const char Driver[] = "Driver";
|
||||
const char CEKeystoreProvider[] = "CEKeystoreProvider";
|
||||
const char CEKeystoreName[] = "CEKeystoreName";
|
||||
const char CEKeystoreEncryptKey[] = "CEKeystoreEncryptKey";
|
||||
|
||||
#ifdef _WIN32
|
||||
const char ColumnEncryption[] = "ColumnEncryption";
|
||||
const char ConnectRetryCount[] = "ConnectRetryCount";
|
||||
const char ConnectRetryInterval[] = "ConnectRetryInterval";
|
||||
#endif // _WIN32
|
||||
|
@ -226,15 +222,6 @@ const connection_option PDO_CONN_OPTS[] = {
|
|||
CONN_ATTR_BOOL,
|
||||
conn_null_func::func
|
||||
},
|
||||
{
|
||||
PDOConnOptionNames::ColumnEncryption,
|
||||
sizeof(PDOConnOptionNames::ColumnEncryption),
|
||||
SQLSRV_CONN_OPTION_COLUMNENCRYPTION,
|
||||
ODBCConnOptions::ColumnEncryption,
|
||||
sizeof(ODBCConnOptions::ColumnEncryption),
|
||||
CONN_ATTR_STRING,
|
||||
column_encryption_set_func::func
|
||||
},
|
||||
{
|
||||
PDOConnOptionNames::Driver,
|
||||
sizeof(PDOConnOptionNames::Driver),
|
||||
|
@ -244,34 +231,16 @@ const connection_option PDO_CONN_OPTS[] = {
|
|||
CONN_ATTR_STRING,
|
||||
driver_set_func::func
|
||||
},
|
||||
{
|
||||
PDOConnOptionNames::CEKeystoreProvider,
|
||||
sizeof(PDOConnOptionNames::CEKeystoreProvider),
|
||||
SQLSRV_CONN_OPTION_CEKEYSTORE_PROVIDER,
|
||||
ODBCConnOptions::CEKeystoreProvider,
|
||||
sizeof(ODBCConnOptions::CEKeystoreProvider),
|
||||
CONN_ATTR_STRING,
|
||||
ce_ksp_provider_set_func::func
|
||||
},
|
||||
{
|
||||
PDOConnOptionNames::CEKeystoreName,
|
||||
sizeof(PDOConnOptionNames::CEKeystoreName),
|
||||
SQLSRV_CONN_OPTION_CEKEYSTORE_NAME,
|
||||
ODBCConnOptions::CEKeystoreName,
|
||||
sizeof(ODBCConnOptions::CEKeystoreName),
|
||||
CONN_ATTR_STRING,
|
||||
ce_ksp_provider_set_func::func
|
||||
},
|
||||
{
|
||||
PDOConnOptionNames::CEKeystoreEncryptKey,
|
||||
sizeof(PDOConnOptionNames::CEKeystoreEncryptKey),
|
||||
SQLSRV_CONN_OPTION_CEKEYSTORE_ENCRYPT_KEY,
|
||||
ODBCConnOptions::CEKeystoreEncryptKey,
|
||||
sizeof(ODBCConnOptions::CEKeystoreEncryptKey),
|
||||
CONN_ATTR_STRING,
|
||||
ce_ksp_provider_set_func::func
|
||||
},
|
||||
#ifdef _WIN32
|
||||
{
|
||||
PDOConnOptionNames::ColumnEncryption,
|
||||
sizeof(PDOConnOptionNames::ColumnEncryption),
|
||||
SQLSRV_CONN_OPTION_COLUMNENCRYPTION,
|
||||
ODBCConnOptions::ColumnEncryption,
|
||||
sizeof(ODBCConnOptions::ColumnEncryption),
|
||||
CONN_ATTR_STRING,
|
||||
column_encryption_set_func::func
|
||||
},
|
||||
{
|
||||
PDOConnOptionNames::ConnectRetryCount,
|
||||
sizeof( PDOConnOptionNames::ConnectRetryCount ),
|
||||
|
|
|
@ -381,22 +381,6 @@ pdo_error PDO_ERRORS[] = {
|
|||
PDO_SQLSRV_ERROR_INVALID_AUTHENTICATION_OPTION,
|
||||
{ IMSSP, (SQLCHAR*) "Invalid option for the Authentication keyword. Only SqlPassword or ActiveDirectoryPassword is supported.", -73, false }
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_NAME_MISSING,
|
||||
{ IMSSP, (SQLCHAR*) "The name of the custom keystore provider is missing.", -74, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_PATH_MISSING,
|
||||
{ IMSSP, (SQLCHAR*) "The path to the custom keystore provider is missing.", -75, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_KEY_MISSING,
|
||||
{ IMSSP, (SQLCHAR*) "The encryption key for the custom keystore provider is missing.", -76, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_INVALID_VALUE,
|
||||
{ IMSSP, (SQLCHAR*) "Invalid value for loading a custom keystore provider.", -77, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_CE_DRIVER_REQUIRED,
|
||||
{ IMSSP, (SQLCHAR*) "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.", -78, false }
|
||||
|
|
|
@ -71,7 +71,6 @@ const char* get_processor_arch( void );
|
|||
void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len) char** server_version, _Out_ SQLSMALLINT& len TSRMLS_DC );
|
||||
connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ const char* key, _In_ SQLULEN key_len TSRMLS_DC );
|
||||
void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str TSRMLS_DC );
|
||||
void load_configure_ksp( _Inout_ sqlsrv_conn* conn TSRMLS_DC );
|
||||
}
|
||||
|
||||
// core_sqlsrv_connect
|
||||
|
@ -246,8 +245,6 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
|
|||
throw core::CoreException();
|
||||
}
|
||||
|
||||
load_configure_ksp( conn );
|
||||
|
||||
// determine the version of the server we're connected to. The server version is left in the
|
||||
// connection upon return.
|
||||
//
|
||||
|
@ -935,66 +932,6 @@ void determine_server_version( _Inout_ sqlsrv_conn* conn TSRMLS_DC )
|
|||
conn->server_version = version_major;
|
||||
}
|
||||
|
||||
// Column Encryption feature: if a custom keystore provider is specified,
|
||||
// load and configure it when column encryption is enabled, but this step has
|
||||
// to be executed after the connection has been established
|
||||
void load_configure_ksp( _Inout_ sqlsrv_conn* conn TSRMLS_DC )
|
||||
{
|
||||
// If column encryption is not enabled simply do nothing. Otherwise, check if a custom keystore provider
|
||||
// is required for encryption or decryption. Note, in order to load and configure a custom keystore provider,
|
||||
// all KSP fields in conn->ce_option must be defined.
|
||||
if ( ! conn->ce_option.enabled || ! conn->ce_option.ksp_required )
|
||||
return;
|
||||
|
||||
// Do something like the following sample
|
||||
// use the KSP related fields in conn->ce_option
|
||||
// CEKEYSTOREDATA is defined in msodbcsql.h
|
||||
// https://docs.microsoft.com/en-us/sql/connect/odbc/custom-keystore-providers
|
||||
|
||||
CHECK_CUSTOM_ERROR( conn->ce_option.ksp_name == NULL, conn, SQLSRV_ERROR_KEYSTORE_NAME_MISSING) {
|
||||
throw core::CoreException();
|
||||
}
|
||||
|
||||
CHECK_CUSTOM_ERROR( conn->ce_option.ksp_path == NULL, conn, SQLSRV_ERROR_KEYSTORE_PATH_MISSING) {
|
||||
throw core::CoreException();
|
||||
}
|
||||
|
||||
CHECK_CUSTOM_ERROR( conn->ce_option.key_size == 0, conn, SQLSRV_ERROR_KEYSTORE_KEY_MISSING) {
|
||||
throw core::CoreException();
|
||||
}
|
||||
|
||||
char* ksp_name = Z_STRVAL_P( conn->ce_option.ksp_name );
|
||||
char* ksp_path = Z_STRVAL_P( conn->ce_option.ksp_path );
|
||||
unsigned int name_len = static_cast<unsigned int>( Z_STRLEN_P( conn->ce_option.ksp_name ));
|
||||
unsigned int key_size = static_cast<unsigned int>( conn->ce_option.key_size );
|
||||
|
||||
sqlsrv_malloc_auto_ptr<unsigned char> ksp_data;
|
||||
|
||||
ksp_data = reinterpret_cast<unsigned char*>( sqlsrv_malloc( sizeof( CEKEYSTOREDATA ) + key_size ) );
|
||||
|
||||
CEKEYSTOREDATA *pKsd = reinterpret_cast<CEKEYSTOREDATA*>( ksp_data.get() );
|
||||
|
||||
pKsd->dataSize = key_size;
|
||||
|
||||
// First, convert conn->ce_option.ksp_name to a WCHAR version
|
||||
unsigned int wname_len = 0;
|
||||
sqlsrv_malloc_auto_ptr<SQLWCHAR> wksp_name;
|
||||
wksp_name = utf16_string_from_mbcs_string( SQLSRV_ENCODING_UTF8, ksp_name, name_len, &wname_len );
|
||||
|
||||
CHECK_CUSTOM_ERROR( wksp_name == 0, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE ) {
|
||||
throw core::CoreException();
|
||||
}
|
||||
|
||||
pKsd->name = (wchar_t *) wksp_name.get();
|
||||
|
||||
// Next, extract the character string from conn->ce_option.ksp_encrypt_key into encrypt_key
|
||||
char* encrypt_key = Z_STRVAL_P( conn->ce_option.ksp_encrypt_key );
|
||||
memcpy_s( pKsd->data, key_size * sizeof( char ) , encrypt_key, key_size );
|
||||
|
||||
core::SQLSetConnectAttr( conn, SQL_COPT_SS_CEKEYSTOREPROVIDER, ksp_path, SQL_NTS );
|
||||
core::SQLSetConnectAttr( conn, SQL_COPT_SS_CEKEYSTOREDATA, reinterpret_cast<SQLPOINTER>( pKsd ), SQL_IS_POINTER );
|
||||
}
|
||||
|
||||
void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str TSRMLS_DC )
|
||||
{
|
||||
// wrap a connection option in a quote. It is presumed that any character that need to be escaped will
|
||||
|
@ -1068,36 +1005,6 @@ void column_encryption_set_func::func( _In_ connection_option const* option, _In
|
|||
conn_str += ";";
|
||||
}
|
||||
|
||||
void ce_ksp_provider_set_func::func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC )
|
||||
{
|
||||
SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_STRING, "Wrong zval type for this keyword" )
|
||||
|
||||
size_t value_len = Z_STRLEN_P( value );
|
||||
|
||||
CHECK_CUSTOM_ERROR( value_len == 0, conn, SQLSRV_ERROR_KEYSTORE_INVALID_VALUE ) {
|
||||
throw core::CoreException();
|
||||
}
|
||||
|
||||
switch ( option->conn_option_key ) {
|
||||
case SQLSRV_CONN_OPTION_CEKEYSTORE_PROVIDER:
|
||||
conn->ce_option.ksp_path = value;
|
||||
conn->ce_option.ksp_required = true;
|
||||
break;
|
||||
case SQLSRV_CONN_OPTION_CEKEYSTORE_NAME:
|
||||
conn->ce_option.ksp_name = value;
|
||||
conn->ce_option.ksp_required = true;
|
||||
break;
|
||||
case SQLSRV_CONN_OPTION_CEKEYSTORE_ENCRYPT_KEY:
|
||||
conn->ce_option.ksp_encrypt_key = value;
|
||||
conn->ce_option.key_size = value_len;
|
||||
conn->ce_option.ksp_required = true;
|
||||
break;
|
||||
default:
|
||||
SQLSRV_ASSERT(false, "ce_ksp_provider_set_func: Invalid KSP option!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to evaluate whether a string value is true or false.
|
||||
// Values = ("true" or "1") are treated as true values. Everything else is treated as false.
|
||||
// Returns 1 for true and 0 for false.
|
||||
|
|
|
@ -1056,13 +1056,8 @@ struct stmt_option;
|
|||
// This holds the various details of column encryption.
|
||||
struct col_encryption_option {
|
||||
bool enabled; // column encryption enabled, false by default
|
||||
zval_auto_ptr ksp_name; // keystore provider name
|
||||
zval_auto_ptr ksp_path; // keystore provider path to the dynamically linked libary (either a *.dll or *.so)
|
||||
zval_auto_ptr ksp_encrypt_key; // the encryption key used to configure the keystore provider
|
||||
size_t key_size; // the length of ksp_encrypt_key without the NULL terminator
|
||||
bool ksp_required; // a keystore provider is required to enable column encryption, false by default
|
||||
|
||||
col_encryption_option() : enabled( false ), key_size ( 0 ), ksp_required( false )
|
||||
col_encryption_option() : enabled( false )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -1109,14 +1104,11 @@ const char APP[] = "APP";
|
|||
const char ApplicationIntent[] = "ApplicationIntent";
|
||||
const char AttachDBFileName[] = "AttachDbFileName";
|
||||
const char Authentication[] = "Authentication";
|
||||
const char ColumnEncryption[] = "ColumnEncryption";
|
||||
const char Driver[] = "Driver";
|
||||
const char CEKeystoreProvider[] = "CEKeystoreProvider";
|
||||
const char CEKeystoreName[] = "CEKeystoreName";
|
||||
const char CEKeystoreEncryptKey[] = "CEKeystoreEncryptKey";
|
||||
const char CharacterSet[] = "CharacterSet";
|
||||
const char ConnectionPooling[] = "ConnectionPooling";
|
||||
#ifdef _WIN32
|
||||
const char ColumnEncryption[] = "ColumnEncryption";
|
||||
const char ConnectRetryCount[] = "ConnectRetryCount";
|
||||
const char ConnectRetryInterval[] = "ConnectRetryInterval";
|
||||
#endif // _WIN32
|
||||
|
@ -1709,10 +1701,6 @@ enum SQLSRV_ERROR_CODES {
|
|||
SQLSRV_ERROR_FIELD_INDEX_ERROR,
|
||||
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
|
||||
SQLSRV_ERROR_INVALID_BUFFER_LIMIT,
|
||||
SQLSRV_ERROR_KEYSTORE_NAME_MISSING,
|
||||
SQLSRV_ERROR_KEYSTORE_PATH_MISSING,
|
||||
SQLSRV_ERROR_KEYSTORE_KEY_MISSING,
|
||||
SQLSRV_ERROR_KEYSTORE_INVALID_VALUE,
|
||||
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
|
||||
SQLSRV_ERROR_ENCRYPTED_STREAM_FETCH,
|
||||
|
||||
|
|
|
@ -187,13 +187,9 @@ const char AttachDBFileName[] = "AttachDbFileName";
|
|||
const char CharacterSet[] = "CharacterSet";
|
||||
const char Authentication[] = "Authentication";
|
||||
const char ConnectionPooling[] = "ConnectionPooling";
|
||||
const char ColumnEncryption[] = "ColumnEncryption";
|
||||
const char Driver[] = "Driver";
|
||||
const char CEKeystoreProvider[] = "CEKeystoreProvider";
|
||||
const char CEKeystoreName[] = "CEKeystoreName";
|
||||
const char CEKeystoreEncryptKey[] = "CEKeystoreEncryptKey";
|
||||
|
||||
#ifdef _WIN32
|
||||
const char ColumnEncryption[] = "ColumnEncryption";
|
||||
const char ConnectRetryCount[] = "ConnectRetryCount";
|
||||
const char ConnectRetryInterval[] = "ConnectRetryInterval";
|
||||
#endif // _WIN32
|
||||
|
@ -307,15 +303,6 @@ const connection_option SS_CONN_OPTS[] = {
|
|||
CONN_ATTR_BOOL,
|
||||
conn_null_func::func
|
||||
},
|
||||
{
|
||||
SSConnOptionNames::ColumnEncryption,
|
||||
sizeof(SSConnOptionNames::ColumnEncryption),
|
||||
SQLSRV_CONN_OPTION_COLUMNENCRYPTION,
|
||||
ODBCConnOptions::ColumnEncryption,
|
||||
sizeof(ODBCConnOptions::ColumnEncryption),
|
||||
CONN_ATTR_STRING,
|
||||
column_encryption_set_func::func
|
||||
},
|
||||
{
|
||||
SSConnOptionNames::Driver,
|
||||
sizeof(SSConnOptionNames::Driver),
|
||||
|
@ -325,34 +312,16 @@ const connection_option SS_CONN_OPTS[] = {
|
|||
CONN_ATTR_STRING,
|
||||
driver_set_func::func
|
||||
},
|
||||
{
|
||||
SSConnOptionNames::CEKeystoreProvider,
|
||||
sizeof(SSConnOptionNames::CEKeystoreProvider),
|
||||
SQLSRV_CONN_OPTION_CEKEYSTORE_PROVIDER,
|
||||
ODBCConnOptions::CEKeystoreProvider,
|
||||
sizeof(ODBCConnOptions::CEKeystoreProvider),
|
||||
CONN_ATTR_STRING,
|
||||
ce_ksp_provider_set_func::func
|
||||
},
|
||||
{
|
||||
SSConnOptionNames::CEKeystoreName,
|
||||
sizeof(SSConnOptionNames::CEKeystoreName),
|
||||
SQLSRV_CONN_OPTION_CEKEYSTORE_NAME,
|
||||
ODBCConnOptions::CEKeystoreName,
|
||||
sizeof(ODBCConnOptions::CEKeystoreName),
|
||||
CONN_ATTR_STRING,
|
||||
ce_ksp_provider_set_func::func
|
||||
},
|
||||
{
|
||||
SSConnOptionNames::CEKeystoreEncryptKey,
|
||||
sizeof(SSConnOptionNames::CEKeystoreEncryptKey),
|
||||
SQLSRV_CONN_OPTION_CEKEYSTORE_ENCRYPT_KEY,
|
||||
ODBCConnOptions::CEKeystoreEncryptKey,
|
||||
sizeof(ODBCConnOptions::CEKeystoreEncryptKey),
|
||||
CONN_ATTR_STRING,
|
||||
ce_ksp_provider_set_func::func
|
||||
},
|
||||
#ifdef _WIN32
|
||||
{
|
||||
SSConnOptionNames::ColumnEncryption,
|
||||
sizeof(SSConnOptionNames::ColumnEncryption),
|
||||
SQLSRV_CONN_OPTION_COLUMNENCRYPTION,
|
||||
ODBCConnOptions::ColumnEncryption,
|
||||
sizeof(ODBCConnOptions::ColumnEncryption),
|
||||
CONN_ATTR_STRING,
|
||||
column_encryption_set_func::func
|
||||
},
|
||||
{
|
||||
SSConnOptionNames::ConnectRetryCount,
|
||||
sizeof( SSConnOptionNames::ConnectRetryCount ),
|
||||
|
|
|
@ -379,22 +379,6 @@ ss_error SS_ERRORS[] = {
|
|||
{
|
||||
SS_SQLSRV_WARNING_FIELD_NAME_EMPTY,
|
||||
{ SSPWARN, (SQLCHAR*)"An empty field name was skipped by sqlsrv_fetch_object.", -100, false }
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_NAME_MISSING,
|
||||
{ IMSSP, (SQLCHAR*) "The name of the custom keystore provider is missing.", -101, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_PATH_MISSING,
|
||||
{ IMSSP, (SQLCHAR*) "The path to the custom keystore provider is missing.", -102, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_KEY_MISSING,
|
||||
{ IMSSP, (SQLCHAR*) "The encryption key for the custom keystore provider is missing.", -103, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_KEYSTORE_INVALID_VALUE,
|
||||
{ IMSSP, (SQLCHAR*) "Invalid value for loading a custom keystore provider.", -104, false}
|
||||
},
|
||||
{
|
||||
SQLSRV_ERROR_CE_DRIVER_REQUIRED,
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
function getKSPpath()
|
||||
{
|
||||
$name = 'myKSP';
|
||||
|
||||
$dir_name = realpath(dirname(__FILE__));
|
||||
$ksp = $dir_name . DIRECTORY_SEPARATOR . $name;
|
||||
if ( strtoupper( substr( php_uname( 's' ), 0, 3 ) ) == 'WIN' ) {
|
||||
$arch = 'x64';
|
||||
if ( PHP_INT_SIZE == 4 ) // running 32 bit
|
||||
$arch = '';
|
||||
$ksp .= $arch . '.dll';
|
||||
}
|
||||
else
|
||||
$ksp .= '.so';
|
||||
|
||||
return $ksp;
|
||||
}
|
||||
|
||||
$ksp_name = 'MyCustomKSPName';
|
||||
$encrypt_key = 'LPKCWVD07N3RG98J0MBLG4H2';
|
||||
$ksp_test_table = 'CustomKSPTestTable';
|
||||
|
||||
?>
|
|
@ -1,160 +1,138 @@
|
|||
--TEST--
|
||||
Test new connection keyword Driver with valid and invalid values
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once('MsSetup.inc');
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server", $uid, $pwd);
|
||||
$msodbcsqlVer = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)['DriverVer'];
|
||||
$msodbcsqlMaj = explode(".", $msodbcsqlVer)[0];
|
||||
} catch(PDOException $e) {
|
||||
echo "Failed to connect\n";
|
||||
print_r($e->getMessage());
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
$conn = null;
|
||||
|
||||
// start test
|
||||
testValidValues();
|
||||
testInvalidValues();
|
||||
testEncryptedWithODBC();
|
||||
testWrongODBC();
|
||||
echo "Done";
|
||||
// end test
|
||||
|
||||
///////////////////////////
|
||||
function connectVerifyOutput($connectionOptions, $expected = '')
|
||||
{
|
||||
global $server, $uid, $pwd;
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server ; $connectionOptions", $uid, $pwd);
|
||||
} catch(PDOException $e) {
|
||||
if (strpos($e->getMessage(), $expected) === false) {
|
||||
print_r($e->getMessage());
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testValidValues()
|
||||
{
|
||||
global $msodbcsqlMaj;
|
||||
|
||||
$value = "";
|
||||
// The major version number of ODBC 11 can be 11 or 12
|
||||
// Test with {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "{ODBC Driver 17 for SQL Server}";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "{ODBC Driver 13 for SQL Server}";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "{ODBC Driver 11 for SQL Server}";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
$connectionOptions = "Driver = $value";
|
||||
connectVerifyOutput($connectionOptions);
|
||||
|
||||
// Test without {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "ODBC Driver 11 for SQL Server";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
|
||||
$connectionOptions = "Driver = $value";
|
||||
connectVerifyOutput($connectionOptions);
|
||||
}
|
||||
|
||||
function testInvalidValues()
|
||||
{
|
||||
$values = array("{SQL Server Native Client 11.0}",
|
||||
"SQL Server Native Client 11.0",
|
||||
"ODBC Driver 00 for SQL Server",
|
||||
123,
|
||||
false);
|
||||
|
||||
foreach ($values as $value) {
|
||||
$connectionOptions = "Driver = $value";
|
||||
$expected = "Invalid value $value was specified for Driver option.";
|
||||
connectVerifyOutput($connectionOptions, $expected);
|
||||
}
|
||||
}
|
||||
|
||||
function testEncryptedWithODBC()
|
||||
{
|
||||
global $msodbcsqlMaj, $server, $uid, $pwd;
|
||||
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
$connectionOptions = "Driver = $value; ColumnEncryption = Enabled;";
|
||||
$expected = "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.";
|
||||
|
||||
connectVerifyOutput($connectionOptions, $expected);
|
||||
|
||||
// TODO: the following block will change once ODBC 17 is officially released
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
$connectionOptions = "Driver = $value; ColumnEncryption = Enabled;";
|
||||
|
||||
$success = "Successfully connected with column encryption.";
|
||||
$expected = "The specified ODBC Driver is not found.";
|
||||
$message = $success;
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server ; $connectionOptions", $uid, $pwd);
|
||||
} catch(PDOException $e) {
|
||||
$message = $e->getMessage();
|
||||
}
|
||||
|
||||
if ($msodbcsqlMaj == 17) {
|
||||
// this indicates that OCBC 17 is the only available driver
|
||||
if (strcmp($message, $success)) {
|
||||
print_r($message);
|
||||
}
|
||||
} else {
|
||||
// OCBC 17 might or might not exist
|
||||
if (strcmp($message, $success)) {
|
||||
if (strpos($message, $expected) === false) {
|
||||
print_r($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testWrongODBC()
|
||||
{
|
||||
global $msodbcsqlMaj;
|
||||
|
||||
// TODO: this will change once ODBC 17 is officially released
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
if ($msodbcsqlMaj == 17 || $msodbcsqlMaj < 13) {
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
}
|
||||
$connectionOptions = "Driver = $value;";
|
||||
$expected = "The specified ODBC Driver is not found.";
|
||||
|
||||
connectVerifyOutput($connectionOptions, $expected);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--TEST--
|
||||
Test new connection keyword Driver with valid and invalid values
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once('MsSetup.inc');
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server", $uid, $pwd);
|
||||
$msodbcsqlVer = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)['DriverVer'];
|
||||
$msodbcsqlMaj = explode(".", $msodbcsqlVer)[0];
|
||||
} catch(PDOException $e) {
|
||||
echo "Failed to connect\n";
|
||||
print_r($e->getMessage());
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
$conn = null;
|
||||
|
||||
// start test
|
||||
testValidValues();
|
||||
testInvalidValues();
|
||||
testEncryptedWithODBC();
|
||||
testWrongODBC();
|
||||
echo "Done";
|
||||
// end test
|
||||
|
||||
///////////////////////////
|
||||
function connectVerifyOutput($connectionOptions, $expected = '')
|
||||
{
|
||||
global $server, $uid, $pwd;
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server ; $connectionOptions", $uid, $pwd);
|
||||
} catch(PDOException $e) {
|
||||
if (strpos($e->getMessage(), $expected) === false) {
|
||||
print_r($e->getMessage());
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testValidValues()
|
||||
{
|
||||
global $msodbcsqlMaj;
|
||||
|
||||
$value = "";
|
||||
// The major version number of ODBC 11 can be 11 or 12
|
||||
// Test with {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "{ODBC Driver 17 for SQL Server}";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "{ODBC Driver 13 for SQL Server}";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "{ODBC Driver 11 for SQL Server}";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
$connectionOptions = "Driver = $value";
|
||||
connectVerifyOutput($connectionOptions);
|
||||
|
||||
// Test without {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "ODBC Driver 11 for SQL Server";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
|
||||
$connectionOptions = "Driver = $value";
|
||||
connectVerifyOutput($connectionOptions);
|
||||
}
|
||||
|
||||
function testInvalidValues()
|
||||
{
|
||||
$values = array("{SQL Server Native Client 11.0}",
|
||||
"SQL Server Native Client 11.0",
|
||||
"ODBC Driver 00 for SQL Server",
|
||||
123,
|
||||
false);
|
||||
|
||||
foreach ($values as $value) {
|
||||
$connectionOptions = "Driver = $value";
|
||||
$expected = "Invalid value $value was specified for Driver option.";
|
||||
connectVerifyOutput($connectionOptions, $expected);
|
||||
}
|
||||
}
|
||||
|
||||
function testEncryptedWithODBC()
|
||||
{
|
||||
global $msodbcsqlMaj, $server, $uid, $pwd;
|
||||
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
$connectionOptions = "Driver = $value; ColumnEncryption = Enabled;";
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
$expected = "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.";
|
||||
} else {
|
||||
$expected = "An invalid keyword 'ColumnEncryption' was specified in the DSN string.";
|
||||
}
|
||||
|
||||
connectVerifyOutput($connectionOptions, $expected);
|
||||
}
|
||||
|
||||
function testWrongODBC()
|
||||
{
|
||||
global $msodbcsqlMaj;
|
||||
|
||||
// TODO: this will change once ODBC 17 is officially released
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
if ($msodbcsqlMaj == 17 || $msodbcsqlMaj < 13) {
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
}
|
||||
$connectionOptions = "Driver = $value;";
|
||||
$expected = "The specified ODBC Driver is not found.";
|
||||
|
||||
connectVerifyOutput($connectionOptions, $expected);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
|
@ -1,7 +1,7 @@
|
|||
--TEST--
|
||||
Test new connection keyword ColumnEncryption
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
<?php require('skipif_unix.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsSetup.inc");
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
--TEST--
|
||||
Fetch data from a prepopulated test table given a custom keystore provider
|
||||
--SKIPIF--
|
||||
<?php require('skipif_not_ksp.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
try
|
||||
{
|
||||
$conn = connect();
|
||||
echo "Connected successfully with ColumnEncryption enabled and KSP specified.\n";
|
||||
}
|
||||
catch( PDOException $e )
|
||||
{
|
||||
echo "Failed to connect.\n";
|
||||
print_r( $e->getMessage() );
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
$tbname = KSP_TEST_TABLE;
|
||||
$tsql = "SELECT * FROM $tbname";
|
||||
$stmt = $conn->query($tsql);
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM))
|
||||
{
|
||||
echo "c1=" . $row[0] . "\tc2=" . $row[1] . "\tc3=" . $row[2] . "\tc4=" . $row[3] . "\n";
|
||||
}
|
||||
|
||||
unset($stmt);
|
||||
unset($conn);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Connected successfully with ColumnEncryption enabled and KSP specified.
|
||||
c1=1 c2=Sample data 0 for column 2 c3=abc c4=2017-08-10
|
||||
c1=12 c2=Sample data 1 for column 2 c3=bcd c4=2017-08-11
|
||||
c1=23 c2=Sample data 2 for column 2 c3=cde c4=2017-08-12
|
||||
c1=34 c2=Sample data 3 for column 2 c3=def c4=2017-08-13
|
||||
c1=45 c2=Sample data 4 for column 2 c3=efg c4=2017-08-14
|
||||
c1=56 c2=Sample data 5 for column 2 c3=fgh c4=2017-08-15
|
||||
c1=67 c2=Sample data 6 for column 2 c3=ghi c4=2017-08-16
|
||||
c1=78 c2=Sample data 7 for column 2 c3=hij c4=2017-08-17
|
||||
c1=89 c2=Sample data 8 for column 2 c3=ijk c4=2017-08-18
|
||||
c1=100 c2=Sample data 9 for column 2 c3=jkl c4=2017-08-19
|
||||
Done
|
|
@ -1,51 +0,0 @@
|
|||
--TEST--
|
||||
Fetch encrypted data from a prepopulated test table given a custom keystore provider
|
||||
--SKIPIF--
|
||||
<?php require('skipif_not_ksp.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
try
|
||||
{
|
||||
$conn = connect();
|
||||
echo "Connected successfully with ColumnEncryption disabled and KSP specified.\n";
|
||||
}
|
||||
catch( PDOException $e )
|
||||
{
|
||||
echo "Failed to connect.\n";
|
||||
print_r( $e->getMessage() );
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
$tbname = KSP_TEST_TABLE;
|
||||
$tsql = "SELECT * FROM $tbname";
|
||||
$stmt = $conn->query($tsql);
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM))
|
||||
{
|
||||
echo "c1=" . $row[0];
|
||||
echo "\tc2=" . bin2hex($row[1]);
|
||||
echo "\tc3=" . bin2hex($row[2]);
|
||||
echo "\tc4=" . bin2hex($row[3]);
|
||||
echo "\n" ;
|
||||
}
|
||||
|
||||
unset($stmt);
|
||||
unset($conn);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
Connected successfully with ColumnEncryption disabled and KSP specified.
|
||||
c1=1 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=12 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=23 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=34 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=45 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=56 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=67 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=78 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=89 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=100 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
Done
|
|
@ -1,102 +0,0 @@
|
|||
--TEST--
|
||||
Connect using a custom keystore provider with some required inputs missing
|
||||
--SKIPIF--
|
||||
<?php require('skipif_not_ksp.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require("MsSetup.inc");
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
function kspConnect( $connectionInfo )
|
||||
{
|
||||
global $server, $uid, $pwd;
|
||||
|
||||
try
|
||||
{
|
||||
$conn = new PDO( "sqlsrv:server = $server ; $connectionInfo", $uid, $pwd );
|
||||
echo "Connected successfully with ColumnEncryption enabled and KSP specified.\n";
|
||||
}
|
||||
catch( PDOException $e )
|
||||
{
|
||||
echo "Failed to connect.\n";
|
||||
print_r( $e->getMessage() );
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$ksp_path = getKSPpath();
|
||||
$ksp_name = KSP_NAME;
|
||||
$encrypt_key = ENCRYPT_KEY;
|
||||
|
||||
echo("Connecting... with column encryption\n");
|
||||
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; ";
|
||||
kspConnect( $connectionInfo );
|
||||
|
||||
echo("\nConnecting... with an invalid input to CEKeystoreProvider\n");
|
||||
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; ";
|
||||
$connectionInfo .= "CEKeystoreName = 1; ";
|
||||
$connectionInfo .= "CEKeystoreProvider = $ksp_path; ";
|
||||
$connectionInfo .= "CEKeystoreEncryptKey = $encrypt_key; ";
|
||||
kspConnect( $connectionInfo );
|
||||
|
||||
echo("\nConnecting... with an empty path\n");
|
||||
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; ";
|
||||
$connectionInfo .= "CEKeystoreName = $ksp_name; ";
|
||||
$connectionInfo .= "CEKeystoreProvider = ; ";
|
||||
$connectionInfo .= "CEKeystoreEncryptKey = $encrypt_key; ";
|
||||
kspConnect( $connectionInfo );
|
||||
|
||||
echo("\nConnecting... without a path\n");
|
||||
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; ";
|
||||
$connectionInfo .= "CEKeystoreName = $ksp_name; ";
|
||||
$connectionInfo .= "CEKeystoreEncryptKey = $encrypt_key;";
|
||||
kspConnect( $connectionInfo );
|
||||
|
||||
echo("\nConnecting... without a name\n");
|
||||
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; ";
|
||||
$connectionInfo .= "CEKeystoreProvider = $ksp_path; ";
|
||||
$connectionInfo .= "CEKeystoreEncryptKey = $encrypt_key; ";
|
||||
kspConnect( $connectionInfo );
|
||||
|
||||
echo("\nConnecting... without a key\n");
|
||||
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; ";
|
||||
$connectionInfo .= "CEKeystoreProvider = $ksp_path; ";
|
||||
$connectionInfo .= "CEKeystoreName = $ksp_name; ";
|
||||
kspConnect( $connectionInfo );
|
||||
|
||||
echo("\nConnecting... with all required inputs\n");
|
||||
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; ";
|
||||
$connectionInfo .= "CEKeystoreProvider = $ksp_path; ";
|
||||
$connectionInfo .= "CEKeystoreName = $ksp_name; ";
|
||||
$connectionInfo .= "CEKeystoreEncryptKey = $encrypt_key; ";
|
||||
kspConnect( $connectionInfo );
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
Connecting\.\.\. with column encryption
|
||||
Connected successfully with ColumnEncryption enabled and KSP specified\.
|
||||
|
||||
Connecting\.\.\. with an invalid input to CEKeystoreProvider
|
||||
Failed to connect.
|
||||
SQLSTATE\[HY024\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid attribute value
|
||||
|
||||
Connecting\.\.\. with an empty path
|
||||
Failed to connect.
|
||||
SQLSTATE\[IMSSP\]: Invalid value for loading a custom keystore provider\.
|
||||
|
||||
Connecting\.\.\. without a path
|
||||
Failed to connect.
|
||||
SQLSTATE\[IMSSP\]: The path to the custom keystore provider is missing\.
|
||||
|
||||
Connecting\.\.\. without a name
|
||||
Failed to connect.
|
||||
SQLSTATE\[IMSSP\]: The name of the custom keystore provider is missing\.
|
||||
|
||||
Connecting\.\.\. without a key
|
||||
Failed to connect.
|
||||
SQLSTATE\[IMSSP\]: The encryption key for the custom keystore provider is missing\.
|
||||
|
||||
Connecting\.\.\. with all required inputs
|
||||
Connected successfully with ColumnEncryption enabled and KSP specified\.
|
||||
Done
|
|
@ -1,16 +1,21 @@
|
|||
<?php
|
||||
if (!extension_loaded("pdo") || !extension_loaded('pdo_sqlsrv')) {
|
||||
die("PDO driver cannot be loaded; skipping test.\n");
|
||||
}
|
||||
|
||||
require_once("MsSetup.inc");
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
|
||||
$dsn = getDSN($server, null);
|
||||
$conn = new PDO($dsn, $uid, $pwd);
|
||||
if (! $conn) {
|
||||
echo("Error: could not connect during SKIPIF!");
|
||||
} elseif (isColEncrypted() && !isAEQualified($conn)) {
|
||||
die("skip - AE feature not supported in the current environment.");
|
||||
}
|
||||
<?php
|
||||
if (!extension_loaded("pdo") || !extension_loaded('pdo_sqlsrv')) {
|
||||
die("PDO driver cannot be loaded; skipping test.\n");
|
||||
}
|
||||
|
||||
require_once("MsSetup.inc");
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
$dsn = getDSN($server, null);
|
||||
$conn = new PDO($dsn, $uid, $pwd);
|
||||
if (! $conn) {
|
||||
echo("Error: could not connect during SKIPIF!");
|
||||
} elseif (isColEncrypted()) {
|
||||
if (!(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')) {
|
||||
die( "Skip, AE test on windows only." );
|
||||
}
|
||||
|
||||
if (!isAEQualified($conn)) {
|
||||
die("skip - AE feature not supported in the current environment.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
if (! extension_loaded( 'pdo' ) || ! extension_loaded( 'pdo_sqlsrv' ))
|
||||
die( "PDO driver cannot be loaded; skipping test.\n" );
|
||||
|
||||
require_once( "MsSetup.inc" );
|
||||
|
||||
if ($keystore != 'ksp')
|
||||
die ( 'skip - this test requires a custom keystore provider.' );
|
||||
|
||||
require_once( "MsCommon.inc" );
|
||||
|
||||
$conn = new PDO( "sqlsrv:server = $server;", $uid, $pwd );
|
||||
if( ! $conn )
|
||||
{
|
||||
echo( "Error: could not connect during SKIPIF!" );
|
||||
}
|
||||
else if(! IsAEQualified($conn))
|
||||
{
|
||||
die( "skip - AE feature not supported in the current environment." );
|
||||
}
|
||||
?>
|
|
@ -22,10 +22,6 @@ const INSERT_PREPARE = 2;
|
|||
const INSERT_QUERY_PARAMS = 3;
|
||||
const INSERT_PREPARE_PARAMS = 4;
|
||||
|
||||
const KSP_NAME = 'MyCustomKSPName';
|
||||
const ENCRYPT_KEY = 'LPKCWVD07N3RG98J0MBLG4H2';
|
||||
const KSP_TEST_TABLE = 'CustomKSPTestTable';
|
||||
|
||||
/**
|
||||
* class for encapsulating column metadata needed for creating a table
|
||||
*/
|
||||
|
@ -214,29 +210,6 @@ function getCekName()
|
|||
return $cekName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the path to the KSP dll/so file
|
||||
*/
|
||||
function getKSPpath()
|
||||
{
|
||||
$name = 'myKSP';
|
||||
|
||||
$dir_name = realpath(dirname(__FILE__));
|
||||
$ksp = $dir_name . DIRECTORY_SEPARATOR . $name;
|
||||
if (strtoupper(substr(php_uname('s'), 0, 3)) == 'WIN') {
|
||||
$arch = 'x64';
|
||||
if (PHP_INT_SIZE == 4) {
|
||||
// running 32 bit
|
||||
$arch = '';
|
||||
}
|
||||
$ksp .= $arch . '.dll';
|
||||
} else {
|
||||
$ksp .= '.so';
|
||||
}
|
||||
|
||||
return $ksp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string default column name when a name is not provided in the ColumnMeta class
|
||||
*/
|
||||
|
@ -383,13 +356,6 @@ function connect($options = array(), $disableCE = false)
|
|||
if (isColEncrypted()) {
|
||||
$connectionOptions = array_merge($connectionOptions, array("ColumnEncryption" => "Enabled"));
|
||||
}
|
||||
if ($keystore == "ksp") {
|
||||
$ksp_path = getKSPPath();
|
||||
$ksp_options = array("CEKeystoreProvider"=>$ksp_path,
|
||||
"CEKeystoreName"=>KSP_NAME,
|
||||
"CEKeystoreEncryptKey"=>ENCRYPT_KEY);
|
||||
$connectionOptions = array_merge($connectionOptions, $ksp_options);
|
||||
}
|
||||
}
|
||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||
if ($conn === false) {
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
if (!extension_loaded("sqlsrv"))
|
||||
die("skip extension not loaded");
|
||||
|
||||
require_once('MsCommon.inc');
|
||||
|
||||
if ($keystore != AE\KEYSTORE_KSP) {
|
||||
die('skip - this test requires a custom keystore provider.');
|
||||
}
|
||||
|
||||
$conn = AE\connect();
|
||||
if (! $conn) {
|
||||
echo("Error: could not connect during SKIPIF!");
|
||||
} elseif (AE\isColEncrypted() && !AE\isQualified($conn)) {
|
||||
die("skip - AE feature not supported in the current environment.");
|
||||
}
|
||||
?>
|
|
@ -1,15 +1,21 @@
|
|||
<?php
|
||||
|
||||
if (! extension_loaded("sqlsrv")) {
|
||||
die("skip extension not loaded");
|
||||
}
|
||||
|
||||
require_once('MsCommon.inc');
|
||||
|
||||
$conn = AE\connect();
|
||||
if (! $conn) {
|
||||
echo("Error: could not connect during SKIPIF!");
|
||||
} elseif (AE\isColEncrypted() && !AE\isQualified($conn)) {
|
||||
die("skip - AE feature not supported in the current environment.");
|
||||
}
|
||||
<?php
|
||||
|
||||
if (! extension_loaded("sqlsrv")) {
|
||||
die("skip extension not loaded");
|
||||
}
|
||||
|
||||
require_once('MsCommon.inc');
|
||||
|
||||
$conn = AE\connect();
|
||||
if (! $conn) {
|
||||
echo("Error: could not connect during SKIPIF!");
|
||||
} elseif (AE\isColEncrypted()) {
|
||||
if (!isWindows()) {
|
||||
die( "Skip, AE test on windows only." );
|
||||
}
|
||||
|
||||
if (!AE\isQualified($conn)) {
|
||||
die("skip - AE feature not supported in the current environment.");
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -1,158 +1,134 @@
|
|||
--TEST--
|
||||
Test new connection keyword Driver with valid and invalid values
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
sqlsrv_configure('WarningsReturnAsErrors', 0);
|
||||
require_once('MsSetup.inc');
|
||||
|
||||
$connectionOptions = array("Database"=>$database, "UID"=>$userName, "PWD"=>$userPassword);
|
||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||
if ($conn === false) {
|
||||
print_r(sqlsrv_errors());
|
||||
}
|
||||
$msodbcsqlVer = sqlsrv_client_info($conn)['DriverVer'];
|
||||
$msodbcsqlMaj = explode(".", $msodbcsqlVer)[0];
|
||||
sqlsrv_close($conn);
|
||||
|
||||
// start test
|
||||
testValidValues($msodbcsqlMaj, $server, $connectionOptions);
|
||||
testInvalidValues($msodbcsqlMaj, $server, $connectionOptions);
|
||||
testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions);
|
||||
testWrongODBC($msodbcsqlMaj, $server, $connectionOptions);
|
||||
echo "Done";
|
||||
// end test
|
||||
|
||||
///////////////////////////
|
||||
function connectVerifyOutput($server, $connectionOptions, $expected = '')
|
||||
{
|
||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||
if ($conn === false) {
|
||||
if (strpos(sqlsrv_errors($conn)[0]['message'], $expected) === false) {
|
||||
print_r(sqlsrv_errors());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testValidValues($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
$value = "";
|
||||
// The major version number of ODBC 11 can be 11 or 12
|
||||
// Test with {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "{ODBC Driver 17 for SQL Server}";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "{ODBC Driver 13 for SQL Server}";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "{ODBC Driver 11 for SQL Server}";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
$connectionOptions['Driver']=$value;
|
||||
connectVerifyOutput($server, $connectionOptions);
|
||||
|
||||
// Test without {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "ODBC Driver 11 for SQL Server";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
|
||||
$connectionOptions['Driver']=$value;
|
||||
connectVerifyOutput($server, $connectionOptions);
|
||||
}
|
||||
|
||||
function testInvalidValues($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
$values = array("{SQL Server Native Client 11.0}",
|
||||
"SQL Server Native Client 11.0",
|
||||
"ODBC Driver 00 for SQL Server");
|
||||
|
||||
foreach ($values as $value) {
|
||||
$connectionOptions['Driver']=$value;
|
||||
$expected = "Invalid value $value was specified for Driver option.";
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
}
|
||||
|
||||
$values = array(123, false);
|
||||
|
||||
foreach ($values as $value) {
|
||||
$connectionOptions['Driver']=$value;
|
||||
$expected = "Invalid value type for option Driver was specified. String type was expected.";
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
}
|
||||
}
|
||||
|
||||
function testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
$connectionOptions['Driver']=$value;
|
||||
$connectionOptions['ColumnEncryption']='Enabled';
|
||||
|
||||
$expected = "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.";
|
||||
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
|
||||
// TODO: the following block will change once ODBC 17 is officially released
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
$connectionOptions['Driver']=$value;
|
||||
$connectionOptions['ColumnEncryption']='Enabled';
|
||||
|
||||
$success = "Successfully connected with column encryption.";
|
||||
$expected = "The specified ODBC Driver is not found.";
|
||||
$message = $success;
|
||||
|
||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||
if ($conn === false) {
|
||||
$message = sqlsrv_errors($conn)[0]['message'];
|
||||
}
|
||||
|
||||
if ($msodbcsqlMaj == 17) {
|
||||
// this indicates that OCBC 17 is the only available driver
|
||||
if (strcmp($message, $success)) {
|
||||
print_r($message);
|
||||
}
|
||||
} else {
|
||||
// OCBC 17 might or might not exist
|
||||
if (strcmp($message, $success)) {
|
||||
if (strpos($message, $expected) === false) {
|
||||
print_r($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testWrongODBC($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
// TODO: this will change once ODBC 17 is officially released
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
if ($msodbcsqlMaj == 17 || $msodbcsqlMaj < 13) {
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
}
|
||||
|
||||
$connectionOptions['Driver']=$value;
|
||||
$expected = "The specified ODBC Driver is not found.";
|
||||
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
||||
--TEST--
|
||||
Test new connection keyword Driver with valid and invalid values
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
sqlsrv_configure('WarningsReturnAsErrors', 0);
|
||||
require_once('MsSetup.inc');
|
||||
|
||||
$connectionOptions = array("Database"=>$database, "UID"=>$userName, "PWD"=>$userPassword);
|
||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||
if ($conn === false) {
|
||||
print_r(sqlsrv_errors());
|
||||
}
|
||||
$msodbcsqlVer = sqlsrv_client_info($conn)['DriverVer'];
|
||||
$msodbcsqlMaj = explode(".", $msodbcsqlVer)[0];
|
||||
sqlsrv_close($conn);
|
||||
|
||||
// start test
|
||||
testValidValues($msodbcsqlMaj, $server, $connectionOptions);
|
||||
testInvalidValues($msodbcsqlMaj, $server, $connectionOptions);
|
||||
testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions);
|
||||
testWrongODBC($msodbcsqlMaj, $server, $connectionOptions);
|
||||
echo "Done";
|
||||
// end test
|
||||
|
||||
///////////////////////////
|
||||
function connectVerifyOutput($server, $connectionOptions, $expected = '')
|
||||
{
|
||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||
if ($conn === false) {
|
||||
if (strpos(sqlsrv_errors($conn)[0]['message'], $expected) === false) {
|
||||
print_r(sqlsrv_errors());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testValidValues($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
$value = "";
|
||||
// The major version number of ODBC 11 can be 11 or 12
|
||||
// Test with {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "{ODBC Driver 17 for SQL Server}";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "{ODBC Driver 13 for SQL Server}";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "{ODBC Driver 11 for SQL Server}";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
$connectionOptions['Driver']=$value;
|
||||
connectVerifyOutput($server, $connectionOptions);
|
||||
|
||||
// Test without {}
|
||||
switch ($msodbcsqlMaj) {
|
||||
case 17:
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
break;
|
||||
case 14:
|
||||
case 13:
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
break;
|
||||
case 12:
|
||||
case 11:
|
||||
$value = "ODBC Driver 11 for SQL Server";
|
||||
break;
|
||||
default:
|
||||
$value = "invalid value $msodbcsqlMaj";
|
||||
}
|
||||
|
||||
$connectionOptions['Driver']=$value;
|
||||
connectVerifyOutput($server, $connectionOptions);
|
||||
}
|
||||
|
||||
function testInvalidValues($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
$values = array("{SQL Server Native Client 11.0}",
|
||||
"SQL Server Native Client 11.0",
|
||||
"ODBC Driver 00 for SQL Server");
|
||||
|
||||
foreach ($values as $value) {
|
||||
$connectionOptions['Driver']=$value;
|
||||
$expected = "Invalid value $value was specified for Driver option.";
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
}
|
||||
|
||||
$values = array(123, false);
|
||||
|
||||
foreach ($values as $value) {
|
||||
$connectionOptions['Driver']=$value;
|
||||
$expected = "Invalid value type for option Driver was specified. String type was expected.";
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
}
|
||||
}
|
||||
|
||||
function testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
$connectionOptions['Driver']=$value;
|
||||
$connectionOptions['ColumnEncryption']='Enabled';
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
$expected = "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.";
|
||||
} else {
|
||||
$expected = "Invalid option ColumnEncryption was passed to sqlsrv_connect.";
|
||||
}
|
||||
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
}
|
||||
|
||||
function testWrongODBC($msodbcsqlMaj, $server, $connectionOptions)
|
||||
{
|
||||
// TODO: this will change once ODBC 17 is officially released
|
||||
$value = "ODBC Driver 17 for SQL Server";
|
||||
if ($msodbcsqlMaj == 17 || $msodbcsqlMaj < 13) {
|
||||
$value = "ODBC Driver 13 for SQL Server";
|
||||
}
|
||||
|
||||
$connectionOptions['Driver']=$value;
|
||||
$expected = "The specified ODBC Driver is not found.";
|
||||
|
||||
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
--TEST--
|
||||
Test new connection keyword ColumnEncryption
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
<?php require('skipif_unix.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
sqlsrv_configure( 'WarningsReturnAsErrors', 0 );
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
--TEST--
|
||||
Fetch data from a prepopulated test table given a custom keystore provider
|
||||
--SKIPIF--
|
||||
<?php require('skipif_not_ksp.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
function verifyData($row, $num)
|
||||
{
|
||||
$c1 = $num * 10 + $num + 1;
|
||||
if (AE\isColEncrypted()) {
|
||||
$c2 = "Sample data $num for column 2";
|
||||
|
||||
$c3 = '';
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
// add to letter 'a'
|
||||
$c3 .= chr(97 + $num + $i);
|
||||
}
|
||||
$c4 = "2017-08-" . ($num + 10);
|
||||
|
||||
// need to trim the third value because it is a char(5)
|
||||
if ($row[0] !== $c1 || $row[1] !== $c2 || trim($row[2]) !== $c3 || $row[3] !== $c4) {
|
||||
echo "Expected the following\n";
|
||||
echo "c1=$c1\nc2=$c2\nc3=$c3\nc4=$c4\n";
|
||||
echo "But got these instead\n";
|
||||
echo "c1=" . $row[0] . "\nc2=" . $row[1] . "\nc3=" . $row[2] . "\nc4=" . $row[3] . "\n" ;
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($row[0] !== $c1) {
|
||||
echo "Expected $c1 but got $row[0]\n";
|
||||
}
|
||||
// should expect binary values for the other columns
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
if (ctype_print($row[1])) {
|
||||
print "Error: expected a binary array for column $i!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sqlsrv_configure('WarningsReturnAsErrors', 1);
|
||||
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
|
||||
|
||||
require_once('MsCommon.inc');
|
||||
$conn = AE\connect(array('ReturnDatesAsStrings'=>true));
|
||||
if ($conn !== false) {
|
||||
echo "Connected successfully with ColumnEncryption enabled.\n";
|
||||
}
|
||||
|
||||
$ksp_test_table = AE\KSP_TEST_TABLE;
|
||||
$tsql = "SELECT * FROM $ksp_test_table";
|
||||
$stmt = sqlsrv_prepare($conn, $tsql);
|
||||
if (!sqlsrv_execute($stmt)) {
|
||||
fatalError("Failed to fetch data.\n");
|
||||
}
|
||||
|
||||
// fetch data
|
||||
$id = 0;
|
||||
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_NUMERIC)) {
|
||||
if (!verifyData($row, $id++)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sqlsrv_free_stmt($stmt);
|
||||
sqlsrv_close($conn);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
Connected successfully with ColumnEncryption enabled.
|
||||
Done
|
|
@ -1,52 +0,0 @@
|
|||
--TEST--
|
||||
Fetch encrypted data from a prepopulated test table given a custom keystore provider
|
||||
--SKIPIF--
|
||||
<?php require('skipif_not_ksp.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
sqlsrv_configure('WarningsReturnAsErrors', 1);
|
||||
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
|
||||
|
||||
require_once('MsCommon.inc');
|
||||
$conn = AE\connect(array('ReturnDatesAsStrings'=>true));
|
||||
if ($conn === false) {
|
||||
fatalError("Failed to connect.\n");
|
||||
} else {
|
||||
echo "Connected successfully with ColumnEncryption disabled.\n";
|
||||
}
|
||||
|
||||
$ksp_test_table = AE\KSP_TEST_TABLE;
|
||||
$tsql = "SELECT * FROM $ksp_test_table";
|
||||
$stmt = sqlsrv_prepare($conn, $tsql);
|
||||
if (!sqlsrv_execute($stmt)) {
|
||||
fatalError("Failed to fetch data.\n");
|
||||
}
|
||||
|
||||
// fetch data
|
||||
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_NUMERIC)) {
|
||||
// all columns should return binary data except the first column
|
||||
echo "c1=" . $row[0];
|
||||
echo "\tc2=" . bin2hex($row[1]);
|
||||
echo "\tc3=" . bin2hex($row[2]);
|
||||
echo "\tc4=" . bin2hex($row[3]);
|
||||
echo "\n" ;
|
||||
}
|
||||
|
||||
sqlsrv_free_stmt($stmt);
|
||||
sqlsrv_close($conn);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
Connected successfully with ColumnEncryption disabled.
|
||||
c1=1 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=12 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=23 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=34 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=45 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=56 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=67 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=78 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=89 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
c1=100 c2=[a-f0-9]+ c3=[a-f0-9]+ c4=[a-f0-9]+
|
||||
Done
|
|
@ -1,127 +0,0 @@
|
|||
--TEST--
|
||||
Connect using a custom keystore provider with some required inputs missing
|
||||
--SKIPIF--
|
||||
<?php require('skipif_not_ksp.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function connect($server, $connectionInfo)
|
||||
{
|
||||
$conn = sqlsrv_connect($server, $connectionInfo);
|
||||
if ($conn === false) {
|
||||
echo "Failed to connect.\n";
|
||||
$errors = sqlsrv_errors();
|
||||
foreach ($errors[0] as $key => $error) {
|
||||
if(is_string($key)) {
|
||||
echo "[$key] => $error\n";
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
} else {
|
||||
echo "Connected successfully with ColumnEncryption enabled.\n";
|
||||
}
|
||||
|
||||
return $conn;
|
||||
}
|
||||
|
||||
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
|
||||
|
||||
require_once('MsHelper.inc');
|
||||
$ksp_path = AE\getKSPpath();
|
||||
$ksp_name = AE\KSP_NAME;
|
||||
$encrypt_key = AE\ENCRYPT_KEY;
|
||||
|
||||
echo "Connecting... with column encryption\n";
|
||||
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
|
||||
"ColumnEncryption"=>"enabled");
|
||||
|
||||
connect($server, $connectionInfo);
|
||||
|
||||
echo "Connecting... with an invalid input to CEKeystoreProvider\n";
|
||||
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
|
||||
"ColumnEncryption"=>"enabled",
|
||||
"CEKeystoreProvider"=>1);
|
||||
|
||||
connect($server, $connectionInfo);
|
||||
|
||||
echo "Connecting... with an empty path\n";
|
||||
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
|
||||
"ColumnEncryption"=>"enabled",
|
||||
"CEKeystoreProvider"=>"",
|
||||
"CEKeystoreName"=>$ksp_name,
|
||||
"CEKeystoreEncryptKey"=>$encrypt_key);
|
||||
|
||||
connect($server, $connectionInfo);
|
||||
|
||||
echo "Connecting... without a name\n";
|
||||
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
|
||||
"ColumnEncryption"=>"enabled",
|
||||
"CEKeystoreProvider"=>$ksp_path,
|
||||
"CEKeystoreEncryptKey"=>$encrypt_key);
|
||||
|
||||
connect($server, $connectionInfo);
|
||||
|
||||
echo "Connecting... with an empty name\n";
|
||||
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
|
||||
"ColumnEncryption"=>"enabled",
|
||||
"CEKeystoreProvider"=>$ksp_path,
|
||||
"CEKeystoreName"=>"",
|
||||
"CEKeystoreEncryptKey"=>$encrypt_key);
|
||||
|
||||
connect($server, $connectionInfo);
|
||||
|
||||
echo "Connecting... without a key\n";
|
||||
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
|
||||
"ColumnEncryption"=>"enabled",
|
||||
"CEKeystoreProvider"=>$ksp_path,
|
||||
"CEKeystoreName"=>$ksp_name);
|
||||
|
||||
connect($server, $connectionInfo);
|
||||
|
||||
echo "Connecting... with all required inputs\n";
|
||||
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd,
|
||||
"ColumnEncryption"=>"enabled",
|
||||
"CEKeystoreProvider"=>$ksp_path,
|
||||
"CEKeystoreName"=>$ksp_name,
|
||||
"CEKeystoreEncryptKey"=>$encrypt_key);
|
||||
|
||||
connect($server, $connectionInfo);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
Connecting... with column encryption
|
||||
Connected successfully with ColumnEncryption enabled.
|
||||
Connecting... with an invalid input to CEKeystoreProvider
|
||||
Failed to connect.
|
||||
[SQLSTATE] => IMSSP
|
||||
[code] => -33
|
||||
[message] => Invalid value type for option CEKeystoreProvider was specified. String type was expected.
|
||||
|
||||
Connecting... with an empty path
|
||||
Failed to connect.
|
||||
[SQLSTATE] => IMSSP
|
||||
[code] => -104
|
||||
[message] => Invalid value for loading a custom keystore provider.
|
||||
|
||||
Connecting... without a name
|
||||
Failed to connect.
|
||||
[SQLSTATE] => IMSSP
|
||||
[code] => -101
|
||||
[message] => The name of the custom keystore provider is missing.
|
||||
|
||||
Connecting... with an empty name
|
||||
Failed to connect.
|
||||
[SQLSTATE] => IMSSP
|
||||
[code] => -104
|
||||
[message] => Invalid value for loading a custom keystore provider.
|
||||
|
||||
Connecting... without a key
|
||||
Failed to connect.
|
||||
[SQLSTATE] => IMSSP
|
||||
[code] => -103
|
||||
[message] => The encryption key for the custom keystore provider is missing.
|
||||
|
||||
Connecting... with all required inputs
|
||||
Connected successfully with ColumnEncryption enabled.
|
||||
Done
|
|
@ -1,213 +0,0 @@
|
|||
--TEST--
|
||||
Test simple insert, fetch and update with ColumnEncryption enabled and a custome keystore provider
|
||||
--SKIPIF--
|
||||
<?php require('skipif_not_ksp.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
function createPatientsTable()
|
||||
{
|
||||
global $conn;
|
||||
$tableName = 'Patients';
|
||||
|
||||
$columns = array(new AE\ColumnMeta('int', 'PatientId', 'IDENTITY(1,1) NOT NULL'),
|
||||
new AE\ColumnMeta('char(11)', 'SSN'),
|
||||
new AE\ColumnMeta('nvarchar(50)', 'FirstName'),
|
||||
new AE\ColumnMeta('nvarchar(50)', 'LastName'),
|
||||
new AE\ColumnMeta('date', 'BirthDate'));
|
||||
$stmt = AE\createTable($conn, $tableName, $columns);
|
||||
if (!$stmt) {
|
||||
fatalError("Failed to create test table!\n");
|
||||
}
|
||||
|
||||
return $tableName;
|
||||
}
|
||||
|
||||
function insertData($ssn, $fname, $lname, $date)
|
||||
{
|
||||
global $conn, $tableName;
|
||||
$params = array(
|
||||
array($ssn, null, null, SQLSRV_SQLTYPE_CHAR(11)), array($fname, null, null, SQLSRV_SQLTYPE_NVARCHAR(50)), array($lname, null, null, SQLSRV_SQLTYPE_NVARCHAR(50)), array($date, null, null, SQLSRV_SQLTYPE_DATE)
|
||||
);
|
||||
|
||||
$tsql = "INSERT INTO $tableName (SSN, FirstName, LastName, BirthDate) VALUES (?, ?, ?, ?)";
|
||||
if (! $stmt = sqlsrv_prepare($conn, $tsql, $params)) {
|
||||
fatalError("Failed to prepare statement.\n");
|
||||
}
|
||||
|
||||
if (! sqlsrv_execute($stmt)) {
|
||||
fatalError("Failed to insert a new record.\n");
|
||||
}
|
||||
}
|
||||
|
||||
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 selectDataBuffered()
|
||||
{
|
||||
global $conn, $tableName;
|
||||
|
||||
$stmt = sqlsrv_query($conn, "SELECT * FROM $tableName", array(), array("Scrollable"=>"buffered"));
|
||||
|
||||
$row_count = sqlsrv_num_rows($stmt);
|
||||
echo "\nRow count for result set is $row_count\n";
|
||||
|
||||
echo "First record=>\t";
|
||||
$row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);
|
||||
$SSN = sqlsrv_get_field($stmt, 1);
|
||||
echo "SSN = $SSN\n";
|
||||
|
||||
echo "Next record=>\t";
|
||||
$row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_NEXT);
|
||||
$BirthDate = sqlsrv_get_field($stmt, 4);
|
||||
echo "BirthDate = $BirthDate\n";
|
||||
|
||||
echo "Last record=>\t";
|
||||
$row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_LAST);
|
||||
$LastName = sqlsrv_get_field($stmt, 3);
|
||||
echo "LastName = $LastName\n";
|
||||
}
|
||||
|
||||
sqlsrv_configure('WarningsReturnAsErrors', 1);
|
||||
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
|
||||
|
||||
require_once('MsHelper.inc');
|
||||
$conn = AE\connect(array('ReturnDatesAsStrings'=>true));
|
||||
if ($conn === false) {
|
||||
fatalError( "Failed to connect.\n");
|
||||
} else {
|
||||
echo "Connected successfully with ColumnEncryption enabled.\n";
|
||||
}
|
||||
|
||||
$tableName = createPatientsTable();
|
||||
|
||||
insertData('748-68-0245', 'Jeannette', 'McDonald', '2002-11-28');
|
||||
insertData('795-73-9838', 'John', 'Doe', '2001-05-29');
|
||||
insertData('456-12-5486', 'Jonathan', 'Wong', '1999-12-20');
|
||||
insertData('156-45-5486', 'Marianne', 'Smith', '1997-03-04');
|
||||
|
||||
selectData();
|
||||
|
||||
///////////////////////////////////////////
|
||||
echo "Update Patient Jonathan Wong...\n";
|
||||
$params = array(array('1999-12-31', null, null, SQLSRV_SQLTYPE_DATE),
|
||||
array('Chang', null, null, SQLSRV_SQLTYPE_NVARCHAR(50)),
|
||||
array('456-12-5486', null, null, SQLSRV_SQLTYPE_CHAR(11)));
|
||||
|
||||
$tsql = "UPDATE $tableName SET BirthDate = ?, LastName = ? WHERE SSN = ?";
|
||||
$stmt = sqlsrv_query($conn, $tsql, $params);
|
||||
|
||||
if (!$stmt) {
|
||||
fatalError("Failed to update record\n");
|
||||
}
|
||||
|
||||
echo "Update his birthdate too...\n";
|
||||
$params = array(array('456-12-5486', null, null, SQLSRV_SQLTYPE_CHAR(11)));
|
||||
$tsql = "SELECT SSN, FirstName, LastName, BirthDate FROM $tableName WHERE SSN = ?";
|
||||
$stmt = sqlsrv_query($conn, $tsql, $params);
|
||||
if (!$stmt) {
|
||||
fatalError("Failed to select with a WHERE clause\n");
|
||||
} else {
|
||||
$obj = sqlsrv_fetch_object($stmt);
|
||||
echo "BirthDate updated for $obj->FirstName:\n";
|
||||
echo $obj->SSN . "\n";
|
||||
echo $obj->FirstName . "\n";
|
||||
echo $obj->LastName . "\n";
|
||||
echo $obj->BirthDate . "\n\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
$procName = '#phpAEProc1';
|
||||
$spArgs = "@p1 INT, @p2 DATE OUTPUT";
|
||||
$spCode = "SET @p2 = (SELECT [BirthDate] FROM $tableName WHERE [PatientId] = @p1)";
|
||||
$stmt = sqlsrv_query($conn, "CREATE PROC [$procName] ($spArgs) AS BEGIN $spCode END");
|
||||
sqlsrv_free_stmt($stmt);
|
||||
|
||||
$callResult = '1900-01-01';
|
||||
//when binding parameter using sqlsrv_query in a column encryption enabled connection, need to provide the sql_type in all parameters
|
||||
$params = array(array(1, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_INT),
|
||||
array(&$callResult, SQLSRV_PARAM_OUT, null, SQLSRV_SQLTYPE_DATE));
|
||||
$callArgs = "?, ?";
|
||||
$stmt = sqlsrv_query($conn, "{ CALL [$procName] ($callArgs)}", $params);
|
||||
if (!$stmt) {
|
||||
print_r(sqlsrv_errors());
|
||||
} else {
|
||||
echo "BirthDate for the first record is: $callResult\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
$procName = '#phpAEProc2';
|
||||
$spArgs = "@p1 INT, @p2 CHAR(11) OUTPUT";
|
||||
$spCode = "SET @p2 = (SELECT [SSN] FROM $tableName WHERE [PatientId] = @p1)";
|
||||
$stmt = sqlsrv_query($conn, "CREATE PROC [$procName] ($spArgs) AS BEGIN $spCode END");
|
||||
sqlsrv_free_stmt($stmt);
|
||||
|
||||
$callResult = '000-00-0000';
|
||||
// when binding parameter using sqlsrv_query in a column encryption enabled connection,
|
||||
// need to provide the sql_type in all parameters
|
||||
$params = array(array(1, SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_INT),
|
||||
array(&$callResult, SQLSRV_PARAM_OUT, null, SQLSRV_SQLTYPE_CHAR(11)));
|
||||
$callArgs = "?, ?";
|
||||
$stmt = sqlsrv_query($conn, "{ CALL [$procName] ($callArgs)}", $params);
|
||||
if (!$stmt) {
|
||||
print_r(sqlsrv_errors());
|
||||
} else {
|
||||
echo "SSN for the first record is: $callResult\n";
|
||||
}
|
||||
|
||||
selectDataBuffered();
|
||||
|
||||
echo "\nDone\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
Connected successfully with ColumnEncryption enabled.
|
||||
1
|
||||
748-68-0245
|
||||
Jeannette
|
||||
McDonald
|
||||
2002-11-28
|
||||
|
||||
2
|
||||
795-73-9838
|
||||
John
|
||||
Doe
|
||||
2001-05-29
|
||||
|
||||
3
|
||||
456-12-5486
|
||||
Jonathan
|
||||
Wong
|
||||
1999-12-20
|
||||
|
||||
4
|
||||
156-45-5486
|
||||
Marianne
|
||||
Smith
|
||||
1997-03-04
|
||||
|
||||
Update Patient Jonathan Wong...
|
||||
Update his birthdate too...
|
||||
BirthDate updated for Jonathan:
|
||||
456-12-5486
|
||||
Jonathan
|
||||
Chang
|
||||
1999-12-31
|
||||
|
||||
BirthDate for the first record is: 2002-11-28
|
||||
SSN for the first record is: 748-68-0245
|
||||
|
||||
Row count for result set is 4
|
||||
First record=> SSN = 748-68-0245
|
||||
Next record=> BirthDate = 2001-05-29
|
||||
Last record=> LastName = Smith
|
||||
|
||||
Done
|
Загрузка…
Ссылка в новой задаче