Skip to content

Commit

Permalink
Merge branch 'main' of github.com:opensearch-project/security into HEAD
Browse files Browse the repository at this point in the history
Signed-off-by: Derek Ho <dxho@amazon.com>
  • Loading branch information
derek-ho committed Dec 20, 2024
2 parents dacdae5 + 2f870c7 commit e255e14
Show file tree
Hide file tree
Showing 21 changed files with 699 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
working-directory: downloaded-artifacts

- name: Upload Coverage with retry
uses: Wandalen/wretry.action@v3.7.2
uses: Wandalen/wretry.action@v3.7.3
with:
attempt_limit: 5
attempt_delay: 2000
Expand Down
28 changes: 14 additions & 14 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -489,16 +489,16 @@ configurations {
force "org.apache.commons:commons-lang3:${versions.commonslang}"

// for spotless transitive dependency CVE
force "org.eclipse.platform:org.eclipse.core.runtime:3.31.100"
force "org.eclipse.platform:org.eclipse.equinox.common:3.19.100"
force "org.eclipse.platform:org.eclipse.core.runtime:3.32.0"
force "org.eclipse.platform:org.eclipse.equinox.common:3.19.200"

// For integrationTest
force "org.apache.httpcomponents:httpclient:4.5.14"
force "org.apache.httpcomponents:httpcore:4.4.16"
force "com.google.errorprone:error_prone_annotations:2.35.1"
force "org.checkerframework:checker-qual:3.48.2"
force "com.google.errorprone:error_prone_annotations:2.36.0"
force "org.checkerframework:checker-qual:3.48.3"
force "ch.qos.logback:logback-classic:1.5.12"
force "commons-io:commons-io:2.17.0"
force "commons-io:commons-io:2.18.0"
}
}

Expand Down Expand Up @@ -585,7 +585,7 @@ dependencies {
implementation 'commons-cli:commons-cli:1.9.0'
implementation "org.bouncycastle:bcprov-jdk18on:${versions.bouncycastle}"
implementation 'org.ldaptive:ldaptive:1.2.3'
implementation 'com.nimbusds:nimbus-jose-jwt:9.46'
implementation 'com.nimbusds:nimbus-jose-jwt:9.47'
implementation 'com.rfksystems:blake2b:2.0.0'
implementation 'com.password4j:password4j:1.8.2'

Expand All @@ -611,7 +611,7 @@ dependencies {
runtimeOnly 'com.eclipsesource.minimal-json:minimal-json:0.9.5'
runtimeOnly 'commons-codec:commons-codec:1.17.1'
runtimeOnly 'org.cryptacular:cryptacular:1.2.7'
compileOnly 'com.google.errorprone:error_prone_annotations:2.35.1'
compileOnly 'com.google.errorprone:error_prone_annotations:2.36.0'
runtimeOnly 'com.sun.istack:istack-commons-runtime:4.2.0'
runtimeOnly 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.2'
runtimeOnly 'org.ow2.asm:asm:9.7.1'
Expand All @@ -620,7 +620,7 @@ dependencies {

//OpenSAML
implementation 'net.shibboleth.utilities:java-support:8.4.2'
runtimeOnly "io.dropwizard.metrics:metrics-core:4.2.28"
runtimeOnly "io.dropwizard.metrics:metrics-core:4.2.29"
implementation "com.onelogin:java-saml:${one_login_java_saml}"
implementation "com.onelogin:java-saml-core:${one_login_java_saml}"
implementation "org.opensaml:opensaml-core:${open_saml_version}"
Expand All @@ -641,7 +641,7 @@ dependencies {
implementation "com.nulab-inc:zxcvbn:1.9.0"

runtimeOnly 'com.google.guava:failureaccess:1.0.2'
runtimeOnly 'org.apache.commons:commons-text:1.12.0'
runtimeOnly 'org.apache.commons:commons-text:1.13.0'
runtimeOnly "org.glassfish.jaxb:jaxb-runtime:${jaxb_version}"
runtimeOnly 'com.google.j2objc:j2objc-annotations:2.8'
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
Expand All @@ -655,7 +655,7 @@ dependencies {
runtimeOnly 'org.apache.ws.xmlschema:xmlschema-core:2.3.1'
runtimeOnly 'org.apache.santuario:xmlsec:2.3.4'
runtimeOnly "com.github.luben:zstd-jni:${versions.zstd}"
runtimeOnly 'org.checkerframework:checker-qual:3.48.2'
runtimeOnly 'org.checkerframework:checker-qual:3.48.3'
runtimeOnly "org.bouncycastle:bcpkix-jdk18on:${versions.bouncycastle}"
runtimeOnly 'org.scala-lang.modules:scala-java8-compat_3:1.0.2'

Expand Down Expand Up @@ -686,7 +686,7 @@ dependencies {
testImplementation "org.apache.kafka:kafka_2.13:${kafka_version}:test"
testImplementation "org.apache.kafka:kafka-clients:${kafka_version}:test"
testImplementation 'commons-validator:commons-validator:1.9.0'
testImplementation 'org.springframework.kafka:spring-kafka-test:2.9.13'
testImplementation 'org.springframework.kafka:spring-kafka-test:3.3.0'
testImplementation "org.springframework:spring-beans:${spring_version}"
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.3'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3'
Expand Down Expand Up @@ -724,13 +724,13 @@ dependencies {
compileOnly "org.opensearch:opensearch:${opensearch_version}"

//integration test framework:
integrationTestImplementation('com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.1') {
integrationTestImplementation('com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.2') {
exclude(group: 'junit', module: 'junit')
}
integrationTestImplementation 'junit:junit:4.13.2'
integrationTestImplementation "org.opensearch.plugin:reindex-client:${opensearch_version}"
integrationTestImplementation "org.opensearch.plugin:percolator-client:${opensearch_version}"
integrationTestImplementation 'commons-io:commons-io:2.17.0'
integrationTestImplementation 'commons-io:commons-io:2.18.0'
integrationTestImplementation "org.apache.logging.log4j:log4j-core:${versions.log4j}"
integrationTestImplementation "org.apache.logging.log4j:log4j-jul:${versions.log4j}"
integrationTestImplementation 'org.hamcrest:hamcrest:2.2'
Expand All @@ -749,7 +749,7 @@ dependencies {
integrationTestImplementation "org.mockito:mockito-core:5.14.2"

//spotless
implementation('com.google.googlejavaformat:google-java-format:1.24.0') {
implementation('com.google.googlejavaformat:google-java-format:1.25.2') {
exclude group: 'com.google.guava'
}
}
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
8 changes: 8 additions & 0 deletions release-notes/opensearch-security.release-notes-1.3.20.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Version 1.3.20.0

Compatible with OpenSearch 1.3.20

### Maintenance

* Update commons-io to 2.18.0 ([#4944](https://github.com/opensearch-project/security/pull/4944))
* Bump spring-framework dependency to 2.9.13 ([#4947](https://github.com/opensearch-project/security/pull/4947))
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
*/
package org.opensearch.security;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.opensearch.common.xcontent.XContentFactory;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.security.http.ExampleSystemIndexPlugin;
import org.opensearch.test.framework.TestSecurityConfig.AuthcDomain;
import org.opensearch.test.framework.cluster.ClusterManager;
import org.opensearch.test.framework.cluster.LocalCluster;
import org.opensearch.test.framework.cluster.TestRestClient;
import org.opensearch.test.framework.cluster.TestRestClient.HttpResponse;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED;
import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS;
import static org.opensearch.test.framework.TestSecurityConfig.User.USER_ADMIN;

@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class)
@ThreadLeakScope(ThreadLeakScope.Scope.NONE)
public class ThreadPoolTests {

public static final AuthcDomain AUTHC_DOMAIN = new AuthcDomain("basic", 0).httpAuthenticatorWithChallenge("basic").backend("internal");

@ClassRule
public static final LocalCluster cluster = new LocalCluster.Builder().clusterManager(ClusterManager.SINGLENODE)
.anonymousAuth(false)
.authc(AUTHC_DOMAIN)
.users(USER_ADMIN)
.plugin(ExampleSystemIndexPlugin.class)
.nodeSettings(Map.of(SECURITY_RESTAPI_ROLES_ENABLED, List.of("user_" + USER_ADMIN.getName() + "__" + ALL_ACCESS.getName())))
.build();

@Test
public void testEnsureNoThreadLeftRunningInGenericThreadPool() throws IOException, InterruptedException {
try (TestRestClient client = cluster.getRestClient(USER_ADMIN)) {
client.put("test-index");

XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
builder.field("field1", "foo");
builder.endObject();

HttpResponse indexDocResponse = client.putJson("test-index/_doc/1", builder.toString());

assertThat(indexDocResponse.getStatusCode(), equalTo(RestStatus.CREATED.getStatus()));

XContentBuilder updateBuilder = XContentFactory.jsonBuilder();
updateBuilder.startObject();
updateBuilder.startObject("doc");
updateBuilder.field("field1", "bar");
updateBuilder.endObject();
updateBuilder.endObject();

HttpResponse updateDocResponse = client.postJson("test-index/_update/1", updateBuilder.toString());

assertThat(updateDocResponse.getStatusCode(), equalTo(RestStatus.OK.getStatus()));

client.delete("test-index");

Thread.sleep(2000);

HttpResponse hotThreadsResponse = client.get("_nodes/hot_threads");

assertThat(hotThreadsResponse.getBody(), not(containsString("ClusterStateMetadataDependentPrivileges")));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ private AuthCredentials extractCredentials0(final SecurityRequest request) {
}
}
}
log.error("Failed to parse JWT token using any of the available parsers");
log.debug("Unable to authenticate JWT Token with any configured signing key");
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,10 @@
import static org.opensearch.security.setting.DeprecatedSettings.checkForDeprecatedSetting;
import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX;
import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE;
import static org.opensearch.security.support.ConfigConstants.SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED;
import static org.opensearch.security.support.ConfigConstants.SECURITY_SSL_CERT_RELOAD_ENABLED;
import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION;

// CS-ENFORCE-SINGLE

public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin
Expand Down Expand Up @@ -314,7 +317,11 @@ private static boolean useClusterStateToInitSecurityConfig(final Settings settin
* @return true if ssl cert reload is enabled else false
*/
private static boolean isSslCertReloadEnabled(final Settings settings) {
return settings.getAsBoolean(ConfigConstants.SECURITY_SSL_CERT_RELOAD_ENABLED, false);
return settings.getAsBoolean(SECURITY_SSL_CERT_RELOAD_ENABLED, false);
}

private boolean sslCertificatesHotReloadEnabled(final Settings settings) {
return settings.getAsBoolean(SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED, false);
}

@SuppressWarnings("removal")
Expand Down Expand Up @@ -1205,6 +1212,19 @@ public Collection<Object> createComponents(
components.add(passwordHasher);

components.add(sslSettingsManager);
if (isSslCertReloadEnabled(settings) && sslCertificatesHotReloadEnabled(settings)) {
throw new OpenSearchException(
"Either "
+ SECURITY_SSL_CERT_RELOAD_ENABLED
+ " or "
+ SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED
+ " can be set to true, but not both."
);
}

if (sslCertificatesHotReloadEnabled(settings) && !isSslCertReloadEnabled(settings)) {
sslSettingsManager.addSslConfigurationsChangeListener(resourceWatcherService);
}

final var allowDefaultInit = settings.getAsBoolean(SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, false);
final var useClusterState = useClusterStateToInitSecurityConfig(settings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,13 +575,14 @@ public void logDocumentWritten(ShardId shardId, GetResult originalResult, Index
msg.addComplianceDocVersion(result.getVersion());
msg.addComplianceOperation(result.isCreated() ? Operation.CREATE : Operation.UPDATE);

if (complianceConfig.shouldLogDiffsForWrite()
&& originalResult != null
&& originalResult.isExists()
&& originalResult.internalSourceRef() != null) {
if (complianceConfig.shouldLogDiffsForWrite()) {
try {
String originalSource = null;
String currentSource = null;
if (!(originalResult != null && originalResult.isExists() && originalResult.internalSourceRef() != null)) {
// originalSource is empty
originalSource = "{}";
}
if (securityIndicesMatcher.test(shardId.getIndexName())) {
try (
XContentParser parser = XContentHelper.createParser(
Expand Down Expand Up @@ -624,7 +625,9 @@ public void logDocumentWritten(ShardId shardId, GetResult originalResult, Index
);
msg.addSecurityConfigWriteDiffSource(diffnode.size() == 0 ? "" : diffnode.toString(), id);
} else {
originalSource = XContentHelper.convertToJson(originalResult.internalSourceRef(), false, XContentType.JSON);
if (originalSource == null) {
originalSource = XContentHelper.convertToJson(originalResult.internalSourceRef(), false, XContentType.JSON);
}
currentSource = XContentHelper.convertToJson(currentIndex.source(), false, XContentType.JSON);
final JsonNode diffnode = JsonDiff.asJson(
DefaultObjectMapper.objectMapper.readTree(originalSource),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public AuthCredentials run() {

private AuthCredentials extractCredentials0(final SecurityRequest request) {
if (!oboEnabled) {
log.error("On-behalf-of authentication is disabled");
log.debug("On-behalf-of authentication is disabled");
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ protected void updateClusterStateMetadata(Metadata metadata) {
long duration = System.currentTimeMillis() - start;

log.debug("Updating DlsFlsProcessedConfig took {} ms", duration);
this.metadataVersionEffective = metadata.version();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ SslContext buildServerSslContext(final boolean validateCertificates) {
.build()
);
} catch (PrivilegedActionException e) {
throw new OpenSearchException("Filed to build server SSL context", e);
throw new OpenSearchException("Failed to build server SSL context", e);
}
}

Expand All @@ -127,7 +127,7 @@ SslContext buildClientSslContext(final boolean validateCertificates) {
.build()
);
} catch (PrivilegedActionException e) {
throw new OpenSearchException("Filed to build client SSL context", e);
throw new OpenSearchException("Failed to build client SSL context", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import java.util.stream.Stream;
import javax.net.ssl.SSLEngine;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.opensearch.security.ssl.config.Certificate;
import org.opensearch.transport.NettyAllocator;

Expand All @@ -30,6 +33,8 @@

public class SslContextHandler {

private final static Logger LOGGER = LogManager.getLogger(SslContextHandler.class);

private SslContext sslContext;

private final SslConfiguration sslConfiguration;
Expand Down Expand Up @@ -78,7 +83,7 @@ Stream<Certificate> keyMaterialCertificates(final List<Certificate> certificates
return certificates.stream().filter(Certificate::hasKey);
}

void reloadSslContext() throws CertificateException {
boolean reloadSslContext() throws CertificateException {
final var newCertificates = sslConfiguration.certificates();

boolean hasChanges = false;
Expand All @@ -89,11 +94,13 @@ void reloadSslContext() throws CertificateException {
final var newKeyMaterialCertificates = keyMaterialCertificates(newCertificates).collect(Collectors.toList());

if (notSameCertificates(loadedAuthorityCertificates, newAuthorityCertificates)) {
LOGGER.debug("Certification authority has changed");
hasChanges = true;
validateDates(newAuthorityCertificates);
}

if (notSameCertificates(loadedKeyMaterialCertificates, newKeyMaterialCertificates)) {
LOGGER.debug("Key material and access certificate has changed");
hasChanges = true;
validateNewKeyMaterialCertificates(
loadedKeyMaterialCertificates,
Expand All @@ -111,6 +118,7 @@ void reloadSslContext() throws CertificateException {
loadedCertificates.clear();
loadedCertificates.addAll(newCertificates);
}
return hasChanges;
}

private boolean notSameCertificates(final List<Certificate> loadedCertificates, final List<Certificate> newCertificates) {
Expand Down
Loading

0 comments on commit e255e14

Please sign in to comment.