6

I would like to use Maven's password encryption such as it uses for nodes for properties of a Mojo. I tried just pasting an encrypted password into the correct property for the mojo, but it treated it as plain text. I was hoping there was an attribute I could set on the annotation for the Mojo property that would explain that it could be encrypted, and if so, to use the system master password to decrypt, but I don't see anything in the documentation for that.

Has anybody managed to use Maven's password encryption for anything other than server password nodes? Would love to make this work for my Mojo.

Colselaw
  • 1,069
  • 9
  • 21

4 Answers4

4

Not a complete answer, but hopefully a pointer in the right direction...

The maven-scm-plugin, maven-release-plugin, and tomcat6-maven-plugin all allow for reading passwords from the <servers> section of the ${user.home}/.m2/settings.xml file.

Perhaps if you look at the source code for those plugins/goals, you will find a Maven core or shared component that allows you to do what you want, and you may adapt it for your needs.

user944849
  • 14,524
  • 2
  • 61
  • 83
  • Wow! Thanks @user944849! It took a bit of digging, but starting from maven-scm-plugin did the trick. The source for it is not that complicated - if you're using Maven 2, you include a Plexus component which does the decrypting for you. – Colselaw Jan 05 '13 at 00:36
2

@user944849 got me started in the right direction, and here's the solution.

If you're using Maven 2, you need to add the following dependency to your mojo:

<dependency>
  <groupId>org.sonatype.plexus</groupId>
  <artifactId>plexus-sec-dispatcher</artifactId>
  <version>1.4</version>
  <scope>compile</scope>
</dependency>

And put the following in src/main/resources/META-INF/plexus/components.xml:

<?xml version="1.0" encoding="utf-8" ?>
<component-set>
  <components>
    <component>
      <role>org.sonatype.plexus.components.sec.dispatcher.SecDispatcher</role>
      <role-hint>mng-4384</role-hint>
      <implementation>org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher</implementation>
      <requirements>
        <requirement>
          <role>org.sonatype.plexus.components.cipher.PlexusCipher</role>
          <role-hint>mng-4384</role-hint>
          <field-name>_cipher</field-name>
        </requirement>
      </requirements>
      <configuration>
        <_configuration-file>~/.m2/settings-security.xml</_configuration-file>
      </configuration>
    </component>
    <component>
      <role>org.sonatype.plexus.components.cipher.PlexusCipher</role>
      <role-hint>mng-4384</role-hint>
      <implementation>org.sonatype.plexus.components.cipher.DefaultPlexusCipher</implementation>
    </component>
  </components>
</component-set>

Then in your Mojo, get the password as an ordinary property, and a SecDispatcher as a component with the same roleHint. The decrypt method on the String will return the string itself if it's not a Maven encrypted string.

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;

/**
 * @goal echopass
 * 
 * @phase process-sources
 */
public class MyMojo extends AbstractMojo {
  /**
  * The password
  * @parameter expression="${password}"
  */
  private String password;

  /**
   * Plexus component for the SecDispatcher
   * @component roleHint="mng-4384"
   */
  private SecDispatcher secDispatcher;

  private String decrypt(String input) {
    try {
      return secDispatcher.decrypt(input);
    } catch (SecDispatcherException sde) {
      getLog().warn(sde.getMessage());
      return input;
    }
  }

  public void execute() throws MojoExecutionException {
    String s = decrypt(password);
    getLog().info("The password is " + s);
  }
}

The string can be in a property in settings.xml, in a Profile, or you can even pass an encrypted string as a system property on the command-line.

References:

Colselaw
  • 1,069
  • 9
  • 21
  • I'm dealing with this issue and could use some assistance. I am getting a null pointer exception on my secDispatcher. You say to "SecDispatcher as a component with the same roleHint." Do I define this in the pom of the project using my plugin? Would you happen to still have the pom from this project? Thanks. – PandaBearSoup Jun 20 '14 at 14:51
1

Take a look at this code as a sample SqlExecMojo. If you are in a plugin you can get the password and decrypt it. If you want to use it for filtering properties in the resource plugin we would probably need to write a custom version of the resources plugin. I have a similar problem may end up doing this.

Kariem
  • 4,398
  • 3
  • 44
  • 73
Usman Ismail
  • 17,999
  • 14
  • 83
  • 165
0

Using Colselaws solution I was getting a null pointer exception. The SecDispatcher component was not being set. I needed to change the annotation to this:

//Plexus component for the SecDispatcher
@Component(role = SecDispatcher.class, hint = "mng-4384")
private SecDispatcher secDispatcher;

Note that this is outside any doc comment and Component must be imported from the maven annotations plugin.

PandaBearSoup
  • 699
  • 3
  • 9
  • 20