docker-maven-plugin icon indicating copy to clipboard operation
docker-maven-plugin copied to clipboard

Error pushing to GCR with one-lined JSON key as password

Open seboudry opened this issue 7 years ago • 9 comments

Description

Hi! Trying to push to GCR with d-m-p using JSON key mechanism. The JSON key is passed to build using an environment variable, so must be a one-line string. DMP fails to decrypt password, it assumes that's a Maven encrypted password (MavenPlexusCipher matches the one-lined JSON with the Maven password regex).

I filled this issue to record it, but don't know if you can handle a fix into d-m-p for this typical use case.

Info

  • d-m-p version : 0.25.2
  • Maven version (mvn -v) :
[MVNVM] Using maven: 3.5.2
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T09:58:13+02:00)
Maven home: /Users/soudry/.mvnvm/apache-maven-3.5.2
Java version: 1.8.0_172, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre
Default locale: fr_FR, platform encoding: UTF-8
OS name: "mac os x", version: "10.13.4", arch: "x86_64", family: "mac"
  • Docker version : 18.03.1-ce, build 9ee9f40

Reproduce bug

Download a JSON key file from a Google service account. Have no issue with using JSON key file directly:

mvn fabric8:push \
  -Ddocker.push.registry=eu.gcr.io/awesome \
  -Ddocker.push.username=_json_key \
  "-Ddocker.push.password=$(cat keyfile.json)"

Make the JSON key file one-line and export it to an env variable:

jq -c . keyfile.json > keyfile-oneline.json
export GCR_JSONKEY=$(cat keyfile-oneline.json)

Try using this env var:

mvn fabric8:push \
  -Ddocker.push.registry=eu.gcr.io/awesome \
  -Ddocker.push.username=_json_key \
  "-Ddocker.push.password=${GCR_JSONKEY}"

Note that f-m-p as no implication in this bug, all Docker authentication is delegated to d-m-p.

[INFO] --- fabric8-maven-plugin:3.5.39:push (default-cli) @ qs-framework-fabric8-python-samples-echo ---
[INFO] F8> Generators:
[INFO] F8>  - spring-boot
[INFO] F8>  - wildfly-swarm
[INFO] F8>  - karaf
[INFO] F8>  - vertx
[INFO] F8>  - java-exec
[INFO] F8>  - webapp
[ERROR] F8> Cannot decrypt password: org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: org.sonatype.plexus.components.cipher.PlexusCipherException: java.lang.ArrayIndexOutOfBoundsException [null]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.554 s
[INFO] Finished at: 2018-05-28T10:51:05+02:00
[INFO] Final Memory: 87M/743M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.fabric8:fabric8-maven-plugin:3.5.39:push (default-cli) on project qs-framework-fabric8-python-samples-echo: Cannot decrypt password: org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: org.sonatype.plexus.components.cipher.PlexusCipherException: java.lang.ArrayIndexOutOfBoundsException: InvocationTargetException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal io.fabric8:fabric8-maven-plugin:3.5.39:push (default-cli) on project qs-framework-fabric8-python-samples-echo: Cannot decrypt password: org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: org.sonatype.plexus.components.cipher.PlexusCipherException: java.lang.ArrayIndexOutOfBoundsException
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
	at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
	at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
	at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
	at org.apache.maven.cli.MavenCli.execute(MavenCli.java:993)
	at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:345)
	at org.apache.maven.cli.MavenCli.main(MavenCli.java:191)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
	at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
	at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
	at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: Cannot decrypt password: org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: org.sonatype.plexus.components.cipher.PlexusCipherException: java.lang.ArrayIndexOutOfBoundsException
	at io.fabric8.maven.docker.util.AuthConfigFactory.decrypt(AuthConfigFactory.java:445)
	at io.fabric8.maven.docker.util.AuthConfigFactory.getAuthConfigFromSystemProperties(AuthConfigFactory.java:232)
	at io.fabric8.maven.docker.util.AuthConfigFactory.createStandardAuthConfig(AuthConfigFactory.java:186)
	at io.fabric8.maven.docker.util.AuthConfigFactory.createAuthConfig(AuthConfigFactory.java:107)
	at io.fabric8.maven.docker.service.RegistryService.createAuthConfig(RegistryService.java:96)
	at io.fabric8.maven.docker.service.RegistryService.pushImages(RegistryService.java:46)
	at io.fabric8.maven.docker.PushMojo.executeInternal(PushMojo.java:38)
	at io.fabric8.maven.docker.AbstractDockerMojo.execute(AbstractDockerMojo.java:223)
	at io.fabric8.maven.plugin.mojo.build.PushMojo.execute(PushMojo.java:101)
	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
	... 20 more
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at io.fabric8.maven.docker.util.AuthConfigFactory.decrypt(AuthConfigFactory.java:441)
	... 30 more
Caused by: org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: org.sonatype.plexus.components.cipher.PlexusCipherException: java.lang.ArrayIndexOutOfBoundsException
	at org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher.decrypt(DefaultSecDispatcher.java:121)
	... 35 more
Caused by: org.sonatype.plexus.components.cipher.PlexusCipherException: java.lang.ArrayIndexOutOfBoundsException
	at org.sonatype.plexus.components.cipher.PBECipher.decrypt64(PBECipher.java:193)
	at org.sonatype.plexus.components.cipher.DefaultPlexusCipher.decrypt(DefaultPlexusCipher.java:74)
	at org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher.decrypt(DefaultSecDispatcher.java:96)
	... 35 more
Caused by: java.lang.ArrayIndexOutOfBoundsException
	at java.lang.System.arraycopy(Native Method)
	at org.sonatype.plexus.components.cipher.PBECipher.decrypt64(PBECipher.java:181)
	... 37 more

seboudry avatar May 28 '18 09:05 seboudry

So, not working the same way on different environments. On my MacOS workstation, Maven consider the given password great, but on Atlassian Bamboo (same Oracle JDK version, same Maven version but Ubuntu) given password is considered as an encrypted text and all Plexus decrypting runs ... and fails.

edit: working in local, but not un Bamboo: cat command is not interpreted :( ~~Only working way: have to use an intermediate multiline JSON file !~~

printf "%s" "${bamboo.GCR_JSONKEY}" > gcr-keyfile.json
mvn fabric8:push \
  -Ddocker.push.registry=eu.gcr.io/awesome \
  -Ddocker.push.username=_json_key \
  "-Ddocker.push.password=$(cat gcr-keyfile.json)"

Hope this will help anybody

seboudry avatar May 28 '18 13:05 seboudry

DMP don't work with GCR auth keyfile, even with the PR https://github.com/fabric8io/docker-maven-plugin/pull/1036 that don't try to apply Maven decryption on JSON key. I think that method io.fabric8.maven.docker.access.AuthConfig#createAuthEncoded isn't adapted for this kind of GCR authentication.

So my workaround is to not use fmp for only pushing images. Use docker login then docker push with same image name calculated by fmp/dmp.

seboudry avatar Jun 07 '18 13:06 seboudry

Sorry for being so unresponsive, lot of things are going on here. We should definitely fix this, so let me reopen this issue.

rhuss avatar Jun 13 '18 09:06 rhuss

Hi, I'm on vacation until begining of jully. Will take a look at this at my return. Cleaner solution might be to use a specific mecanism as for Amazon registry. To not polute existing code.

seboudry avatar Jun 19 '18 23:06 seboudry

@seboudry let me know when we can tackle this issue.

rhuss avatar Jul 04 '18 15:07 rhuss

A workaround just in case someone else needs it:

mvn fabric8:push  \
	-Ddocker.push.registry=eu.gcr.io/awesome \
	-Ddocker.username=oauth2accesstoken \
	-Ddocker.password=$(gcloud auth print-access-token)

Allsimon avatar Sep 11 '18 10:09 Allsimon

Was this resolved? I am also facing the same issue with version 0.39.1

[INFO] --- docker-maven-plugin:0.39.1:push (default) @ recon-kafka-retry-service ---
[ERROR] DOCKER> Cannot decrypt password: org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: java.io.FileNotFoundException: /var/go/.m2/settings-security.xml (No such file or directory) [null]

ankurga avatar Jul 22 '22 13:07 ankurga

@ankurga I don't think this is the same issue. It looks like that Maven can't find your settings.yml.

rhuss avatar Jul 29 '22 13:07 rhuss

I am working with DMP but included in a pom.xml, as part of the build process. What comes as input to my maven build is a file path ('sa_credentials_file'), the one of the key.json. That file in my case comes as a oneliner so I did hit the problem described here. What I did is to insert a goal right before DMP to basically make the oneliner not to be a oneliner, by replacing the opening brace '{'by '{' + System.getProperty('line.separator'). I did that with a scriptlet in groovy using gmaven-plugin:

<plugin>
	<groupId>org.codehaus.gmaven</groupId>
	<artifactId>gmaven-plugin</artifactId>
	<version>1.5</version>
	<executions>
		<execution>
	<phase>process-resources</phase>
	<goals>
		<goal>execute</goal>
	</goals>
	<configuration>
	    <providerSelection>1.8</providerSelection>
		<source>
		    def newline = System.getProperty('line.separator')
			def file = new File(project.properties.sa_credentials_file) // gcp json credentials
			project.properties.sa_credentials = file.getText().replaceFirst('\{', '\{'+newline)
		</source>
	</configuration>
		</execution>
	</executions>
</plugin>

Then I just use that 'sa_credentials' variable created there to configure DMP:

<authConfig>
	<username>_json_key</username>
	<password>${sa_credentials}</password>
</authConfig>

It doesn't have to be groovy, you can take your pick on how to add that extra newline sequence after the opening brace.

TL;DR: By introducing a single newline char|sequence after the opening brace you will make the credentials text 'fall-off' the regex pattern that makes DMP think that it needs to decrypt something. Other edits might work too.

agustin-eche avatar Jul 26 '23 11:07 agustin-eche