View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm.provider.git.jgit.command.checkout;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.net.InetSocketAddress;
25  import java.nio.charset.StandardCharsets;
26  import java.nio.file.Files;
27  import java.nio.file.Path;
28  import java.nio.file.StandardCopyOption;
29  import java.security.GeneralSecurityException;
30  import java.security.PublicKey;
31  import java.util.function.Consumer;
32  
33  import org.apache.commons.io.IOUtils;
34  import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
35  import org.apache.maven.scm.provider.git.command.checkout.GitSshCheckOutCommandTckTest;
36  import org.apache.maven.scm.provider.git.jgit.JGitTestScmProvider;
37  import org.apache.maven.scm.provider.git.jgit.command.ScmProviderAwareSshdSessionFactory;
38  import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
39  import org.apache.maven.scm.repository.ScmRepository;
40  import org.apache.sshd.common.config.keys.PublicKeyEntry;
41  import org.eclipse.jgit.annotations.NonNull;
42  import org.eclipse.jgit.internal.transport.sshd.OpenSshServerKeyDatabase;
43  import org.eclipse.jgit.transport.CredentialsProvider;
44  import org.eclipse.jgit.transport.sshd.ServerKeyDatabase;
45  import org.eclipse.jgit.util.FileUtils;
46  import org.junit.Test;
47  import org.slf4j.Logger;
48  
49  /** @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> */
50  public class JGitSshCheckOutCommandTckTest extends GitSshCheckOutCommandTckTest {
51  
52      public JGitSshCheckOutCommandTckTest() throws GeneralSecurityException, IOException {
53          super();
54      }
55  
56      @Override
57      protected String getScmProvider() {
58          return "jgit";
59      }
60  
61      @Override
62      public void initRepo() throws Exception {
63          super.initRepo();
64          JGitTestScmProvider provider =
65                  (JGitTestScmProvider) getScmManager().getProviderByRepository(getScmRepository());
66          // accept all hosts
67          provider.registerCheckOutCommandCallback(new Consumer<JGitCheckOutCommand>() {
68              @Override
69              public void accept(JGitCheckOutCommand command) {
70                  command.setSshSessionFactorySupplier(AcceptAllHostsSshdSessionFactory::new);
71              }
72          });
73      }
74  
75      private static final class AcceptAllHostsSshdSessionFactory extends ScmProviderAwareSshdSessionFactory {
76          public AcceptAllHostsSshdSessionFactory(GitScmProviderRepository repo, Logger logger) {
77              super(repo, logger);
78          }
79  
80          @Override
81          protected ServerKeyDatabase createServerKeyDatabase(File homeDir, File sshDir) {
82              return new OpenSshServerKeyDatabase(false, null) {
83                  @Override
84                  public boolean accept(
85                          @NonNull String connectAddress,
86                          @NonNull InetSocketAddress remoteAddress,
87                          @NonNull PublicKey serverKey,
88                          @NonNull Configuration config,
89                          CredentialsProvider provider) {
90                      return true;
91                  }
92              };
93          }
94      }
95  
96      @Override
97      protected void deleteDirectory(File directory) throws IOException {
98          if (directory.exists()) {
99              FileUtils.delete(directory, FileUtils.RECURSIVE | FileUtils.RETRY);
100         }
101     }
102 
103     @Test
104     public void testCheckOutCommandWithPregeneratedKeysTest() throws Exception {
105         // test key pairs being generated with ssh-keygen (they have a slighly different format than the ones tested
106         // in testCheckOutCommandWithPassphraseTest and testCheckOutCommandTest)
107         configureKeypairFromClasspathResource(getScmRepository(), "sample_rsa", "mySecret");
108         super.testCheckOutCommandTest();
109     }
110 
111     private void configureKeypairFromClasspathResource(ScmRepository repository, String resourceName, String passphrase)
112             throws IOException, GeneralSecurityException {
113         // accept public key
114         try (InputStream publicKeyInputStream =
115                 this.getClass().getResourceAsStream("/ssh-keypairs/" + resourceName + ".pub")) {
116             PublicKey publicKey = PublicKeyEntry.parsePublicKeyEntry(
117                             IOUtils.toString(publicKeyInputStream, StandardCharsets.US_ASCII))
118                     .resolvePublicKey(null, null, null);
119             acceptedPublicKeys.add(publicKey);
120         }
121         Path privateKeyFile = Files.createTempFile("privateKey", null);
122         // private key into tmp file
123         try (InputStream privateKeyInputStream = this.getClass().getResourceAsStream("/ssh-keypairs/" + resourceName)) {
124             Files.copy(privateKeyInputStream, privateKeyFile, StandardCopyOption.REPLACE_EXISTING);
125         }
126         // configure provider repository with private key details
127         ScmProviderRepositoryWithHost providerRepository =
128                 ScmProviderRepositoryWithHost.class.cast(repository.getProviderRepository());
129         providerRepository.setPassphrase(passphrase); // may be null
130         providerRepository.setPrivateKey(privateKeyFile.toString());
131     }
132 }