Skip to content

Commit

Permalink
SECURITY-836 store secret on disk in encrypted form
Browse files Browse the repository at this point in the history
  • Loading branch information
dalvizu committed Apr 17, 2019
1 parent ecce81c commit e252f40
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 8 deletions.
27 changes: 27 additions & 0 deletions src/main/java/org/jenkinsci/plugins/jiraext/Config.java
Expand Up @@ -22,6 +22,7 @@
import hudson.model.Job;
import hudson.model.JobProperty;
import hudson.model.JobPropertyDescriptor;
import hudson.util.Secret;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
Expand Down Expand Up @@ -61,7 +62,12 @@ public static final class PluginDescriptor

private String jiraBaseUrl;
private String username;

// SECURITY-836 this stores in plaintext on disk -- keep around so we can move this to
// correct encrypted field
private String password;
private Secret encryptedPassword;

private String pattern;
private boolean verboseLogging;
private Integer timeout;
Expand All @@ -78,6 +84,10 @@ public Object readResolve()
{
timeout = 10;
}
if (StringUtils.isNotEmpty(password)) {
this.encryptedPassword = Secret.fromString(password);
this.password = null;
}
return this;
}

Expand Down Expand Up @@ -107,16 +117,33 @@ public void setUsername(String username)
this.username = username;
}

@Deprecated
/**
* @deprecated do not use - this stores password in plaintext: SECURITY-836
*/
public String getPassword()
{
return password;
}

@Deprecated
/**
* @deprecated do not use - this stores password in plaintext: SECURITY-836
*/
public void setPassword(String password)
{
this.password = password;
}

public Secret getEncryptedPassword()
{
return encryptedPassword;
}

public void setEncryptedPassword(Secret encryptedPassword)
{
this.encryptedPassword = encryptedPassword;
}
public String getPattern()
{
return pattern;
Expand Down
Expand Up @@ -41,7 +41,7 @@ public JiraClient newJiraClient()
Config.PluginDescriptor config = Config.getGlobalConfig();
String jiraUrl = config.getJiraBaseUrl();
String username = config.getUsername();
String password = config.getPassword();
String password = config.getEncryptedPassword() == null ? null : config.getEncryptedPassword().getPlainText();

BasicCredentials creds = new BasicCredentials(username, password);
JiraClient client = new JiraClient(jiraUrl, creds);
Expand Down
Expand Up @@ -5,22 +5,22 @@
<f:section title="jira-ext Config">

<f:entry title="JIRA Base URL" field="jiraBaseUrl"
description="The base URL of Jira server, not ending with slash">
description="The base URL of JIRA server, not ending with slash">
<f:textbox />
</f:entry>
<f:entry title="JIRA Username" field="username"
description="The Jira bot username">
description="Username of a JIRA user, used in API requests as HTTP Basic Authentication">
<f:textbox />
</f:entry>
<f:entry title="JIRA Password">
<f:password field="password" description="The Jira bot password"/>
<f:password field="password" description="Password of a JIRA user, used in API requests as HTTP Basic Authentication"/>
</f:entry>
<f:entry title="Ticket Pattern" field="pattern"
description="Comma-separate string of jira prefixes">
description="Comma-separate string of JIRA prefixes">
<f:textbox default="FOO-,BAR-" />
</f:entry>
<f:entry title="Verbose Logging" field="verboseLogging"
description="Whether to log a lot of information, ie API http debugging, in jobs">
description="Whether to log a lot of information, ie API HTTP debugging, in jobs">
<f:checkbox />
</f:entry>
<f:entry title="Timeout" field="timeout" description="Connection and socket timeout value, in seconds">
Expand Down
22 changes: 20 additions & 2 deletions src/test/java/org/jenkinsci/plugins/jiraext/ConfigTest.java
Expand Up @@ -18,12 +18,15 @@
**************************************************************************/
package org.jenkinsci.plugins.jiraext;

import hudson.util.Secret;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

import static org.junit.Assert.*;

/**
* @author dalvizu
*/
Expand Down Expand Up @@ -52,11 +55,26 @@ public void testSaveConfig()
Config.PluginDescriptor before = Config.getGlobalConfig();
before.setPattern("FOO-");
before.setUsername("username");
before.setPassword("password");
before.setEncryptedPassword(Secret.fromString("password"));
before.setVerboseLogging(true);
jenkinsRule.configRoundtrip();
Config.PluginDescriptor after = Config.getGlobalConfig();
jenkinsRule.assertEqualBeans(before, after, "jiraBaseUrl,username,password,pattern,verboseLogging");
jenkinsRule.assertEqualBeans(before, after, "jiraBaseUrl,username,encryptedPassword,pattern,verboseLogging");
}

@Test
@SuppressWarnings("deprecation")
public void testMigrationToEncryptedPassword()
throws Exception
{
Config.PluginDescriptor config = Config.getGlobalConfig();
config.setPattern("FOO-");
config.setUsername("username");
config.setPassword("password");
config.setVerboseLogging(true);
config.readResolve();
assertNull(config.getPassword());
assertEquals("password", config.getEncryptedPassword().getPlainText());

}

Expand Down

0 comments on commit e252f40

Please sign in to comment.