This is an automated email from the ASF dual-hosted git repository. lmccay pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push: new 94b445e KNOX-2469 - Fixing Knox keystore path directory creation for symlinks (#383) 94b445e is described below commit 94b445ea18585f0571e177fba72c1af7560943b1 Author: jameschen1519 <57380512+jameschen1...@users.noreply.github.com> AuthorDate: Sat Nov 21 10:22:15 2020 -0800 KNOX-2469 - Fixing Knox keystore path directory creation for symlinks (#383) * Fixing Knox symlink Co-authored-by: James Chen <jamc...@microsoft.com> --- .../security/impl/DefaultKeystoreService.java | 10 +++-- .../security/impl/DefaultKeystoreServiceTest.java | 52 +++++++++++++++++++++- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java index e814bf9..2ed637a 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java @@ -513,12 +513,14 @@ public class DefaultKeystoreService implements KeystoreService { // Package private for unit test access // We need this to be synchronized to prevent multiple threads from using at once synchronized KeyStore createKeyStore(Path keystoreFilePath, String keystoreType, char[] password) throws KeystoreServiceException { - if (Files.notExists(keystoreFilePath)) { - // Ensure the parent directory exists... - try { + // Ensure the parent directory exists... + // This is symlink safe. + Path parentPath = keystoreFilePath.getParent(); + if (parentPath != null && !Files.isDirectory(parentPath)) { + try{ // This will attempt to create all missing directories. No failures will occur if the // directories already exist. - Files.createDirectories(keystoreFilePath.getParent()); + Files.createDirectories(parentPath); } catch (IOException e) { LOG.failedToCreateKeystore(keystoreFilePath.toString(), keystoreType, e); throw new KeystoreServiceException(e); diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java index c6815b2..85841c3 100644 --- a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java +++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java @@ -287,7 +287,14 @@ public class DefaultKeystoreServiceTest { .andReturn(null) .atLeastOnce(); - replay(keystoreServiceAlt, masterService); + DefaultKeystoreService keystoreServiceSymlink = createMockBuilder(DefaultKeystoreService.class) + .addMockedMethod("getCredentialForCluster", String.class, String.class) + .createMock(); + expect(keystoreServiceSymlink.getCredentialForCluster(eq(AliasService.NO_CLUSTER_NAME), eq(GatewayConfig.DEFAULT_SIGNING_KEYSTORE_PASSWORD_ALIAS))) + .andReturn(null) + .atLeastOnce(); + + replay(keystoreServiceAlt, keystoreServiceSymlink, masterService); Path baseDir = testFolder.newFolder().toPath(); GatewayConfigImpl config = createGatewayConfig(baseDir); @@ -332,13 +339,54 @@ public class DefaultKeystoreServiceTest { testSigningKeystore(keystoreServiceAlt, customFile, customKeyAlias, masterPassword); + /* ******************* + * Test Symlink Parent + */ + String symlinkFileName = "symlink_signing.jks"; + Path symlinkSecurityDir = baseDir.resolve("security").resolve("symlink"); + Path symlinkTarget = baseDir.resolve("symlinkTarget"); + Path symlinkParentLink = symlinkSecurityDir.resolve("keystores"); + + try { + //Creating the real path to symlinkParentLink + Files.createDirectories(symlinkTarget.resolve("keystores")); + } catch (IOException e) { + fail("Unable to create symlink target directory."); + } + + try { + Files.createSymbolicLink(symlinkSecurityDir, symlinkTarget); + } catch (IOException e) { + fail("Unable to create symlink while instantiating keystores."); + } + + Path symlinkFile = symlinkParentLink.resolve(symlinkFileName); + + String symlinkKeyAlias = "symlink_alias"; + + config.set(SIGNING_KEYSTORE_NAME, symlinkFileName); + config.set(SIGNING_KEY_ALIAS, symlinkKeyAlias); + config.set(GatewayConfigImpl.SECURITY_DIR, symlinkSecurityDir.toString()); + + keystoreServiceSymlink.setMasterService(masterService); + + // Ensure the signing keystore exists before init-ing the keystore service + createKeystore(keystoreService, symlinkFile, symlinkKeyAlias, masterPassword); + + keystoreServiceSymlink.init(config, Collections.emptyMap()); + + testSigningKeystore(keystoreServiceSymlink, symlinkFile, symlinkKeyAlias, masterPassword); + + // Verify the keystore passwords are set properly... assertTrue(Files.exists(defaultFile)); assertNotNull(keystoreService.loadKeyStore(defaultFile, "JKS", masterPassword)); assertTrue(Files.exists(customFile)); assertNotNull(keystoreService.loadKeyStore(customFile, "JKS", masterPassword)); + assertTrue(Files.exists(symlinkFile)); + assertNotNull(keystoreService.loadKeyStore(symlinkFile, "JKS", masterPassword)); - verify(keystoreServiceAlt, masterService); + verify(keystoreServiceAlt, keystoreServiceSymlink, masterService); } @Test