You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ol...@apache.org on 2021/05/27 16:58:20 UTC
[sling-org-apache-sling-commons-crypto] 01/03: SLING-10430 Add fix
for POSIX newline in password files
This is an automated email from the ASF dual-hosted git repository.
olli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-crypto.git
commit abce0d2499730ba0fff31e13c240bf6718e35180
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Thu May 27 18:56:29 2021 +0200
SLING-10430 Add fix for POSIX newline in password files
---
pom.xml | 6 ++
.../crypto/internal/FilePasswordProvider.java | 22 +++--
.../FilePasswordProviderConfiguration.java | 6 ++
.../crypto/internal/FilePasswordProviderTest.java | 109 +++++++++++++++++++++
src/test/resources/password.ascii85_newline | 1 +
src/test/resources/password.ascii85_newlines | 2 +
6 files changed, 139 insertions(+), 7 deletions(-)
diff --git a/pom.xml b/pom.xml
index 44c6285..dbdd33c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -222,6 +222,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>3.10.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>
<version>1.2.0</version>
diff --git a/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProvider.java b/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProvider.java
index 6428c5e..26ed9b0 100644
--- a/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProvider.java
+++ b/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProvider.java
@@ -50,38 +50,46 @@ public class FilePasswordProvider implements PasswordProvider {
private FilePasswordProviderConfiguration configuration;
+ private static final char NEWLINE_CHARACTER = '\n';
+
private final Logger logger = LoggerFactory.getLogger(FilePasswordProvider.class);
public FilePasswordProvider() {
}
@Activate
- private void activate(final FilePasswordProviderConfiguration configuration) throws IOException {
+ protected void activate(final FilePasswordProviderConfiguration configuration) throws IOException {
logger.debug("activating");
this.configuration = configuration;
checkConfiguration();
}
@Modified
- private void modified(final FilePasswordProviderConfiguration configuration) throws IOException {
+ protected void modified(final FilePasswordProviderConfiguration configuration) throws IOException {
logger.debug("modifying");
this.configuration = configuration;
checkConfiguration();
}
@Deactivate
- private void deactivate() {
+ protected void deactivate() {
logger.debug("deactivating");
this.configuration = null;
}
- private char[] readPassword(final String path) throws IOException {
+ private char[] readPassword(final String path, final boolean fixPosixNewline) throws IOException {
final File file = new File(path);
final char[] buffer = new char[(int) file.length()];
try (final BufferedReader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
final int size = reader.read(buffer);
- final char[] password = new char[size];
- System.arraycopy(buffer, 0, password, 0, size);
+ final int length;
+ if (fixPosixNewline && buffer[size - 1] == NEWLINE_CHARACTER) {
+ length = size - 1;
+ } else {
+ length = size;
+ }
+ final char[] password = new char[length];
+ System.arraycopy(buffer, 0, password, 0, length);
Arrays.fill(buffer, '0');
return password;
}
@@ -99,7 +107,7 @@ public class FilePasswordProvider implements PasswordProvider {
@Override
public char @NotNull [] getPassword() {
try {
- return readPassword(configuration.path());
+ return readPassword(configuration.path(), configuration.fix_posixNewline());
} catch (IOException e) {
throw new RuntimeException(e);
}
diff --git a/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProviderConfiguration.java b/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProviderConfiguration.java
index cefdfbe..e529b7f 100644
--- a/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProviderConfiguration.java
+++ b/src/main/java/org/apache/sling/commons/crypto/internal/FilePasswordProviderConfiguration.java
@@ -40,6 +40,12 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition;
)
String path();
+ @AttributeDefinition(
+ name = "Fix POSIX newline",
+ description = "ignores the very last newline character from file content for password"
+ )
+ boolean fix_posixNewline() default false;
+
String webconsole_configurationFactory_nameHint() default "{names} {path}";
}
diff --git a/src/test/java/org/apache/sling/commons/crypto/internal/FilePasswordProviderTest.java b/src/test/java/org/apache/sling/commons/crypto/internal/FilePasswordProviderTest.java
new file mode 100644
index 0000000..5510451
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/crypto/internal/FilePasswordProviderTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.sling.commons.crypto.internal;
+
+import java.io.IOException;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.ops4j.pax.exam.util.PathUtils;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FilePasswordProviderTest {
+
+ private static final char[] PASSWORD_ASCII = "+AQ?aDes!'DBMkrCi:FE6q\\sOn=Pbmn=PK8n=PK?".toCharArray();
+
+ private static final char[] PASSWORD_ASCII_NEWLINE = "+AQ?aDes!'DBMkrCi:FE6q\\sOn=Pbmn=PK8n=PK?\n".toCharArray();
+
+ private static final char[] PASSWORD_ASCII_NEWLINES = "+AQ?aDes!'DBMkrCi:FE6q\\sOn=Pbmn=PK8n=PK?\n\n".toCharArray();
+
+ private static final char[] PASSWORD_UTF8 = " Napøleøn Sølø (DK) \uD83C\uDFC1\uD83C\uDDE9\uD83C\uDDF0".toCharArray();
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void testComponentLifecycle() throws IOException {
+ final FilePasswordProvider provider = new FilePasswordProvider();
+ { // activate
+ final String path = String.format("%s/src/test/resources/password.ascii85", PathUtils.getBaseDir());
+ final FilePasswordProviderConfiguration configuration = mock(FilePasswordProviderConfiguration.class);
+ when(configuration.path()).thenReturn(path);
+ provider.activate(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_ASCII);
+ }
+ { // modified
+ final String path = String.format("%s/src/test/resources/password.utf8", PathUtils.getBaseDir());
+ final FilePasswordProviderConfiguration configuration = mock(FilePasswordProviderConfiguration.class);
+ when(configuration.path()).thenReturn(path);
+ provider.modified(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_UTF8);
+ }
+ }
+
+ @Test
+ public void testPasswordFile() throws IOException {
+ final FilePasswordProvider provider = new FilePasswordProvider();
+ final String path = String.format("%s/src/test/resources/password.ascii85", PathUtils.getBaseDir());
+ final FilePasswordProviderConfiguration configuration = mock(FilePasswordProviderConfiguration.class);
+ when(configuration.path()).thenReturn(path);
+ when(configuration.fix_posixNewline()).thenReturn(false);
+ provider.activate(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_ASCII);
+ // enable fix for POSIX newline
+ when(configuration.fix_posixNewline()).thenReturn(true);
+ provider.modified(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_ASCII);
+ }
+
+ @Test
+ public void testPasswordFileWithNewline() throws IOException {
+ final FilePasswordProvider provider = new FilePasswordProvider();
+ final String path = String.format("%s/src/test/resources/password.ascii85_newline", PathUtils.getBaseDir());
+ final FilePasswordProviderConfiguration configuration = mock(FilePasswordProviderConfiguration.class);
+ when(configuration.path()).thenReturn(path);
+ when(configuration.fix_posixNewline()).thenReturn(false);
+ provider.activate(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_ASCII_NEWLINE);
+ // enable fix for POSIX newline
+ when(configuration.fix_posixNewline()).thenReturn(true);
+ provider.modified(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_ASCII);
+ }
+
+ @Test
+ public void testPasswordFileWithNewlines() throws IOException {
+ final FilePasswordProvider provider = new FilePasswordProvider();
+ final String path = String.format("%s/src/test/resources/password.ascii85_newlines", PathUtils.getBaseDir());
+ final FilePasswordProviderConfiguration configuration = mock(FilePasswordProviderConfiguration.class);
+ when(configuration.path()).thenReturn(path);
+ when(configuration.fix_posixNewline()).thenReturn(false);
+ provider.activate(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_ASCII_NEWLINES);
+ // enable fix for POSIX newline
+ when(configuration.fix_posixNewline()).thenReturn(true);
+ provider.modified(configuration);
+ assertThat(provider.getPassword()).isEqualTo(PASSWORD_ASCII_NEWLINE);
+ }
+
+}
diff --git a/src/test/resources/password.ascii85_newline b/src/test/resources/password.ascii85_newline
new file mode 100644
index 0000000..8884d75
--- /dev/null
+++ b/src/test/resources/password.ascii85_newline
@@ -0,0 +1 @@
++AQ?aDes!'DBMkrCi:FE6q\sOn=Pbmn=PK8n=PK?
diff --git a/src/test/resources/password.ascii85_newlines b/src/test/resources/password.ascii85_newlines
new file mode 100644
index 0000000..e33e3c4
--- /dev/null
+++ b/src/test/resources/password.ascii85_newlines
@@ -0,0 +1,2 @@
++AQ?aDes!'DBMkrCi:FE6q\sOn=Pbmn=PK8n=PK?
+