Skip to content

Commit

Permalink
fix: IAM auth in CN RDS (#579) (#582)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronchung-bitquill authored May 30, 2024
1 parent 5264adb commit 926d28f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

package com.mysql.cj.protocol.a.authentication;

import com.mysql.cj.jdbc.ha.util.RdsUtils;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rds.RdsUtilities;
Expand All @@ -50,7 +51,7 @@ public class AwsIamAuthenticationTokenHelper {
private final String hostname;
private final int port;
private final Log log;
private static final int REGION_MATCHER_GROUP = 3;
private static final String REGION_MATCHER_GROUP = "region";

public AwsIamAuthenticationTokenHelper(final String hostname, final int port, final String logger) {
this.log = LogFactory.getLogger(logger, Log.LOGGER_INSTANCE_NAME);
Expand Down Expand Up @@ -83,23 +84,25 @@ private String generateAuthenticationToken(final String user) {

private Region getRdsRegion() {
// Check Hostname
final Pattern auroraDnsPattern =
Pattern.compile(
"(.+)\\.(proxy-|cluster-|cluster-ro-|cluster-custom-)?[a-zA-Z0-9]+\\.([a-zA-Z0-9\\-]+)\\.rds\\.amazonaws\\.com",
Pattern.CASE_INSENSITIVE);
final Matcher matcher = auroraDnsPattern.matcher(hostname);
Matcher matcher = RdsUtils.AURORA_DNS_PATTERN.matcher(hostname);
if (!matcher.find()) {
// Does not match Amazon's Hostname, throw exception
final String exceptionMessage = Messages.getString(
"AuthenticationAwsIamPlugin.UnsupportedHostname",
new String[]{hostname});

log.logTrace(exceptionMessage);
throw ExceptionFactory.createException(exceptionMessage);
final Matcher chinaMatcher = RdsUtils.AURORA_CHINA_DNS_PATTERN.matcher(hostname);
if (!chinaMatcher.find()) {
// Does not match Amazon's Hostname, throw exception
final String exceptionMessage = Messages.getString(
"AuthenticationAwsIamPlugin.UnsupportedHostname",
new String[]{hostname});

log.logTrace(exceptionMessage);
throw ExceptionFactory.createException(exceptionMessage);
}
matcher = chinaMatcher;
}

// Get Region
final String rdsRegion = matcher.group(REGION_MATCHER_GROUP);
final String rdsRegion = matcher.group(REGION_MATCHER_GROUP) == null
? null
: matcher.group(REGION_MATCHER_GROUP).replaceAll("rds", "").replaceAll("\\.", "");

// Check Region
Optional<Region> regionOptional = Region.regions().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ AuthenticationProvider.BadDisabledAuthenticationPlugin=Can''t disable the defaul
AuthenticationProvider.AuthenticationPluginRequiresSSL=SSL connection required for plugin "{0}". Check if ''sslMode'' is enabled.
AuthenticationProvider.UnexpectedAuthenticationApproval=Unexpected authentication approval. Authentication plugin "{0}" did not report "done" state but server has approved the connection.

AuthenticationAwsIamPlugin.UnsupportedHostname=Unsupported AWS hostname ''{0}''. Amazon domain name in format *.AWS-Region.rds.amazonaws.com is expected
AuthenticationAwsIamPlugin.UnsupportedHostname=Unsupported AWS hostname ''{0}''. Amazon domain name in format *.AWS-Region.rds.amazonaws.com or *.rds.AWS-Region.amazonaws.com.cn is expected
AuthenticationAwsIamPlugin.UnsupportedRegion=Unsupported AWS region ''{0}''. For supported regions, please read https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html
AuthenticationAwsIamPlugin.MissingSDK=Unable to connect using AWS IAM authentication due to missing AWS Java SDK For Amazon RDS. Add dependency to classpath.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public class RdsUtils {
// Instance Endpoint: <instance-name>.<xyz>.rds.<aws-region>.amazonaws.com.cn
// Example: test-postgres-instance-1.123456789012.rds.cn-northwest-1.amazonaws.com.cn

private static final Pattern AURORA_DNS_PATTERN =
public static final Pattern AURORA_DNS_PATTERN =
Pattern.compile(
"(?<instance>.+)\\."
+ "(?<dns>proxy-|cluster-|cluster-ro-|cluster-custom-)?"
Expand All @@ -104,7 +104,7 @@ public class RdsUtils {
+ "(?<domain>[a-zA-Z0-9]+\\.(?<region>[a-zA-Z0-9\\-]+)\\.rds\\.amazonaws\\.com(\\.cn)?)",
Pattern.CASE_INSENSITIVE);

private static final Pattern AURORA_CHINA_DNS_PATTERN =
public static final Pattern AURORA_CHINA_DNS_PATTERN =
Pattern.compile(
"(?<instance>.+)\\."
+ "(?<dns>proxy-|cluster-|cluster-ro-|cluster-custom-)?"
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/testsuite/simple/AwsIamAuthenticationHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ public void test_1_ValidHostAndRegion() {
PORT,
StandardLogger.class.getName()
));

Assertions.assertNotNull(new AwsIamAuthenticationTokenHelper(
"MyDBInstanceName.SomeServerName.us-east-1.rds.amazonaws.com.cn",
PORT,
StandardLogger.class.getName()
));

Assertions.assertNotNull(new AwsIamAuthenticationTokenHelper(
"test-postgres.cluster-123456789012.rds.cn-northwest-1.amazonaws.com.cn",
PORT,
StandardLogger.class.getName()
));
}


Expand Down

0 comments on commit 926d28f

Please sign in to comment.