Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-63146

Pipeline Clone fails on zOS with SSH Key-pair with Passphrase

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Blocker Blocker
    • git-client-plugin
    • Jenkins:2.222.3
      git-client: 3.3.1
      git-plugin: 4.3.0
      z/OS R2.4
      git 2.14
    • 3.4.0

      When attempting to clone a repository using an SSH key-pair in a pipeline, the clone fails with
      Permission denied (publickey).
      if the key has a passphrase. The authentication succeeds if there is no passphrase. Various encodings have been attempted to get past this, including utf8, ISO8859-1, and IBM-1047.

      We are using an SSH Agent as a workaround for the time being, but that requires manually modifying the git configuration in new workspaces.

          [JENKINS-63146] Pipeline Clone fails on zOS with SSH Key-pair with Passphrase

          Mark Waite added a comment -

          Thanks for the report and good luck with your investigation. I don't have access to z/OS so can only offer to code review proposed changes. Refer to the CredentialsTest in git client plugin if you'd like an automated test environment that can check passphrase protected private keys.

          Mark Waite added a comment - Thanks for the report and good luck with your investigation. I don't have access to z/OS so can only offer to code review proposed changes. Refer to the CredentialsTest in git client plugin if you'd like an automated test environment that can check passphrase protected private keys.

          Thanks. Any pointers on where the passphrase is passed in? I'm guessing this is an encoding issue. The credentials comes from a controller on x86 Gentoo Docker image of Jenkins, going to a z/OS agent. I'm not at all sure what happens with all the if (isZos()) { code branches. Sadly, this is not my native platform either, but I do have a machine on which I can try to debug the agent (with difficulty).

          Randall Becker added a comment - Thanks. Any pointers on where the passphrase is passed in? I'm guessing this is an encoding issue. The credentials comes from a controller on x86 Gentoo Docker image of Jenkins, going to a z/OS agent. I'm not at all sure what happens with all the if (isZos()) { code branches. Sadly, this is not my native platform either, but I do have a machine on which I can try to debug the agent (with difficulty).

          Mark Waite added a comment -

          Mark Waite added a comment - Search for the 'passphrase' in git-client-plugin. https://github.com/jenkinsci/git-client-plugin/blob/eeec334af0b6447f3db9fb88d55728911a092d73/src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java#L1962

          I am not sure about the line at 2167:

          try (PrintWriter w = new PrintWriter(passphraseFile, "UTF-8")) {
             w.println(Secret.toString(sshUser.getPassphrase()));

          }

          On the zOS machine, I think the passphrase file needs to be encoded in IBM-1047. I will verify with my contacts at IBM on this.

          Randall Becker added a comment - I am not sure about the line at 2167: try (PrintWriter w = new PrintWriter(passphraseFile, "UTF-8")) {    w.println(Secret.toString(sshUser.getPassphrase())); } On the zOS machine, I think the passphrase file needs to be encoded in IBM-1047. I will verify with my contacts at IBM on this.

          So far, it looks like the IBM team is requesting a parameter to set the passphrase encoding rather than hard coding "UTF-8". Would that be possible?

          Randall Becker added a comment - So far, it looks like the IBM team is requesting a parameter to set the passphrase encoding rather than hard coding "UTF-8". Would that be possible?

          Mark Waite added a comment -

          Is it the same encoding used for the process on the agent or does it need to be independent of the encoding used for the agent?

          I could envision an agent specific environment variable defined for the zOS agent and not defined on other agents. If that variable is defined, then it could be used when encoding those temporary files that transmit credentials information to command line git.

          If your repositories are not huge, you might consider enabling JGit and using JGit instead of command line git. It does not use temporary files for credentials so it should not rely on file encoding.

          Mark Waite added a comment - Is it the same encoding used for the process on the agent or does it need to be independent of the encoding used for the agent? I could envision an agent specific environment variable defined for the zOS agent and not defined on other agents. If that variable is defined, then it could be used when encoding those temporary files that transmit credentials information to command line git. If your repositories are not huge, you might consider enabling JGit and using JGit instead of command line git. It does not use temporary files for credentials so it should not rely on file encoding.

          The situation is that original passphrase is coming from a UTF8 controller going to an IBM-1047 agent. So yes, this should be something on the agent config. Maybe something like -Dibm.passphrase.encoding=IBM-1047. I already tried JGit - it does not seem to like being on the platform at all. I could not make it work on R2.3 at all - either standalone or inside Jenkins.

          Randall Becker added a comment - The situation is that original passphrase is coming from a UTF8 controller going to an IBM-1047 agent. So yes, this should be something on the agent config. Maybe something like -Dibm.passphrase.encoding=IBM-1047. I already tried JGit - it does not seem to like being on the platform at all. I could not make it work on R2.3 at all - either standalone or inside Jenkins.

          Mark Waite added a comment -

          I'd prefer a name like GitSCM.credentials.file.encoding since there may be other platforms that want to change the encoding of the files.

          Can the encoding be used for all the git credentials files (username/password, private key, and passphrase files)?

          Mark Waite added a comment - I'd prefer a name like GitSCM.credentials.file.encoding since there may be other platforms that want to change the encoding of the files. Can the encoding be used for all the git credentials files (username/password, private key, and passphrase files)?

          That name sounds ok. The thing is, it looks like the private key is going across fine, it's just the passphrase that is not working because it's UTF-8. As above, when there is no passphrase, GitSCM authenticates fine and does the clone correctly. It seems to be just the passphrase. Can you MacGyver a version for me with a candidate and I will try it?

          Randall Becker added a comment - That name sounds ok. The thing is, it looks like the private key is going across fine, it's just the passphrase that is not working because it's UTF-8. As above, when there is no passphrase, GitSCM authenticates fine and does the clone correctly. It seems to be just the passphrase. Can you MacGyver a version for me with a candidate and I will try it?

          Mark Waite added a comment -

          Not until after work today (6 or 8 hours from now). Git plugin maintenance is a personal time thing.

          Mark Waite added a comment - Not until after work today (6 or 8 hours from now). Git plugin maintenance is a personal time thing.

          At your convenience

          Randall Becker added a comment - At your convenience

          I had confirmation of what's going on. On z/OS, files in the USS space (used by Jenkins) there is a tag attribute of each file that describes the encoding of the file as these can be a mixed bag. The default encoding on the box is assumed to be IBM-1047, but may not necessarily be so. The pipeline code seems to be interpreted correctly because the default encoding of the agent was set to ISO8859-1, so the shell steps understand that and pass the contents appropriately. The passphrase file, being hard-coded to UTF-8 and untagged is interpreted by git as IBM-1047, which it is not, so the authentication fails. So looks like this is just the passphrase file, not all credentials. I put in an interception script to change the tag of the passphrase file to ISO8859-1 and that got the authentication to work - a hack not a generic solution. So I think we're on the right track by allowing the passphrase file to be encoded as something other than UTF-8.

          Randall Becker added a comment - I had confirmation of what's going on. On z/OS, files in the USS space (used by Jenkins) there is a tag attribute of each file that describes the encoding of the file as these can be a mixed bag. The default encoding on the box is assumed to be IBM-1047, but may not necessarily be so. The pipeline code seems to be interpreted correctly because the default encoding of the agent was set to ISO8859-1, so the shell steps understand that and pass the contents appropriately. The passphrase file, being hard-coded to UTF-8 and untagged is interpreted by git as IBM-1047, which it is not, so the authentication fails. So looks like this is just the passphrase file, not all credentials. I put in an interception script to change the tag of the passphrase file to ISO8859-1 and that got the authentication to work - a hack not a generic solution. So I think we're on the right track by allowing the passphrase file to be encoded as something other than UTF-8.

          Mark Waite added a comment - - edited

          I've submitted two pull requests that try to provide a character set adjustment for the zOS environment without risking breaking other use cases.

          The incremental build with the ibm encoding property is [^git-client-3.3.2-PR-584-ibm.encoding.property.hpi]

          The incremental build with the GitSCM.credentials encoding environment variable is [^git-client-3.3.2-PR-585-credentials-file.encoding.hpi]

          Mark Waite added a comment - - edited I've submitted two pull requests that try to provide a character set adjustment for the zOS environment without risking breaking other use cases. The incremental build with the ibm encoding property is [^git-client-3.3.2-PR-584-ibm.encoding.property.hpi] The incremental build with the GitSCM.credentials encoding environment variable is [^git-client-3.3.2-PR-585-credentials-file.encoding.hpi]

          Environment variables cannot have this particular format, as in GitSCM.credentials.file.encoding, at least not on z/OS. I can use -DGitSCM.credentials.file.encoding or a different name, but this combination doesn't work. Can you change this to System.getProperty("GitSCM.credentials.file.encoding") instead of System.getenv("GitSCM.credentials.file.encoding"), please?

          Randall Becker added a comment - Environment variables cannot have this particular format, as in GitSCM.credentials.file.encoding, at least not on z/OS. I can use -DGitSCM.credentials.file.encoding or a different name, but this combination doesn't work. Can you change this to System.getProperty("GitSCM.credentials.file.encoding") instead of System.getenv("GitSCM.credentials.file.encoding"), please?

          Mark Waite added a comment - - edited

          Sure, it can use a property instead of an environment variable. New build will be available on the CI job for that PR.

          In order to make the property match with other properties that control the command line git implementation, the name of the property is now:

          org.jenkinsci.plugins.gitclient.CliGitAPIImpl.credentials.file.encoding

          Mark Waite added a comment - - edited Sure, it can use a property instead of an environment variable. New build will be available on the CI job for that PR. In order to make the property match with other properties that control the command line git implementation, the name of the property is now: org.jenkinsci.plugins.gitclient.CliGitAPIImpl.credentials.file.encoding

          CI did not build

          Randall Becker added a comment - CI did not build

          It does not look like the build failure was related to the PR; rather, it looks like the CI job has an environment issue.

          Randall Becker added a comment - It does not look like the build failure was related to the PR; rather, it looks like the CI job has an environment issue.

          Currently under test on my z/OS system

          Randall Becker added a comment - Currently under test on my z/OS system

          Randall Becker added a comment - - edited

          Looks good. I ran two different jobs - one on a new workspace, one on an existing workspace with no updates. The expected messages came out correctly (repository name changed to protect the guilty):

          > git --version # timeout=10
          using GIT_SSH to set credentials
          Using passphrase charset 'IBM1047'
          > git fetch --tags --progress – git@Bitbucket.org:REPO-SLUG.git +refs/heads/:refs/remotes/origin/ # timeout=10
          Checking out Revision ce210a4618766170a0dd9cc6f2aee4a8563d4070 (refs/remotes/origin/development)

          and we had no authentication issues.

          As a side nit - the plugin does not recognize the repository format - probably also an encoding issue but that would be a separate case.

          My sincere thanks.

          Randall Becker added a comment - - edited Looks good. I ran two different jobs - one on a new workspace, one on an existing workspace with no updates. The expected messages came out correctly (repository name changed to protect the guilty): > git --version # timeout=10 using GIT_SSH to set credentials Using passphrase charset 'IBM1047' > git fetch --tags --progress – git@Bitbucket.org:REPO-SLUG.git +refs/heads/ :refs/remotes/origin/ # timeout=10 Checking out Revision ce210a4618766170a0dd9cc6f2aee4a8563d4070 (refs/remotes/origin/development) and we had no authentication issues. As a side nit - the plugin does not recognize the repository format - probably also an encoding issue but that would be a separate case. My sincere thanks.

          Mark Waite added a comment -

          rsbeckerca I'm unassigning this issue from me now. I won't merge the proposed pull request until you can confirm that the entire use case is working. Keep this issue updated as you make further progress. Thanks!

          Mark Waite added a comment - rsbeckerca I'm unassigning this issue from me now. I won't merge the proposed pull request until you can confirm that the entire use case is working. Keep this issue updated as you make further progress. Thanks!

          markewaite We have been using the fix for a week with no issues. I can confirm that the SSH key-pair is correctly authenticating with this option. The repository format recognition is a completely separate issue and unrelated. So the entire use case is working.

          Randall Becker added a comment - markewaite We have been using the fix for a week with no issues. I can confirm that the SSH key-pair is correctly authenticating with this option. The repository format recognition is a completely separate issue and unrelated. So the entire use case is working.

          Mark Waite added a comment -

          Thanks. Then all I need to do is add the documentation that describes the property. That's a good excuse to document the other properties provided by the plugin as well.

          Mark Waite added a comment - Thanks. Then all I need to do is add the documentation that describes the property. That's a good excuse to document the other properties provided by the plugin as well.

          Mark Waite added a comment -

          rsbeckerca I've added documentation for the other properties. Does the layout look reasonable to you? If so, then I'll submit a pull request for that documentation, then once it is merged, I'll update the docs in the PR for this property.

          Mark Waite added a comment - rsbeckerca I've added documentation for the other properties . Does the layout look reasonable to you? If so, then I'll submit a pull request for that documentation, then once it is merged, I'll update the docs in the PR for this property.

          I like the format. Actually learned something about tags that I was annoying - I want my tags being updated silently as long as they are verified. Side issue. Go for PR

          Randall Becker added a comment - I like the format. Actually learned something about tags that I was annoying - I want my tags being updated silently as long as they are verified. Side issue. Go for PR

          Mark Waite added a comment -

          Released in git client plugin 3.4.0 with the properties documented in plugin properties

          Mark Waite added a comment - Released in git client plugin 3.4.0 with the properties documented in plugin properties

            markewaite Mark Waite
            rsbeckerca Randall Becker
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: