Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #787

Merged
merged 131 commits into from
May 30, 2018
Merged

Dev #787

Changes from 1 commit
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
4740ed2
Fix issue 705 by including the possible negative sign
yitam Apr 2, 2018
54c0f5a
Fixed output to test
david-puglielli Apr 4, 2018
88f0bcf
Added bigint into the options
yitam Apr 4, 2018
a8db024
Merge pull request #737 from david-puglielli/pdo_utf8_conn-test-fix
david-puglielli Apr 4, 2018
dd58240
Merge pull request #732 from yitam/issue705
yitam Apr 4, 2018
72a1027
Merge pull request #740 from Microsoft/master
david-puglielli Apr 5, 2018
761c03e
Fixed test again
david-puglielli Apr 5, 2018
f15a3f8
Fixed test again
david-puglielli Apr 5, 2018
fafb7f4
Merge pull request #741 from david-puglielli/pdo_utf8_conn-test-fix
david-puglielli Apr 6, 2018
812db3d
Increase LAST_INSERT_ID_BUFF_LEN for other data types for identity co…
yitam Apr 6, 2018
dd64980
Merge pull request #742 from yitam/issue735
yitam Apr 6, 2018
2960738
Reverted change handling bigint output parameters
david-puglielli Apr 10, 2018
8c681f2
Updated failing tests
david-puglielli Apr 11, 2018
99a11c1
Fixed binary test
david-puglielli Apr 11, 2018
bbf951c
Minor fixes
david-puglielli Apr 11, 2018
454bc27
Merge pull request #744 from david-puglielli/Revert-bigint-change
david-puglielli Apr 11, 2018
2f8b9c2
Fix bigint output param test
yitam Apr 11, 2018
b8d1feb
Modified the driver tests as well
yitam Apr 12, 2018
c87e37f
Merge pull request #746 from yitam/BIGINTs
yitam Apr 12, 2018
93b9938
Replace most strlen with strnlen_s
yitam Apr 13, 2018
7a531d9
Merge pull request #747 from yitam/strlen
yitam Apr 16, 2018
9c78b1e
Modified the new issue template
yitam Apr 20, 2018
6365fbb
Workaround for pip install + ODBC 17 in windows
yitam Apr 20, 2018
c553105
Further simplified the issue template
yitam Apr 20, 2018
b34d5bd
Merge pull request #752 from yitam/template
yitam Apr 20, 2018
7a3d698
Modify buildscripts to configure php.ini
yitam Apr 20, 2018
16e0b89
Merge pull request #753 from yitam/phpini
yitam Apr 20, 2018
6b6500f
Use latest build scripts for testing with php 7.2
yitam Apr 20, 2018
d54f703
Debugging some more
yitam Apr 20, 2018
a548fcb
Tried not to rename the extensions
yitam Apr 23, 2018
dc95256
why empty coverage
yitam Apr 23, 2018
ac5064a
keep trying
yitam Apr 23, 2018
806c663
used full path for modules
yitam Apr 23, 2018
0169ec7
Tried other things
yitam Apr 23, 2018
3dbacb8
Try a shorter path
yitam Apr 24, 2018
714ea0f
Cleaning up to double check
yitam Apr 24, 2018
bdecae6
Switched the builder image
yitam Apr 24, 2018
4d9cc3c
Removed the wrong yml file
yitam Apr 24, 2018
246824a
Use the latest SQL Server
yitam Apr 24, 2018
72ca1cd
Fixed incorrect error when binding inout PDO STR with binary encoding
yitam Apr 24, 2018
3033a26
Added a comment to address the issue
yitam Apr 25, 2018
218497c
Made changes to output param handling code to convert doubles to ints…
yitam Apr 25, 2018
f4436d0
Merge pull request #757 from yitam/php72
yitam Apr 26, 2018
5b6b6f8
Merge branch 'dev' into vso2823
yitam Apr 26, 2018
5bb3f1a
Modified the error message to indicate value out of range
yitam Apr 26, 2018
5f6c399
A huge negative number is out of range too
yitam Apr 26, 2018
2fc3afe
Added a new test for issue 707
yitam Apr 27, 2018
06e9297
Use helper method isAEQualified instead
yitam Apr 30, 2018
440636a
Merge pull request #759 from yitam/vso2829
yitam May 1, 2018
04fa748
Added new tests for issue 678
yitam May 1, 2018
4a51049
Fixed one skipif
yitam May 1, 2018
5f99983
Use python -m pip instead
yitam May 1, 2018
1246864
Added --user
yitam May 2, 2018
991d776
Reverted -- user flag not working
yitam May 2, 2018
5f555df
Modified the expected results for a bind column test
yitam May 2, 2018
25f8590
Removed the workaround in a decimal test because issue 706 has been f…
yitam May 2, 2018
31685c4
Added another test for issue 699
yitam May 2, 2018
977e530
Support for Azure Key Vault
david-puglielli May 6, 2018
52cd004
Removed unnecessary comments
david-puglielli May 6, 2018
2fe0b5a
Removed more unnecessary comments
david-puglielli May 6, 2018
dde0e23
Merge pull request #764 from yitam/issue678
yitam May 7, 2018
f49da62
Added AKV configuration to setup files
david-puglielli May 7, 2018
55ae086
Skip test 699 in Linux for now
yitam May 7, 2018
39056d9
Removed output param test for now
yitam May 8, 2018
5a842c9
Merge pull request #761 from yitam/vso2823
yitam May 8, 2018
fb1a2ec
Changes according to PR review comments
david-puglielli May 8, 2018
5f62186
Updated Apache instructions, install order, fixed links
david-puglielli May 8, 2018
364fef6
Changes according to PR comments
david-puglielli May 8, 2018
2aaae26
Minor fixes
david-puglielli May 9, 2018
3b94eb4
Merging
david-puglielli May 9, 2018
f835447
Merge pull request #770 from david-puglielli/readme-apache-update
david-puglielli May 9, 2018
3cb84ee
Tests updated
david-puglielli May 9, 2018
b98b129
Tests updated
david-puglielli May 9, 2018
0bc4a36
Added test case for Issue 699
yitam May 14, 2018
2239511
Workaround for error returned in Linux
david-puglielli May 14, 2018
999312b
Tried using INT_MAX instead
yitam May 15, 2018
9a82e9d
Used sizeof not INT_MAX
yitam May 15, 2018
63c85ed
Merge pull request #765 from yitam/decimalTests
yitam May 15, 2018
bca3110
Modified the output param initial value
yitam May 15, 2018
4c7c085
Added workaround for the test plus use BIGINT for 64-bit systems
yitam May 15, 2018
0b5ceb0
Reverted the changes
yitam May 15, 2018
4747537
Fixed the formatting
yitam May 15, 2018
0a11136
Modified the test to address VSO 2915
yitam May 15, 2018
c56fb30
Changelog for 5.2.1-preview
yitam May 16, 2018
ebd7827
Fixed the links
yitam May 16, 2018
3d51d76
Fixed one more link
yitam May 16, 2018
079c4ea
Fixed tests, fixed wide char name in keystore struct
david-puglielli May 16, 2018
30a9708
Merge pull request #774 from yitam/vso2915
yitam May 16, 2018
196fe49
Merge pull request #773 from yitam/Issue699Test
yitam May 17, 2018
6eb96d9
Merge branch 'dev' into changelog
yitam May 17, 2018
e2b48df
Updated change log based on review
yitam May 17, 2018
85bda81
Skipping Ubuntu on verification akv tests
david-puglielli May 17, 2018
a0ade5d
Fixed connect_driver tests
david-puglielli May 17, 2018
64e2241
Extend output buffer sizes with SQL decimals or numerics
yitam May 17, 2018
eaa9446
Workaround for 32-bit error
david-puglielli May 17, 2018
757a84f
Added constant for AKV name
david-puglielli May 17, 2018
84f0168
Merge pull request #775 from yitam/vso2913
yitam May 18, 2018
10ea928
Fixed coding style
david-puglielli May 18, 2018
e2ed131
Final style fixes
david-puglielli May 18, 2018
e0f9afa
Merge pull request #768 from david-puglielli/azure-key-vault-support
david-puglielli May 18, 2018
05833bf
Modified BVT stream tests to make them more robust
yitam May 23, 2018
13e69b5
Fixed bigint insertion bug in x86
david-puglielli May 23, 2018
1b98036
Added unset to free conns/stmts
david-puglielli May 23, 2018
1edd16d
made bigint string for x64 too
david-puglielli May 24, 2018
5c46d4b
Merge pull request #777 from david-puglielli/bigint-x86-test-fix
david-puglielli May 24, 2018
f0eefaf
Merge pull request #776 from yitam/streamTests
yitam May 24, 2018
4c06237
Added a couple more fixes and elaborated some comments
yitam May 24, 2018
8356b15
Fixed some typos
yitam May 24, 2018
d26440b
Modified version.h for 5.2.1-preview
yitam May 24, 2018
cee6370
Split akv verification tests to fix SSL issue
david-puglielli May 25, 2018
8f5c706
Corrected the expected output
yitam May 25, 2018
6817c7b
Modified the comments to clarify things
yitam May 25, 2018
9e8d674
Fixed the bvt streams tests
yitam May 25, 2018
997e80c
Added High Sierra and modified the macOS instructions
yitam May 25, 2018
3c405f4
Shifted NOTES
yitam May 25, 2018
bd9d85b
Refactored some akv tests, other small changes
david-puglielli May 25, 2018
1747df1
addressed review comments
david-puglielli May 25, 2018
ff0e460
dropped tables at end
david-puglielli May 25, 2018
0861f06
Merge pull request #781 from david-puglielli/akv-verification-test-fix
david-puglielli May 25, 2018
c676ae0
Addressed review comments
yitam May 25, 2018
fbd686c
Merge pull request #782 from yitam/FixStreamTests
yitam May 25, 2018
45f422a
Merge pull request #780 from yitam/version
yitam May 25, 2018
d35575b
Added select type conversion test and updated values
david-puglielli May 26, 2018
c348aad
Addressed review comments
david-puglielli May 28, 2018
13144d9
Merge pull request #783 from david-puglielli/type-conversion-for-ae
david-puglielli May 28, 2018
b7a9ec6
Check if returned error is empty first before using count()
yitam May 29, 2018
99b91f8
Merge pull request #784 from yitam/fixCount
yitam May 29, 2018
9e75dfe
Merge pull request #779 from yitam/changelog
yitam May 29, 2018
b128820
Fixed akv test failures with win encryption
david-puglielli May 29, 2018
9d1eafd
Fixed encryption check
david-puglielli May 29, 2018
4509756
Merge pull request #785 from david-puglielli/ae-test-experiments
david-puglielli May 30, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions source/pdo_sqlsrv/pdo_dbh.cpp
Original file line number Diff line number Diff line change
@@ -40,17 +40,20 @@ const char Server[] = "Server";
const char APP[] = "APP";
const char ApplicationIntent[] = "ApplicationIntent";
const char AttachDBFileName[] = "AttachDbFileName";
const char ConnectionPooling[] = "ConnectionPooling";
const char Authentication[] = "Authentication";
const char Driver[] = "Driver";
#ifdef _WIN32
const char ColumnEncryption[] = "ColumnEncryption";
const char ConnectionPooling[] = "ConnectionPooling";
#ifdef _WIN32
const char ConnectRetryCount[] = "ConnectRetryCount";
const char ConnectRetryInterval[] = "ConnectRetryInterval";
#endif // _WIN32
const char Database[] = "Database";
const char Driver[] = "Driver";
const char Encrypt[] = "Encrypt";
const char Failover_Partner[] = "Failover_Partner";
const char KeyStoreAuthentication[] = "KeyStoreAuthentication";
const char KeyStorePrincipalId[] = "KeyStorePrincipalId";
const char KeyStoreSecret[] = "KeyStoreSecret";
const char LoginTimeout[] = "LoginTimeout";
const char MARS_Option[] = "MultipleActiveResultSets";
const char MultiSubnetFailover[] = "MultiSubnetFailover";
@@ -231,7 +234,6 @@ const connection_option PDO_CONN_OPTS[] = {
CONN_ATTR_STRING,
driver_set_func::func
},
#ifdef _WIN32
{
PDOConnOptionNames::ColumnEncryption,
sizeof(PDOConnOptionNames::ColumnEncryption),
@@ -241,6 +243,7 @@ const connection_option PDO_CONN_OPTS[] = {
CONN_ATTR_STRING,
column_encryption_set_func::func
},
#ifdef _WIN32
{
PDOConnOptionNames::ConnectRetryCount,
sizeof( PDOConnOptionNames::ConnectRetryCount ),
@@ -287,6 +290,33 @@ const connection_option PDO_CONN_OPTS[] = {
CONN_ATTR_STRING,
conn_str_append_func::func
},
{
PDOConnOptionNames::KeyStoreAuthentication,
sizeof( PDOConnOptionNames::KeyStoreAuthentication ),
SQLSRV_CONN_OPTION_KEYSTORE_AUTHENTICATION,
ODBCConnOptions::KeyStoreAuthentication,
sizeof( ODBCConnOptions::KeyStoreAuthentication ),
CONN_ATTR_STRING,
ce_akv_str_set_func::func
},
{
PDOConnOptionNames::KeyStorePrincipalId,
sizeof( PDOConnOptionNames::KeyStorePrincipalId ),
SQLSRV_CONN_OPTION_KEYSTORE_PRINCIPAL_ID,
ODBCConnOptions::KeyStorePrincipalId,
sizeof( ODBCConnOptions::KeyStorePrincipalId ),
CONN_ATTR_STRING,
ce_akv_str_set_func::func
},
{
PDOConnOptionNames::KeyStoreSecret,
sizeof( PDOConnOptionNames::KeyStoreSecret ),
SQLSRV_CONN_OPTION_KEYSTORE_SECRET,
ODBCConnOptions::KeyStoreSecret,
sizeof( ODBCConnOptions::KeyStoreSecret ),
CONN_ATTR_STRING,
ce_akv_str_set_func::func
},
{
PDOConnOptionNames::LoginTimeout,
sizeof( PDOConnOptionNames::LoginTimeout ),
@@ -362,7 +392,7 @@ const connection_option PDO_CONN_OPTS[] = {
{
PDOConnOptionNames::TransparentNetworkIPResolution,
sizeof(PDOConnOptionNames::TransparentNetworkIPResolution),
SQLSRV_CONN_OPTION_TRANSPARANT_NETWORK_IP_RESOLUTION,
SQLSRV_CONN_OPTION_TRANSPARENT_NETWORK_IP_RESOLUTION,
ODBCConnOptions::TransparentNetworkIPResolution,
sizeof(ODBCConnOptions::TransparentNetworkIPResolution),
CONN_ATTR_STRING,
2 changes: 1 addition & 1 deletion source/pdo_sqlsrv/pdo_parser.cpp
Original file line number Diff line number Diff line change
@@ -189,7 +189,7 @@ void conn_string_parser::add_key_value_pair( _In_reads_(len) const char* value,
if( !valid ) {
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_AUTHENTICATION_OPTION, this->current_key_name );
}

string_parser::add_key_value_pair( value, len );
}

16 changes: 16 additions & 0 deletions source/pdo_sqlsrv/pdo_util.cpp
Original file line number Diff line number Diff line change
@@ -409,6 +409,22 @@ pdo_error PDO_ERRORS[] = {
SQLSRV_ERROR_ENCRYPTED_STREAM_FETCH,
{ IMSSP, (SQLCHAR*) "Connection with Column Encryption enabled does not support fetching stream. Please fetch the data as a string.", -84, false }
},
{
SQLSRV_ERROR_INVALID_AKV_AUTHENTICATION_OPTION,
{ IMSSP, (SQLCHAR*) "Invalid option for the KeyStoreAuthentication keyword. Only KeyVaultPassword or KeyVaultClientSecret is allowed.", -85, false }
},
{
SQLSRV_ERROR_AKV_AUTH_MISSING,
{ IMSSP, (SQLCHAR*) "Authentication method for Azure Key Vault is missing. KeyStoreAuthentication must be set to KeyVaultPassword or KeyVaultClientSecret.", -86, false }
},
{
SQLSRV_ERROR_AKV_NAME_MISSING,
{ IMSSP, (SQLCHAR*) "ID for Azure Key Vault is missing. A username or client Id is required.", -87, false }
},
{
SQLSRV_ERROR_AKV_SECRET_MISSING,
{ IMSSP, (SQLCHAR*) "Secret for Azure Key Vault is missing. A password or client secret is required.", -88, false }
},
{ UINT_MAX, {} }
};

142 changes: 135 additions & 7 deletions source/shared/core_conn.cpp
Original file line number Diff line number Diff line change
@@ -71,6 +71,9 @@ 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_azure_key_vault( _Inout_ sqlsrv_conn* conn TSRMLS_DC );
void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const DWORD config_value, size_t key_size);
void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const char* config_value, size_t key_size);
}

// core_sqlsrv_connect
@@ -128,13 +131,13 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
// we do this earlier because we have to allocate the connection handle prior to setting attributes on
// it in build_connection_string_and_set_conn_attr.

if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {
zval* option_z = NULL;
option_z = zend_hash_index_find( options_ht, SQLSRV_CONN_OPTION_CONN_POOLING );
if ( option_z ) {
// if the option was found and it's not true, then use the non pooled environment handle
if(( Z_TYPE_P( option_z ) == IS_STRING && !core_str_zval_is_true( option_z )) || !zend_is_true( option_z ) ) {
if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {

zval* option_z = NULL;
option_z = zend_hash_index_find( options_ht, SQLSRV_CONN_OPTION_CONN_POOLING );
if ( option_z ) {
// if the option was found and it's not true, then use the non pooled environment handle
if(( Z_TYPE_P( option_z ) == IS_STRING && !core_str_zval_is_true( option_z )) || !zend_is_true( option_z ) ) {
henv = &henv_ncp;
is_pooled = false;
}
@@ -245,6 +248,8 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
throw core::CoreException();
}

load_azure_key_vault( conn );

// determine the version of the server we're connected to. The server version is left in the
// connection upon return.
//
@@ -932,6 +937,90 @@ void determine_server_version( _Inout_ sqlsrv_conn* conn TSRMLS_DC )
conn->server_version = version_major;
}

void load_azure_key_vault( _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.akv_required )
return;

CHECK_CUSTOM_ERROR( conn->ce_option.akv_auth == NULL || Z_STRLEN_P(conn->ce_option.akv_auth) <= 0, conn, SQLSRV_ERROR_AKV_AUTH_MISSING) {
throw core::CoreException();
}

CHECK_CUSTOM_ERROR( conn->ce_option.akv_id == NULL || Z_STRLEN_P(conn->ce_option.akv_id) <= 0, conn, SQLSRV_ERROR_AKV_NAME_MISSING) {
throw core::CoreException();
}

CHECK_CUSTOM_ERROR( conn->ce_option.akv_secret == NULL || Z_STRLEN_P(conn->ce_option.akv_secret) <= 0, conn, SQLSRV_ERROR_AKV_SECRET_MISSING) {
throw core::CoreException();
}

char *akv_auth = Z_STRVAL_P( conn->ce_option.akv_auth );
char *akv_id = Z_STRVAL_P( conn->ce_option.akv_id );
char *akv_secret = Z_STRVAL_P( conn->ce_option.akv_secret );
unsigned int id_len = static_cast<unsigned int>( Z_STRLEN_P( conn->ce_option.akv_id ));
unsigned int key_size = static_cast<unsigned int>( Z_STRLEN_P( conn->ce_option.akv_secret ));

//sqlsrv_malloc_auto_ptr<unsigned char> akv_data;
//akv_data = reinterpret_cast<unsigned char*>( sqlsrv_malloc( sizeof( CEKEYSTOREDATA ) + key_size ));
//CEKEYSTOREDATA *pAKV = reinterpret_cast<CEKEYSTOREDATA*>( akv_data.get() );

//pAKV->dataSize = key_size;

// unsigned int wid_len = 0;
// sqlsrv_malloc_auto_ptr<SQLWCHAR> wakv_id;
// wakv_id = utf16_string_from_mbcs_string( SQLSRV_ENCODING_UTF8, akv_id, id_len, &wid_len );

// CHECK_CUSTOM_ERROR( wakv_id == 0, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE ) {
// throw core::CoreException();
// }

//pAKV->name = L"AZURE_KEY_VAULT";(wchar_t *) wakv_id.get();

// Next, extract the character string from conn->ce_option.ksp_encrypt_key into encrypt_key
//char* akv_secret = Z_STRVAL_P( conn->ce_option.akv_secret );
//memcpy_s( pAKV->data, key_size * sizeof( char ) , encrypt_key, key_size );

if ( !stricmp(akv_auth, "KeyVaultPassword") )
{
configure_azure_key_vault( conn, AKV_CONFIG_FLAGS, AKVCFG_AUTHMODE_PASSWORD, 0 );
}
else if ( !stricmp(akv_auth, "KeyVaultClientSecret") )
{
configure_azure_key_vault( conn, AKV_CONFIG_FLAGS, AKVCFG_AUTHMODE_CLIENTKEY, 0 );
}

configure_azure_key_vault( conn, AKV_CONFIG_PRINCIPALID, akv_id, id_len );
configure_azure_key_vault( conn, AKV_CONFIG_AUTHSECRET, akv_secret, key_size );
}

void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const DWORD config_value, size_t key_size )
{
BYTE akv_data[sizeof( CEKEYSTOREDATA ) + sizeof(DWORD) + 1 ];
CEKEYSTOREDATA *pData = reinterpret_cast<CEKEYSTOREDATA*>( akv_data );
pData->name = L"AZURE_KEY_VAULT";
pData->data[0] = config_attr;
pData->dataSize = sizeof(config_attr) + sizeof(config_value);
*reinterpret_cast<DWORD*>(&pData->data[1]) = config_value;

core::SQLSetConnectAttr( conn, SQL_COPT_SS_CEKEYSTOREDATA, reinterpret_cast<SQLPOINTER>(pData), SQL_IS_POINTER );
}

void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const char* config_value, size_t key_size )
{
BYTE akv_data[sizeof( CEKEYSTOREDATA ) + 2048 ];
CEKEYSTOREDATA *pData = reinterpret_cast<CEKEYSTOREDATA*>( akv_data );
pData->name = L"AZURE_KEY_VAULT";
pData->data[0] = config_attr;
pData->dataSize = 1+key_size;
//pData->data[1] = config_value;
memcpy_s( pData->data+1, key_size * sizeof( char ) , config_value, key_size );

core::SQLSetConnectAttr( conn, SQL_COPT_SS_CEKEYSTOREDATA, reinterpret_cast<SQLPOINTER>(pData), 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
@@ -1005,6 +1094,45 @@ void column_encryption_set_func::func( _In_ connection_option const* option, _In
conn_str += ";";
}

void ce_akv_str_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, "Azure Key Vault keywords accept only strings." );

//size_t value_len = Z_STRLEN_P( value );

switch( option->conn_option_key )
{
case SQLSRV_CONN_OPTION_KEYSTORE_AUTHENTICATION:
{
char *value_str = Z_STRVAL_P( value );
CHECK_CUSTOM_ERROR( stricmp( value_str, "KeyVaultPassword" ) && stricmp( value_str, "KeyVaultClientSecret" ), conn, SQLSRV_ERROR_INVALID_AKV_AUTHENTICATION_OPTION )
{
throw core::CoreException();
}
conn->ce_option.akv_auth = value;
conn->ce_option.akv_required = true;
break;
}
case SQLSRV_CONN_OPTION_KEYSTORE_PRINCIPAL_ID:
{
conn->ce_option.akv_id = value;
//conn->ce_option.akv_id_len = value_len;
conn->ce_option.akv_required = true;
break;
}
case SQLSRV_CONN_OPTION_KEYSTORE_SECRET:
{
conn->ce_option.akv_secret = value;
//conn->ce_option.akv_secret_len = value_len;
conn->ce_option.akv_required = true;
break;
}
default:
SQLSRV_ASSERT( false, "ce_akv_str_set_func: Invalid AKV 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.
26 changes: 22 additions & 4 deletions source/shared/core_sqlsrv.h
Original file line number Diff line number Diff line change
@@ -1055,8 +1055,12 @@ 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 akv_auth;
zval_auto_ptr akv_id;
zval_auto_ptr akv_secret;
bool akv_required;

col_encryption_option() : enabled( false )
col_encryption_option() : enabled( false ), akv_required( false )
{
}
};
@@ -1106,14 +1110,17 @@ const char Authentication[] = "Authentication";
const char Driver[] = "Driver";
const char CharacterSet[] = "CharacterSet";
const char ConnectionPooling[] = "ConnectionPooling";
#ifdef _WIN32
const char ColumnEncryption[] = "ColumnEncryption";
#ifdef _WIN32
const char ConnectRetryCount[] = "ConnectRetryCount";
const char ConnectRetryInterval[] = "ConnectRetryInterval";
#endif // _WIN32
const char Database[] = "Database";
const char Encrypt[] = "Encrypt";
const char Failover_Partner[] = "Failover_Partner";
const char KeyStoreAuthentication[] = "KeyStoreAuthentication";
const char KeyStorePrincipalId[] = "KeyStorePrincipalId";
const char KeyStoreSecret[] = "KeyStoreSecret";
const char LoginTimeout[] = "LoginTimeout";
const char MARS_ODBC[] = "MARS_Connection";
const char MultiSubnetFailover[] = "MultiSubnetFailover";
@@ -1156,7 +1163,10 @@ enum SQLSRV_CONN_OPTIONS {
SQLSRV_CONN_OPTION_CEKEYSTORE_PROVIDER,
SQLSRV_CONN_OPTION_CEKEYSTORE_NAME,
SQLSRV_CONN_OPTION_CEKEYSTORE_ENCRYPT_KEY,
SQLSRV_CONN_OPTION_TRANSPARANT_NETWORK_IP_RESOLUTION,
SQLSRV_CONN_OPTION_KEYSTORE_AUTHENTICATION,
SQLSRV_CONN_OPTION_KEYSTORE_PRINCIPAL_ID,
SQLSRV_CONN_OPTION_KEYSTORE_SECRET,
SQLSRV_CONN_OPTION_TRANSPARENT_NETWORK_IP_RESOLUTION,
#ifdef _WIN32
SQLSRV_CONN_OPTION_CONN_RETRY_COUNT,
SQLSRV_CONN_OPTION_CONN_RETRY_INTERVAL,
@@ -1219,6 +1229,10 @@ struct ce_ksp_provider_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC );
};

struct ce_akv_str_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC );
};


// factory to create a connection (since they are subclassed to instantiate statements)
typedef sqlsrv_conn* (*driver_conn_factory)( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* drv TSRMLS_DC );
@@ -1699,6 +1713,10 @@ enum SQLSRV_ERROR_CODES {
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
SQLSRV_ERROR_INVALID_BUFFER_LIMIT,
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
SQLSRV_ERROR_INVALID_AKV_AUTHENTICATION_OPTION,
SQLSRV_ERROR_AKV_AUTH_MISSING,
SQLSRV_ERROR_AKV_NAME_MISSING,
SQLSRV_ERROR_AKV_SECRET_MISSING,
SQLSRV_ERROR_ENCRYPTED_STREAM_FETCH,

// Driver specific error codes starts from here.
@@ -1916,7 +1934,7 @@ namespace core {
}

inline void SQLAllocHandle( _In_ SQLSMALLINT HandleType, _Inout_ sqlsrv_context& InputHandle,
_Out_ SQLHANDLE* OutputHandlePtr TSRMLS_DC )
_Out_ SQLHANDLE* OutputHandlePtr TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLAllocHandle( HandleType, InputHandle.handle(), OutputHandlePtr );
Loading