diff --git a/src/main/java/org/jenkinsci/plugins/jiraext/Config.java b/src/main/java/org/jenkinsci/plugins/jiraext/Config.java index bc5922b..8f1c24d 100644 --- a/src/main/java/org/jenkinsci/plugins/jiraext/Config.java +++ b/src/main/java/org/jenkinsci/plugins/jiraext/Config.java @@ -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; @@ -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; @@ -78,6 +84,10 @@ public Object readResolve() { timeout = 10; } + if (StringUtils.isNotEmpty(password)) { + this.encryptedPassword = Secret.fromString(password); + this.password = null; + } return this; } @@ -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; diff --git a/src/main/java/org/jenkinsci/plugins/jiraext/svc/impl/JiraClientFactoryImpl.java b/src/main/java/org/jenkinsci/plugins/jiraext/svc/impl/JiraClientFactoryImpl.java index ff11a0c..fca1452 100644 --- a/src/main/java/org/jenkinsci/plugins/jiraext/svc/impl/JiraClientFactoryImpl.java +++ b/src/main/java/org/jenkinsci/plugins/jiraext/svc/impl/JiraClientFactoryImpl.java @@ -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); diff --git a/src/main/resources/org/jenkinsci/plugins/jiraext/Config/global.jelly b/src/main/resources/org/jenkinsci/plugins/jiraext/Config/global.jelly index 2b2f849..0ce0328 100644 --- a/src/main/resources/org/jenkinsci/plugins/jiraext/Config/global.jelly +++ b/src/main/resources/org/jenkinsci/plugins/jiraext/Config/global.jelly @@ -5,22 +5,22 @@ + description="The base URL of JIRA server, not ending with slash"> + description="Username of a JIRA user, used in API requests as HTTP Basic Authentication"> - + + description="Comma-separate string of JIRA prefixes"> + description="Whether to log a lot of information, ie API HTTP debugging, in jobs"> diff --git a/src/test/java/org/jenkinsci/plugins/jiraext/ConfigTest.java b/src/test/java/org/jenkinsci/plugins/jiraext/ConfigTest.java index a00b845..fee73e9 100644 --- a/src/test/java/org/jenkinsci/plugins/jiraext/ConfigTest.java +++ b/src/test/java/org/jenkinsci/plugins/jiraext/ConfigTest.java @@ -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 */ @@ -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()); }