Skip to content

Commit 65df90c

Browse files
authored
Merge pull request #40 from sophiegreen/master
Store password as char arrays
2 parents a79e43a + 93d6782 commit 65df90c

File tree

3 files changed

+53
-39
lines changed

3 files changed

+53
-39
lines changed

src/main/java/com/ibm/cics/bundle/deploy/BundleDeployHelper.java

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public class BundleDeployHelper {
5151

5252
private static final String AUTHORIZATION_HEADER = "Authorization";
5353

54-
public static void deployBundle(URI endpointURL, File bundle, String bunddef, String csdgroup, String cicsplex, String region, String username, String password, boolean allowSelfSignedCertificate) throws BundleDeployException, IOException {
54+
public static void deployBundle(URI endpointURL, File bundle, String bunddef, String csdgroup, String cicsplex, String region, String username, char[] password, boolean allowSelfSignedCertificate) throws BundleDeployException, IOException {
5555
MultipartEntityBuilder mpeb = MultipartEntityBuilder.create();
5656
mpeb.addPart("bundle", new FileBody(bundle, ContentType.create("application/zip")));
5757
mpeb.addPart("bunddef", new StringBody(bunddef, ContentType.TEXT_PLAIN));
@@ -103,9 +103,8 @@ public static void deployBundle(URI endpointURL, File bundle, String bunddef, St
103103
}
104104
}
105105

106-
107-
108-
String credentials = username + ":" + password;
106+
String stringPassword = (password == null || password.length == 0) ? null : String.valueOf(password);
107+
String credentials = username + ":" + stringPassword;
109108
String encoding = Base64.getEncoder().encodeToString(credentials.getBytes());
110109
httpPost.setHeader(AUTHORIZATION_HEADER, "Basic " + encoding);
111110

@@ -127,31 +126,35 @@ public static void deployBundle(URI endpointURL, File bundle, String bunddef, St
127126

128127
if (responseStatus.getStatusCode() != 200) {
129128
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
130-
String responseContent = bufferedReader.lines().collect(Collectors.joining());
131-
if (contentType == null) {
132-
throw new BundleDeployException("Http response: " + responseStatus);
133-
} else if (contentType.equals("application/xml")) {
134-
//liberty level error
135-
throw new BundleDeployException(responseContent);
136-
} else if (contentType.equals("application/json")) {
137-
//error from deploy endpoint
138-
ObjectMapper objectMapper = new ObjectMapper();
139-
String responseMessage = objectMapper.readTree(responseContent).get("message").asText();
140-
String responseErrors = "";
141-
142-
if (responseMessage.contains("Some of the supplied parameters were invalid")) {
143-
Iterator<Entry<String, JsonNode>> errorFields = objectMapper.readTree(responseContent).get("requestErrors").fields();
144-
while (errorFields.hasNext()) {
145-
Entry<String, JsonNode> errorField = errorFields.next();
146-
responseErrors += errorField.getKey() + ": " + errorField.getValue().asText() + "\n";
129+
try {
130+
String responseContent = bufferedReader.lines().collect(Collectors.joining());
131+
if (contentType == null) {
132+
throw new BundleDeployException("Http response: " + responseStatus);
133+
} else if (contentType.equals("application/xml")) {
134+
//liberty level error
135+
throw new BundleDeployException(responseContent);
136+
} else if (contentType.equals("application/json")) {
137+
//error from deploy endpoint
138+
ObjectMapper objectMapper = new ObjectMapper();
139+
String responseMessage = objectMapper.readTree(responseContent).get("message").asText();
140+
String responseErrors = "";
141+
142+
if (responseMessage.contains("Some of the supplied parameters were invalid")) {
143+
Iterator<Entry<String, JsonNode>> errorFields = objectMapper.readTree(responseContent).get("requestErrors").fields();
144+
while (errorFields.hasNext()) {
145+
Entry<String, JsonNode> errorField = errorFields.next();
146+
responseErrors += errorField.getKey() + ": " + errorField.getValue().asText() + "\n";
147+
}
148+
} else if (responseMessage.contains("Bundle deployment failure")) {
149+
responseErrors = objectMapper.readTree(responseContent).get("deployments").findValue("message").asText();
147150
}
148-
} else if (responseMessage.contains("Bundle deployment failure")) {
149-
responseErrors = objectMapper.readTree(responseContent).get("deployments").findValue("message").asText();
151+
throw new BundleDeployException(responseMessage + ":\n - " + responseErrors);
152+
} else {
153+
//CICS level error
154+
throw new BundleDeployException(responseContent);
150155
}
151-
throw new BundleDeployException(responseMessage + ":\n - " + responseErrors);
152-
} else {
153-
//CICS level error
154-
throw new BundleDeployException(responseContent);
156+
} finally {
157+
bufferedReader.close();
155158
}
156159
}
157160
}

src/main/java/com/ibm/cics/bundle/deploy/BundleDeployer.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static void main(String[] args) {
3030
String cicsplex = args[4];
3131
String region = args[5];
3232
String username = args[6];
33-
String password = args[7];
33+
char[] password = getPasswordAsChars(args[7]);
3434
boolean allowSelfSignedCertificate = Boolean.parseBoolean(args[8]);
3535

3636
try {
@@ -45,7 +45,18 @@ public static void main(String[] args) {
4545
System.err.println("IO Exception: " + e.getMessage());
4646
}
4747

48-
48+
}
49+
50+
/*
51+
* Current best practice is to avoid putting strings containing passwords onto
52+
* the heap or interning the strings containing them, hence using char[] where possible
53+
*/
54+
public static char[] getPasswordAsChars(String password) {
55+
if (password != null && !password.isEmpty()) {
56+
return password.toCharArray();
57+
} else {
58+
return new char[0];
59+
}
4960
}
5061

5162
}

src/test/java/com/ibm/cics/bundle/deploy/BundleDeployHelperTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void testBundleDeployHelper_response200() throws Exception {
5555

5656
File bundleArchive = new File(bundleFilePath);
5757

58-
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password", true);
58+
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password".toCharArray(), true);
5959
}
6060

6161
@Test
@@ -71,7 +71,7 @@ public void testBundleDeployHelper_selfSignedNotValid() throws Exception {
7171
File bundleArchive = new File(bundleFilePath);
7272

7373
try {
74-
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password", false);
74+
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password".toCharArray(), false);
7575
fail("Expected SSLException because self signed certificates are not allowed");
7676
} catch (SSLException e) {
7777
// pass
@@ -93,7 +93,7 @@ public void testBundleDeployHelper_invalidFile() throws Exception {
9393
expectedException.expect(BundleDeployException.class);
9494
expectedException.expectMessage("Bundle does not exist: 'invalid path'");
9595

96-
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password", true);
96+
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password".toCharArray(), true);
9797
}
9898

9999
@Test
@@ -111,7 +111,7 @@ public void testBundleDeployHelper_invalidBundle() throws Exception {
111111
expectedException.expect(BundleDeployException.class);
112112
expectedException.expectMessage("Some of the supplied parameters were invalid:\n - bundle: Derived bundledir \"" + bundleFilePath + "\" didn't match the target BUNDDEF's bundle dir \"" + bundleFilePath + "\"\n");;
113113

114-
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password", true);
114+
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password".toCharArray(), true);
115115
}
116116

117117
@Test
@@ -129,7 +129,7 @@ public void testBundleDeployHelper_unauthenticated401() throws Exception {
129129
expectedException.expect(BundleDeployException.class);
130130
expectedException.expectMessage("Http response: HTTP/1.1 401 Unauthorized");
131131

132-
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password", true);
132+
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password".toCharArray(), true);
133133
}
134134

135135
@Test
@@ -146,7 +146,7 @@ public void testBundleDeployHelper_unauthenticated401_noContentType() throws Exc
146146
expectedException.expect(BundleDeployException.class);
147147
expectedException.expectMessage("Http response: HTTP/1.1 401 Unauthorized");
148148

149-
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password", true);
149+
BundleDeployHelper.deployBundle(new URI(wireMockRule.baseUrl()), bundleArchive, "bundle", "csdgroup", "cicsplex", "region", "username", "password".toCharArray(), true);
150150
}
151151

152152
@Test
@@ -169,7 +169,7 @@ public void noPath() throws Exception {
169169
"cicsplex",
170170
"region",
171171
"username",
172-
"password",
172+
"password".toCharArray(),
173173
true
174174
);
175175
}
@@ -195,7 +195,7 @@ public void noPathSlash() throws Exception {
195195
"cicsplex",
196196
"region",
197197
"username",
198-
"password",
198+
"password".toCharArray(),
199199
true
200200
);
201201
}
@@ -221,7 +221,7 @@ public void pathNoSlash() throws Exception {
221221
"cicsplex",
222222
"region",
223223
"username",
224-
"password",
224+
"password".toCharArray(),
225225
true
226226
);
227227
}
@@ -247,7 +247,7 @@ public void pathEndsWithSlash() throws Exception {
247247
"cicsplex",
248248
"region",
249249
"username",
250-
"password",
250+
"password".toCharArray(),
251251
true
252252
);
253253
}

0 commit comments

Comments
 (0)