Skip to content

Commit

Permalink
GEODE-9354: Extract and test ArgumentRedactorRegex (#6641) (#6747)
Browse files Browse the repository at this point in the history
* Rename ArgumentRedactorJUnitTest to ArgumentRedactorTest.
* Reorganize and reformat ArgumentRedactor and its tests.
* Fix issues in regex found by new tests.

(cherry picked from commit 693e18c)
  • Loading branch information
kirklund committed Aug 12, 2021
1 parent 4af660d commit b82e282
Show file tree
Hide file tree
Showing 24 changed files with 3,540 additions and 455 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,24 @@

import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER;
import static org.apache.geode.examples.security.ExampleSecurityManager.SECURITY_JSON;
import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
import static org.apache.geode.test.util.ResourceUtils.getResource;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Collection;
import java.util.Properties;
import java.util.Scanner;

import org.apache.commons.io.FileUtils;
import org.assertj.core.api.SoftAssertions;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;

import org.apache.geode.examples.security.ExampleSecurityManager;
import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
import org.apache.geode.test.assertj.LogFileAssert;
import org.apache.geode.test.junit.categories.LoggingTest;
import org.apache.geode.test.junit.categories.SecurityTest;
import org.apache.geode.test.junit.rules.RequiresGeodeHome;
Expand All @@ -53,94 +52,82 @@
@Category({SecurityTest.class, LoggingTest.class})
public class LogsAndDescribeConfigAreFullyRedactedAcceptanceTest {

private static final String sharedPasswordString = "abcdefg";

private File propertyFile;
private File securityPropertyFile;
private static final String PASSWORD = "abcdefg";

@Rule
public RequiresGeodeHome geodeHome = new RequiresGeodeHome();
@Rule
public GfshRule gfsh = new GfshRule();

@Rule
public RequiresGeodeHome geodeHome = new RequiresGeodeHome();
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Before
public void createDirectoriesAndFiles() throws Exception {
propertyFile = gfsh.getTemporaryFolder().newFile("geode.properties");
securityPropertyFile = gfsh.getTemporaryFolder().newFile("security.properties");

Properties properties = new Properties();
properties.setProperty(LOG_LEVEL, "debug");
properties.setProperty("security-username", "propertyFileUser");
properties.setProperty("security-password", sharedPasswordString + "-propertyFile");
try (FileOutputStream fileOutputStream = new FileOutputStream(propertyFile)) {
properties.store(fileOutputStream, null);
File geodePropertiesFile = temporaryFolder.newFile("geode.properties");
File securityPropertiesFile = temporaryFolder.newFile("security.properties");

Properties geodeProperties = new Properties();
geodeProperties.setProperty(LOG_LEVEL, "debug");
geodeProperties.setProperty("security-username", "propertyFileUser");
geodeProperties.setProperty("security-password", PASSWORD + "-propertyFile");

try (FileOutputStream fileOutputStream = new FileOutputStream(geodePropertiesFile)) {
geodeProperties.store(fileOutputStream, null);
}

Properties securityProperties = new Properties();
securityProperties.setProperty(SECURITY_MANAGER, ExampleSecurityManager.class.getName());
securityProperties.setProperty(ExampleSecurityManager.SECURITY_JSON, "security.json");
securityProperties.setProperty(SECURITY_JSON, "security.json");
securityProperties.setProperty("security-file-username", "securityPropertyFileUser");
securityProperties.setProperty("security-file-password",
sharedPasswordString + "-securityPropertyFile");
try (FileOutputStream fileOutputStream = new FileOutputStream(securityPropertyFile)) {
securityProperties.setProperty("security-file-password", PASSWORD + "-securityPropertyFile");

try (FileOutputStream fileOutputStream = new FileOutputStream(securityPropertiesFile)) {
securityProperties.store(fileOutputStream, null);
}

startSecureLocatorAndServer();
}

private void startSecureLocatorAndServer() {
// The json is in the root resource directory.
String securityJson =
getResource(LogsAndDescribeConfigAreFullyRedactedAcceptanceTest.class,
"/security.json").getPath();
// We want to add the folder to the classpath, so we strip off the filename.
securityJson = securityJson.substring(0, securityJson.length() - "security.json".length());
String startLocatorCmd =
new CommandStringBuilder("start locator").addOption("name", "test-locator")
.addOption("properties-file", propertyFile.getAbsolutePath())
.addOption("security-properties-file", securityPropertyFile.getAbsolutePath())
.addOption("J", "-Dsecure-username-jd=user-jd")
.addOption("J", "-Dsecure-password-jd=password-jd")
.addOption("classpath", securityJson).getCommandString();
createFileFromResource(getResource("/security.json"), temporaryFolder.getRoot(),
"security.json");

String startLocatorCmd = new CommandStringBuilder("start locator")
.addOption("name", "test-locator")
.addOption("properties-file", geodePropertiesFile.getAbsolutePath())
.addOption("security-properties-file", securityPropertiesFile.getAbsolutePath())
.addOption("J", "-Dsecure-username-jd=user-jd")
.addOption("J", "-Dsecure-password-jd=password-jd")
.addOption("classpath", temporaryFolder.getRoot().getAbsolutePath())
.getCommandString();

String startServerCmd = new CommandStringBuilder("start server")
.addOption("name", "test-server").addOption("user", "viaStartMemberOptions")
.addOption("password", sharedPasswordString + "-viaStartMemberOptions")
.addOption("properties-file", propertyFile.getAbsolutePath())
.addOption("security-properties-file", securityPropertyFile.getAbsolutePath())
.addOption("name", "test-server")
.addOption("user", "viaStartMemberOptions")
.addOption("password", PASSWORD + "-viaStartMemberOptions")
.addOption("properties-file", geodePropertiesFile.getAbsolutePath())
.addOption("security-properties-file", securityPropertiesFile.getAbsolutePath())
.addOption("J", "-Dsecure-username-jd=user-jd")
.addOption("J", "-Dsecure-password-jd=" + sharedPasswordString + "-password-jd")
.addOption("J", "-Dsecure-password-jd=" + PASSWORD + "-password-jd")
.addOption("server-port", "0")
.addOption("classpath", securityJson).getCommandString();
.addOption("classpath", temporaryFolder.getRoot().getAbsolutePath())
.getCommandString();

gfsh.execute(startLocatorCmd, startServerCmd);
}

@Test
public void logsDoNotContainStringThatShouldBeRedacted() throws FileNotFoundException {
Collection<File> logs =
FileUtils.listFiles(gfsh.getTemporaryFolder().getRoot(), new String[] {"log"}, true);

// Use soft assertions to report all redaction failures, not just the first one.
SoftAssertions softly = new SoftAssertions();
for (File logFile : logs) {
Scanner scanner = new Scanner(logFile);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
softly.assertThat(line).describedAs("File: %s, Line: %s", logFile.getAbsolutePath(), line)
.doesNotContain(sharedPasswordString);
}
public void logsDoNotContainStringThatShouldBeRedacted() {
File dir = gfsh.getTemporaryFolder().getRoot();
File[] logFiles = dir.listFiles((d, name) -> name.endsWith(".log"));

for (File logFile : logFiles) {
LogFileAssert.assertThat(logFile).doesNotContain(PASSWORD);
}
softly.assertAll();
}

@Test
public void describeConfigRedactsJvmArguments() {
String connectCommand = new CommandStringBuilder("connect")
.addOption("user", "viaStartMemberOptions")
.addOption("password", sharedPasswordString + "-viaStartMemberOptions").getCommandString();
.addOption("password", PASSWORD + "-viaStartMemberOptions").getCommandString();

String describeLocatorConfigCommand = new CommandStringBuilder("describe config")
.addOption("hide-defaults", "false").addOption("member", "test-locator").getCommandString();
Expand All @@ -150,6 +137,6 @@ public void describeConfigRedactsJvmArguments() {

GfshExecution execution =
gfsh.execute(connectCommand, describeLocatorConfigCommand, describeServerConfigCommand);
assertThat(execution.getOutputText()).doesNotContain(sharedPasswordString);
assertThat(execution.getOutputText()).doesNotContain(PASSWORD);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.internal.util.redaction;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.RestoreSystemProperties;

import org.apache.geode.internal.logging.Banner;

public class ArgumentRedactorIntegrationTest {

private static final String someProperty = "redactorTest.someProperty";
private static final String somePasswordProperty = "redactorTest.aPassword";
private static final String someOtherPasswordProperty =
"redactorTest.aPassword-withCharactersAfterward";

@Rule
public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();

@Test
public void systemPropertiesGetRedactedInBanner() {
System.setProperty(someProperty, "isNotRedacted");
System.setProperty(somePasswordProperty, "isRedacted");
System.setProperty(someOtherPasswordProperty, "isRedacted");

List<String> args = asList("--user=me", "--password=isRedacted",
"--another-password-for-some-reason =isRedacted", "--yet-another-password = isRedacted",
"--one-more-password isRedacted");

String banner = new Banner().getString(args.toArray(new String[0]));

assertThat(banner).doesNotContain("isRedacted");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ org/apache/geode/internal/shared/TCPSocketOptions
org/apache/geode/internal/statistics/platform/LinuxProcFsStatistics$CPU
org/apache/geode/internal/tcp/VersionedByteBufferInputStream
org/apache/geode/internal/util/concurrent/StoppableReadWriteLock
org/apache/geode/internal/util/redaction/ParserRegex$Group
org/apache/geode/logging/internal/LogMessageRegex$Group
org/apache/geode/logging/internal/log4j/LogWriterLogger
org/apache/geode/logging/internal/spi/LogLevelUpdateOccurs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ private void printSourceSection(ConfigSource source, PrintWriter printWriter) {
attributeValueToPrint = getAttribute(name);
} else if (sourceIsSecured) {
// Never show secure sources
attributeValueToPrint = ArgumentRedactor.redacted;
attributeValueToPrint = ArgumentRedactor.getRedacted();
} else {
// Otherwise, redact based on the key string
attributeValueToPrint =
Expand Down
Loading

0 comments on commit b82e282

Please sign in to comment.