Skip to content

Commit

Permalink
feat: okta authentication support (#203)
Browse files Browse the repository at this point in the history
  • Loading branch information
karenc-bq committed Aug 30, 2024
1 parent 81540b4 commit 3097afb
Show file tree
Hide file tree
Showing 27 changed files with 860 additions and 97 deletions.
82 changes: 30 additions & 52 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,44 +1,32 @@
# Copyright (c) 2016, 2024, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is designed to work with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms, as
# designated in a particular file or component or in included license
# documentation. The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have either included with
# the program or referenced in the documentation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 2.0
// (GPLv2), as published by the Free Software Foundation, with the
// following additional permissions:
//
// This program is distributed with certain software that is licensed
// under separate terms, as designated in a particular file or component
// or in the license documentation. Without limiting your rights under
// the GPLv2, the authors of this program hereby grant you an additional
// permission to link the program and your derivative works with the
// separately licensed software that they have included with the program.
//
// Without limiting the foregoing grant of rights under the GPLv2 and
// additional permission as to separately licensed software, this
// program is also subject to the Universal FOSS Exception, version 1.0,
// a copy of which can be found along with its FAQ at
// http://oss.oracle.com/licenses/universal-foss-exception.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License, version 2.0, for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// http://www.gnu.org/licenses/gpl-2.0.html.

# We currently use clang-format version 10.
#
# This is the output of
#
# $ clang-format-10 --style=google --dump-config
#
# for C++ files except for changes mentioned below.
#
# For JavaScript files the output is generated by:
#
# $ clang-format-10 --assume-filename=format.js \
# --style=google --dump-config
#
# We lock the style so that any newer version of clang-format will give
# the same result; as time goes, we may update this list, requiring
# newer versions of clang-format.

---
Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -1
Expand Down Expand Up @@ -90,23 +78,21 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
Expand Down Expand Up @@ -146,7 +132,6 @@ PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
- Language: Cpp
Delimiters:
Expand Down Expand Up @@ -197,7 +182,6 @@ SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
Expand All @@ -208,10 +192,7 @@ UseTab: Never
# We declare one specific pointer style since right alignment is dominant in
# the MySQL code base (default --style=google has DerivePointerAlignment true).
DerivePointerAlignment: false
PointerAlignment: Right

# MySQL source code is allowed to use C++11 (and C++14) features.
Standard: Cpp11
PointerAlignment: Left

# MySQL includes frequently are not order-independent (e.g. my_config.h needs
# to go on top). This is unfortunate, but not something we can change easily,
Expand Down Expand Up @@ -285,7 +266,6 @@ ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
Expand Down Expand Up @@ -325,7 +305,6 @@ PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
- Language: Cpp
Delimiters:
Expand Down Expand Up @@ -376,7 +355,6 @@ SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/failover.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ jobs:
unzip -d C:/mysql-${{ vars.MYSQL_VERSION }}-winx64-debug mysql-debug.zip
mv -Force C:/mysql-${{ vars.MYSQL_VERSION }}-winx64-debug/mysql-${{ vars.MYSQL_VERSION }}-winx64/lib/debug/mysqlclient.lib C:/mysql-${{ vars.MYSQL_VERSION }}-winx64/lib/mysqlclient.lib
- name: Install OpenSSL 3
run: |
curl -L https://download.firedaemon.com/FireDaemon-OpenSSL/openssl-3.3.1.zip -o openssl3.zip
unzip -d C:/ openssl3.zip
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2

Expand Down Expand Up @@ -71,6 +76,9 @@ jobs:
-DMYSQLCLIENT_STATIC_LINKING=TRUE
-DENABLE_UNIT_TESTS=TRUE
-DENABLE_INTEGRATION_TESTS=FALSE
-DOPENSSL_INCLUDE_DIR="C:/openssl-3/x64/include/"
-DOPENSSL_LIBRARY="C:/openssl-3/x64/bin/libssl-3-x64.dll"
-DCRYPTO_LIBRARY="C:/openssl-3/x64/bin/libcrypto-3-x64.dll"

# Configure test environment
- name: Build Driver
Expand Down
20 changes: 14 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ jobs:
curl -L https://dev.mysql.com/get/Downloads/MySQL-8.3/mysql-${{ vars.MYSQL_VERSION }}-winx64.zip -o mysql.zip
unzip -d C:/ mysql.zip
- name: Install OpenSSL 3
run: |
curl -L https://download.firedaemon.com/FireDaemon-OpenSSL/openssl-3.3.1.zip -o openssl3.zip
unzip -d C:/ openssl3.zip
cp -r C:/openssl-3/x64/bin/libssl-3-x64.dll C:/Windows/System32/
cp -r C:/openssl-3/x64/bin/libcrypto-3-x64.dll C:/Windows/System32/
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2

Expand Down Expand Up @@ -66,15 +73,16 @@ jobs:
-DMYSQL_SQL="C:/mysql-${{ vars.MYSQL_VERSION }}-winx64"
-DCMAKE_BUILD_TYPE=$BUILD_TYPE
-DMYSQLCLIENT_STATIC_LINKING=TRUE
-DOPENSSL_INCLUDE_DIR="C:/openssl-3/x64/include/"

# Configure test environment
- name: Build Driver and Copy files
shell: bash
working-directory: ${{ github.workspace }}/build
run: |
cmake --build . --config $BUILD_TYPE
cp -r lib/Release/* C:/Windows/System32/
cp -r bin/Release/* C:/Windows/System32/
cp -r lib/$BUILD_TYPE/* C:/Windows/System32/
cp -r bin/$BUILD_TYPE/* C:/Windows/System32/
- name: Add DSN to registry
shell: bash
Expand Down Expand Up @@ -157,11 +165,11 @@ jobs:
brew update
brew unlink unixodbc
brew install libiodbc mysql@8.3 mysql-client@8.3
brew install libiodbc mysql@8.4 mysql-client@8.4
brew link --overwrite --force libiodbc
brew link --overwrite --force mysql@8.3
echo 'export PATH="/usr/local/opt/mysql@8.3/bin:$PATH"' >> /Users/runner/.bash_profile
echo 'export PATH="/usr/local/opt/mysql-client@8.3/bin:$PATH"' >> /Users/runner/.bash_profile
brew link --overwrite --force mysql@8.4
echo 'export PATH="/usr/local/opt/mysql@8.4/bin:$PATH"' >> /Users/runner/.bash_profile
echo 'export PATH="/usr/local/opt/mysql-client@8.4/bin:$PATH"' >> /Users/runner/.bash_profile
brew install openssl@3
rm -f /usr/local/lib/libssl.3.dylib
Expand Down
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ ENDIF(WIN32)
#------------ find the AWS SDK for C++ package---------
LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/aws_sdk/install")

FIND_PACKAGE(AWSSDK REQUIRED COMPONENTS rds secretsmanager)
FIND_PACKAGE(AWSSDK REQUIRED COMPONENTS rds secretsmanager sts)

#------------------------------------------------------

Expand Down Expand Up @@ -815,7 +815,6 @@ else(APPLE)
)
endif(APPLE)


# List plugins and other libraries that can be found bundled with the server
# but which are not relevant on client-side and can be safely ignored.

Expand Down
29 changes: 27 additions & 2 deletions driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,14 @@ WHILE(${DRIVER_INDEX} LESS ${DRIVERS_COUNT})
my_stmt.cc
mylog.cc
mysql_proxy.cc
okta_proxy.cc
options.cc
parse.cc
prepare.cc
query_parsing.cc
results.cc
saml_http_client.cc
saml_util.cc
secrets_manager_proxy.cc
topology_service.cc
transact.cc
Expand Down Expand Up @@ -149,8 +152,11 @@ WHILE(${DRIVER_INDEX} LESS ${DRIVERS_COUNT})
mylog.h
mysql_proxy.h
myutil.h
okta_proxy.h
parse.h
query_parsing.h
saml_http_client.h
saml_util.h
secrets_manager_proxy.h
topology_service.h
../MYODBC_MYSQL.h ../MYODBC_CONF.h ../MYODBC_ODBC.h)
Expand Down Expand Up @@ -295,10 +301,29 @@ WHILE(${DRIVER_INDEX} LESS ${DRIVERS_COUNT})

MATH(EXPR DRIVER_INDEX "${DRIVER_INDEX} + 1")

#------------DEPENDENCIES FOR FEDERATED AUTH---------
include(FetchContent)

FetchContent_Declare(
json
URL https://github.com/nlohmann/json/releases/download/v3.10.5/json.tar.xz
)

FetchContent_Declare(
httplib
URL https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.16.1.zip
)

FetchContent_MakeAvailable(httplib json)

TARGET_INCLUDE_DIRECTORIES(${DRIVER_NAME} PUBLIC "${httplib_SOURCE_DIR}" ${OPENSSL_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${DRIVER_NAME} nlohmann_json::nlohmann_json)
TARGET_INCLUDE_DIRECTORIES(${DRIVER_NAME_STATIC} PUBLIC "${httplib_SOURCE_DIR}" ${OPENSSL_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${DRIVER_NAME_STATIC} nlohmann_json::nlohmann_json)

#------------AWS SDK------------------
LIST(APPEND SERVICE_LIST rds secretsmanager)
LIST(APPEND SERVICE_LIST rds secretsmanager sts aws-c-compression aws-c-sdkutils)

MESSAGE(STATUS "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}")
IF(MSVC)
MESSAGE(STATUS "Copying AWS SDK libraries to ${LIBRARY_OUTPUT_PATH}/${CMAKE_BUILD_TYPE}")
AWSSDK_CPY_DYN_LIBS(SERVICE_LIST "" ${LIBRARY_OUTPUT_PATH}/${CMAKE_BUILD_TYPE})
Expand Down
16 changes: 13 additions & 3 deletions driver/auth_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,26 @@ AWS_SDK_HELPER SDK_HELPER;
AUTH_UTIL::AUTH_UTIL(const char* region) {
++SDK_HELPER;

Aws::Auth::DefaultAWSCredentialsProviderChain credentials_provider;
Aws::Auth::AWSCredentials credentials = credentials_provider.GetAWSCredentials();
Aws::RDS::RDSClientConfiguration client_config;
if (region) {
client_config.region = region;
}

this->rds_client = std::make_shared<Aws::RDS::RDSClient>(
Aws::Auth::DefaultAWSCredentialsProviderChain().GetAWSCredentials(),
client_config);
};

AUTH_UTIL::AUTH_UTIL(const char* region, Aws::Auth::AWSCredentials credentials) {
++SDK_HELPER;

Aws::RDS::RDSClientConfiguration client_config;
if (region) {
client_config.region = region;
}

this->rds_client = std::make_shared<Aws::RDS::RDSClient>(credentials, client_config);
};
}

std::string AUTH_UTIL::get_auth_token(const char* host, const char* region, unsigned int port, const char* user) {
return this->rds_client->GenerateConnectAuthToken(host, region, port, user);
Expand Down
1 change: 1 addition & 0 deletions driver/auth_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class AUTH_UTIL {
public:
AUTH_UTIL() {};
AUTH_UTIL(const char* region);
AUTH_UTIL(const char* region, Aws::Auth::AWSCredentials credentials);
~AUTH_UTIL();

virtual std::string get_auth_token(const char* host, const char* region, unsigned int port, const char* user);
Expand Down
3 changes: 2 additions & 1 deletion driver/connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,8 @@ SQLRETURN DBC::connect(DataSource *dsrc, bool failover_enabled, bool is_monitor_
#if (MYSQL_VERSION_ID >= 50527 && MYSQL_VERSION_ID < 50600) || MYSQL_VERSION_ID >= 50607
// IAM authentication requires the plugin to be set.
if (dsrc->opt_ENABLE_CLEARTEXT_PLUGIN ||
(dsrc->opt_AUTH_MODE && !myodbc_strcasecmp(AUTH_MODE_IAM, (const char*)dsrc->opt_AUTH_MODE)))
(dsrc->opt_AUTH_MODE && !myodbc_strcasecmp(AUTH_MODE_IAM, (const char*)dsrc->opt_AUTH_MODE))
|| dsrc->opt_FED_AUTH_MODE)
{
connection_proxy->options(MYSQL_ENABLE_CLEARTEXT_PLUGIN, (char *)&on);
}
Expand Down
16 changes: 16 additions & 0 deletions driver/handle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@
* *
****************************************************************************/

#include "adfs_proxy.h"
#include "driver.h"
#include "efm_proxy.h"
#include "iam_proxy.h"
#include "mysql_proxy.h"
#include "okta_proxy.h"
#include "secrets_manager_proxy.h"

#include <mutex>
Expand Down Expand Up @@ -141,6 +143,20 @@ void DBC::init_proxy_chain(DataSource* dsrc)
}
}

if (dsrc->opt_FED_AUTH_MODE) {
const char* fed_auth_mode = (const char*)dsrc->opt_FED_AUTH_MODE;
if (!myodbc_strcasecmp(FED_AUTH_MODE_ADFS, fed_auth_mode)) {
CONNECTION_PROXY* adfs_proxy = new ADFS_PROXY(this, dsrc);
adfs_proxy->set_next_proxy(head);
head = adfs_proxy;
}
else if (!myodbc_strcasecmp(FED_AUTH_MODE_OKTA, fed_auth_mode)) {
CONNECTION_PROXY* okta_proxy = new OKTA_PROXY(this, dsrc);
okta_proxy->set_next_proxy(head);
head = okta_proxy;
}
}

this->connection_proxy = head;
}

Expand Down
Loading

0 comments on commit 3097afb

Please sign in to comment.