View Javadoc
1   package org.apache.maven.scm.provider.git.jgit.command;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import com.jcraft.jsch.JSch;
23  import com.jcraft.jsch.JSchException;
24  import com.jcraft.jsch.Session;
25  import org.apache.maven.scm.log.ScmLogger;
26  import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
27  import org.eclipse.jgit.api.TransportConfigCallback;
28  import org.eclipse.jgit.transport.JschConfigSessionFactory;
29  import org.eclipse.jgit.transport.OpenSshConfig;
30  import org.eclipse.jgit.transport.SshSessionFactory;
31  import org.eclipse.jgit.transport.SshTransport;
32  import org.eclipse.jgit.transport.Transport;
33  import org.eclipse.jgit.util.FS;
34  import org.eclipse.jgit.util.StringUtils;
35  
36  /**
37   * Implementation of {@link TransportConfigCallback} which adds
38   * a public/private key identity to ssh URLs if configured.
39   */
40  public class JGitTransportConfigCallback implements TransportConfigCallback
41  {
42      private SshSessionFactory sshSessionFactory = null;
43  
44      public JGitTransportConfigCallback( GitScmProviderRepository repo, ScmLogger logger )
45      {
46          if ( repo.getFetchInfo().getProtocol().equals( "ssh" ) )
47          {
48              if ( !StringUtils.isEmptyOrNull( repo.getPrivateKey() ) && repo.getPassphrase() == null )
49              {
50                  logger.debug( "using private key: " + repo.getPrivateKey() );
51                  sshSessionFactory = new UnprotectedPrivateKeySessionFactory( repo );
52              }
53              else if ( !StringUtils.isEmptyOrNull( repo.getPrivateKey() ) && repo.getPassphrase() != null )
54              {
55                  logger.debug( "using private key with passphrase: " + repo.getPrivateKey() );
56                  sshSessionFactory = new ProtectedPrivateKeyFileSessionFactory( repo );
57              }
58              else
59              {
60                  sshSessionFactory = new SimpleSessionFactory();
61              }
62          }
63      }
64  
65      @Override
66      public void configure( Transport transport )
67      {
68          if ( transport instanceof SshTransport )
69          {
70              SshTransport sshTransport = (SshTransport) transport;
71              sshTransport.setSshSessionFactory( sshSessionFactory );
72          }
73      }
74  
75      private static class SimpleSessionFactory extends JschConfigSessionFactory
76      {
77          @Override
78          protected void configure( OpenSshConfig.Host host, Session session )
79          {
80          }
81      }
82  
83      private abstract static class PrivateKeySessionFactory extends SimpleSessionFactory
84      {
85          private final GitScmProviderRepository repo;
86  
87          GitScmProviderRepository getRepo()
88          {
89              return repo;
90          }
91  
92          PrivateKeySessionFactory( GitScmProviderRepository repo )
93          {
94              this.repo = repo;
95          }
96      }
97  
98      private static class UnprotectedPrivateKeySessionFactory extends PrivateKeySessionFactory
99      {
100 
101         UnprotectedPrivateKeySessionFactory( GitScmProviderRepository repo )
102         {
103             super( repo );
104         }
105 
106         @Override
107         protected JSch createDefaultJSch( FS fs ) throws JSchException
108         {
109             JSch defaultJSch = super.createDefaultJSch( fs );
110             defaultJSch.addIdentity( getRepo().getPrivateKey() );
111             return defaultJSch;
112         }
113     }
114 
115     private static class ProtectedPrivateKeyFileSessionFactory extends PrivateKeySessionFactory
116     {
117 
118         ProtectedPrivateKeyFileSessionFactory( GitScmProviderRepository repo )
119         {
120             super( repo );
121         }
122 
123         @Override
124         protected JSch createDefaultJSch( FS fs ) throws JSchException
125         {
126             JSch defaultJSch = super.createDefaultJSch( fs );
127             defaultJSch.addIdentity( getRepo().getPrivateKey(), getRepo().getPassphrase() );
128             return defaultJSch;
129         }
130     }
131 }