001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.git.jgit.command.checkout; 020 021import java.io.File; 022import java.io.IOException; 023import java.io.InputStream; 024import java.net.InetSocketAddress; 025import java.nio.charset.StandardCharsets; 026import java.nio.file.Files; 027import java.nio.file.Path; 028import java.nio.file.StandardCopyOption; 029import java.security.GeneralSecurityException; 030import java.security.PublicKey; 031import java.util.function.Consumer; 032 033import org.apache.commons.io.IOUtils; 034import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost; 035import org.apache.maven.scm.provider.git.command.checkout.GitSshCheckOutCommandTckTest; 036import org.apache.maven.scm.provider.git.jgit.JGitTestScmProvider; 037import org.apache.maven.scm.provider.git.jgit.command.ScmProviderAwareSshdSessionFactory; 038import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; 039import org.apache.maven.scm.repository.ScmRepository; 040import org.apache.sshd.common.config.keys.PublicKeyEntry; 041import org.eclipse.jgit.annotations.NonNull; 042import org.eclipse.jgit.internal.transport.sshd.OpenSshServerKeyDatabase; 043import org.eclipse.jgit.transport.CredentialsProvider; 044import org.eclipse.jgit.transport.sshd.ServerKeyDatabase; 045import org.eclipse.jgit.util.FileUtils; 046import org.junit.Test; 047import org.slf4j.Logger; 048 049/** @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a> */ 050public class JGitSshCheckOutCommandTckTest extends GitSshCheckOutCommandTckTest { 051 052 public JGitSshCheckOutCommandTckTest() throws GeneralSecurityException, IOException { 053 super(); 054 } 055 056 @Override 057 protected String getScmProvider() { 058 return "jgit"; 059 } 060 061 @Override 062 public void initRepo() throws Exception { 063 super.initRepo(); 064 JGitTestScmProvider provider = 065 (JGitTestScmProvider) getScmManager().getProviderByRepository(getScmRepository()); 066 // accept all hosts 067 provider.registerCheckOutCommandCallback(new Consumer<JGitCheckOutCommand>() { 068 @Override 069 public void accept(JGitCheckOutCommand command) { 070 command.setSshSessionFactorySupplier(AcceptAllHostsSshdSessionFactory::new); 071 } 072 }); 073 } 074 075 private static final class AcceptAllHostsSshdSessionFactory extends ScmProviderAwareSshdSessionFactory { 076 public AcceptAllHostsSshdSessionFactory(GitScmProviderRepository repo, Logger logger) { 077 super(repo, logger); 078 } 079 080 @Override 081 protected ServerKeyDatabase createServerKeyDatabase(File homeDir, File sshDir) { 082 return new OpenSshServerKeyDatabase(false, null) { 083 @Override 084 public boolean accept( 085 @NonNull String connectAddress, 086 @NonNull InetSocketAddress remoteAddress, 087 @NonNull PublicKey serverKey, 088 @NonNull Configuration config, 089 CredentialsProvider provider) { 090 return true; 091 } 092 }; 093 } 094 } 095 096 @Override 097 protected void deleteDirectory(File directory) throws IOException { 098 if (directory.exists()) { 099 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}