Skip to content

Commit

Permalink
Fix secure password generation and use.
Browse files Browse the repository at this point in the history
  • Loading branch information
dstreev committed Jun 1, 2022
1 parent c26afc2 commit 33ad7c5
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 18 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<groupId>com.cloudera.utils.hadoop</groupId>
<artifactId>hms-mirror</artifactId>
<version>1.5.1.6-SNAPSHOT</version>
<version>1.5.1.7-SNAPSHOT</version>
<name>hms-mirror</name>

<url>https://github.com/dstreev/hms_mirror</url>
Expand Down
30 changes: 17 additions & 13 deletions src/main/java/com/cloudera/utils/hadoop/hms/Mirror.java
Original file line number Diff line number Diff line change
Expand Up @@ -432,16 +432,20 @@ public void init(String[] args) {
Cluster cluster = config.getCluster(env);
if (cluster != null) {
HiveServer2Config hiveServer2Config = cluster.getHiveServer2();
Properties props = hiveServer2Config.getConnectionProperties();
String password = props.getProperty("password");
if (password != null) {
try {
String decryptedPassword = protect.decrypt(password);
props.put("password", decryptedPassword);
} catch (Exception e) {
e.printStackTrace();
System.err.println("Issue decrypting password");
System.exit(-1);
// Don't process shadow, transfer clusters.
if (hiveServer2Config != null) {
Properties props = hiveServer2Config.getConnectionProperties();
String password = props.getProperty("password");
if (password != null) {
try {
String decryptedPassword = protect.decrypt(password);
props.put("password", decryptedPassword);
} catch (Exception e) {
config.getErrors().set(MessageCode.PASSWORD_DECRYPT_ISSUE.getCode());
// e.printStackTrace();
System.err.println("Issue decrypting password");
// System.exit(-1);
}
}
}
}
Expand Down Expand Up @@ -1321,7 +1325,7 @@ private Options getOptions() {
"Used this in conjunction with '-pkey' to generate the encrypted password that you'll add to the configs for the JDBC connections.");
pwOption.setRequired(Boolean.FALSE);
pwOption.setArgName("password");
options.addOption(pwOption);
// options.addOption(pwOption);

Option setupOption = new Option("su", "setup", false,
"Setup a default configuration file through a series of questions");
Expand All @@ -1331,13 +1335,13 @@ private Options getOptions() {
"The key used to encrypt / decrypt the cluster jdbc passwords. If not present, the passwords will be processed as is (clear text) from the config file.");
pKeyOption.setRequired(false);
pKeyOption.setArgName("password-key");
// options.addOption(pKeyOption);
options.addOption(pKeyOption);

OptionGroup dbGroup = new OptionGroup();
dbGroup.addOption(dbOption);
dbGroup.addOption(helpOption);
dbGroup.addOption(setupOption);
dbGroup.addOption(pKeyOption);
dbGroup.addOption(pwOption);
dbGroup.setRequired(Boolean.TRUE);
options.addOptionGroup(dbGroup);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,13 @@ && getMigrateACID().isDowngrade()
}

}

if (rtn) {
// Last check for errors.
if (errors.getReturnCode() != 0) {
rtn = Boolean.FALSE;
}
}
return rtn;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public enum MessageCode {
SQL_DISTCP_ACID_W_STORAGE_OPTS (33, "SQL Strategy with `distcp` is only valid for ACID table transfers NOT using " +
"storage options `-is` or `-cs`. `distcp` is NOT required since the data has already been moved while preparing " +
"the ACID table."),
PASSWORD_DECRYPT_ISSUE(34, "Password Decrypt Issue."),
// SQL_DISTCP_ONLY_W_DA_ACID (34, "SQL Strategy with `distcp` is only valid for ACID table transfers. " +
// "Use SCHEMA_ONLY from External and Legacy Managed (Non-Transactional) tables."),

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/cloudera/utils/hadoop/hms/util/Protect.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public String encrypt(String plainText) {
* @param text
* @return plainText
*/
public String decrypt(String text) {
public String decrypt(String text) throws RuntimeException {
String plainText = null;
byte[] ciphertext = DatatypeConverter.parseBase64Binary(text);

Expand All @@ -117,9 +117,9 @@ public String decrypt(String text) {
try {
message = cipher.doFinal(ciphertext);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (BadPaddingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
plainText = new String(message);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,5 +388,4 @@ public void test_so_rdl_leg() {
assertTrue("Return Code Failure: " + rtn + " doesn't match: " + check, rtn == check);
}


}
115 changes: 115 additions & 0 deletions src/test/java/com/cloudera/utils/hadoop/hms/EncryptValidationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright 2021 Cloudera, Inc. All Rights Reserved.
*
* Licensed 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 com.cloudera.utils.hadoop.hms;

import com.cloudera.utils.hadoop.hms.mirror.MessageCode;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;

public class EncryptValidationTest extends MirrorTestBase {
@Before
public void setUp() throws Exception {
super.setUp();
DataState.getInstance().setConfiguration(CDP_ENCRYPT);
if (DataState.getInstance().getPopulate() == null) {
DataState.getInstance().setPopulate(Boolean.FALSE);
}
dataSetup01();
}

@After
public void tearDown() throws Exception {
dataCleanup(Boolean.TRUE);
}

@AfterClass
public static void tearDownClass() throws Exception {
dataCleanup(Boolean.FALSE);
}

@Test
public void test_pkey_test() {
String nameofCurrMethod = new Throwable()
.getStackTrace()[0]
.getMethodName();

String outputDir = outputDirBase + nameofCurrMethod;

String[] args = new String[]{"-pkey", "test",
"-p", "myspecialpassword"};
args = toExecute(args, execArgs, Boolean.FALSE);

long rtn = 0;
Mirror mirror = new Mirror();
rtn = mirror.go(args);
long check = 0;
// MessageCode.RESET_TO_DEFAULT_LOCATION_WITHOUT_WAREHOUSE_DIRS.getLong();

assertTrue("Return Code Failure: " + rtn + " doesn't match: " + check, rtn == check);
}

@Test
public void test_p_test() {
String nameofCurrMethod = new Throwable()
.getStackTrace()[0]
.getMethodName();

String outputDir = outputDirBase + nameofCurrMethod;

String[] args = new String[]{
"-pkey", "test1",
"-db", DataState.getInstance().getWorking_db(),
"-o", outputDir, "-cfg", DataState.getInstance().getConfiguration()};
args = toExecute(args, execArgs, Boolean.FALSE);

long rtn = 0;
Mirror mirror = new Mirror();
rtn = mirror.go(args);
long check = MessageCode.PASSWORD_DECRYPT_ISSUE.getLong();

assertTrue("Return Code Failure: " + rtn + " doesn't match: " + check, rtn == check);
}

@Test
public void test_p_test_02() {
String nameofCurrMethod = new Throwable()
.getStackTrace()[0]
.getMethodName();

String outputDir = outputDirBase + nameofCurrMethod;

String[] args = new String[]{
"-pkey", "test",
"-db", DataState.getInstance().getWorking_db(),
"-o", outputDir, "-cfg", DataState.getInstance().getConfiguration()};
args = toExecute(args, execArgs, Boolean.FALSE);

long rtn = 0;
Mirror mirror = new Mirror();
rtn = mirror.go(args);
long check = MessageCode.PASSWORD_DECRYPT_ISSUE.getLong();

// As long as failure isn't about decrypt.
assertFalse("Return Code Failure: " + rtn + " doesn't match: " + check, rtn == check);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class MirrorTestBase {
protected static final String HDP2_CDP = "default.yaml.hdp2-cdp";
protected static final String CDP_CDP = "default.yaml.cdp-cdp";
protected static final String CDP = "default.yaml.cdp";
protected static final String CDP_ENCRYPT = "default.yaml.cdp.encrypted";
protected static final String CDP_HDP2 = "default.yaml.cdp-hdp2";

protected static final String[] execArgs = {"-e", "--accept"};
Expand Down

0 comments on commit 33ad7c5

Please sign in to comment.