1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.scm.provider.git.command.checkout;
20
21 import java.io.IOException;
22 import java.io.OutputStream;
23 import java.io.Writer;
24 import java.nio.file.FileSystem;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.attribute.PosixFilePermissions;
28 import java.security.GeneralSecurityException;
29 import java.security.KeyPair;
30 import java.security.PublicKey;
31 import java.util.ArrayList;
32 import java.util.List;
33
34 import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
35 import org.apache.maven.scm.provider.git.GitScmTestUtils;
36 import org.apache.maven.scm.repository.ScmRepository;
37 import org.apache.maven.scm.tck.command.checkout.CheckOutCommandTckTest;
38 import org.apache.sshd.common.config.keys.KeyUtils;
39 import org.apache.sshd.common.config.keys.writer.openssh.OpenSSHKeyEncryptionContext;
40 import org.apache.sshd.common.config.keys.writer.openssh.OpenSSHKeyPairResourceWriter;
41 import org.apache.sshd.git.GitLocationResolver;
42 import org.apache.sshd.git.pack.GitPackCommandFactory;
43 import org.apache.sshd.server.SshServer;
44 import org.apache.sshd.server.auth.pubkey.KeySetPublickeyAuthenticator;
45 import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
46 import org.apache.sshd.server.session.ServerSession;
47 import org.apache.sshd.util.test.CommonTestSupportUtils;
48 import org.apache.sshd.util.test.CoreTestSupportUtils;
49 import org.bouncycastle.openssl.PKCS8Generator;
50 import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
51 import org.bouncycastle.openssl.jcajce.JcaPKCS8Generator;
52 import org.bouncycastle.util.io.pem.PemObject;
53 import org.junit.Assume;
54 import org.junit.Rule;
55 import org.junit.Test;
56 import org.junit.rules.TemporaryFolder;
57
58
59
60
61 public abstract class GitSshCheckOutCommandTckTest extends CheckOutCommandTckTest {
62 protected final SshServer sshServer;
63 protected final KeyPair keyPair;
64 protected final List<PublicKey> acceptedPublicKeys;
65
66 @Rule
67 public TemporaryFolder tmpDirectory = new TemporaryFolder();
68
69 protected GitSshCheckOutCommandTckTest() throws GeneralSecurityException {
70 sshServer = CoreTestSupportUtils.setupTestServer(getClass());
71 keyPair = CommonTestSupportUtils.generateKeyPair(KeyUtils.RSA_ALGORITHM, 2048);
72 acceptedPublicKeys = new ArrayList<>();
73 acceptedPublicKeys.add(keyPair.getPublic());
74 PublickeyAuthenticator authenticator = new KeySetPublickeyAuthenticator("onlykey", acceptedPublicKeys);
75 sshServer.setPublickeyAuthenticator(authenticator);
76 }
77
78 void writePrivateKeyAsPkcs8(Path file, String passphrase) throws IOException, GeneralSecurityException {
79
80 if (passphrase != null) {
81
82 OpenSSHKeyPairResourceWriter writer = new OpenSSHKeyPairResourceWriter();
83 OpenSSHKeyEncryptionContext context = new OpenSSHKeyEncryptionContext();
84 context.setCipherType("192");
85 context.setPassword(passphrase);
86 try (OutputStream output = Files.newOutputStream(file)) {
87 writer.writePrivateKey(keyPair, "comment", context, output);
88 }
89 } else {
90
91 PKCS8Generator pkcs8Generator = new JcaPKCS8Generator(keyPair.getPrivate(), null);
92 PemObject pemObject = pkcs8Generator.generate();
93
94 try (Writer writer = Files.newBufferedWriter(file);
95 JcaPEMWriter pw = new JcaPEMWriter(writer)) {
96 pw.writeObject(pemObject);
97 }
98 }
99
100 if (file.getFileSystem().supportedFileAttributeViews().contains("posix")) {
101
102 Files.setPosixFilePermissions(file, PosixFilePermissions.fromString("rwx------"));
103 }
104 }
105
106 protected abstract String getScmProvider();
107
108
109 public String getScmUrl() throws Exception {
110 return "scm:" + getScmProvider() + ":ssh://localhost:" + sshServer.getPort() + "/repository";
111 }
112
113 public void configureCredentials(ScmRepository repository, String passphrase) throws Exception {
114 ScmProviderRepositoryWithHost providerRepository =
115 ScmProviderRepositoryWithHost.class.cast(repository.getProviderRepository());
116
117 Path privateKeyFile = tmpDirectory.newFile().toPath();
118 writePrivateKeyAsPkcs8(privateKeyFile, passphrase);
119 providerRepository.setPrivateKey(privateKeyFile.toString());
120 providerRepository.setPassphrase(passphrase);
121 }
122
123
124 public void initRepo() throws Exception {
125 GitScmTestUtils.initRepo("src/test/resources/repository/", getRepositoryRoot(), getWorkingDirectory());
126
127 GitLocationResolver gitLocationResolver = new GitLocationResolver() {
128 @Override
129 public Path resolveRootDirectory(String command, String[] args, ServerSession session, FileSystem fs)
130 throws IOException {
131 return getRepositoryRoot().getParentFile().toPath();
132 }
133 };
134 sshServer.setCommandFactory(new GitPackCommandFactory(gitLocationResolver));
135 sshServer.start();
136
137
138 configureCredentials(getScmRepository(), null);
139 }
140
141 @Override
142 public void removeRepo() throws Exception {
143 sshServer.stop();
144 super.removeRepo();
145 }
146
147 @Override
148 @Test
149 public void testCheckOutCommandTest() throws Exception {
150 configureCredentials(getScmRepository(), null);
151 super.testCheckOutCommandTest();
152 }
153
154 @Test
155 public void testCheckOutCommandWithPassphraseTest() throws Exception {
156
157 Assume.assumeTrue(
158 "Ignore test with passphrase for provider " + getScmProvider(), "jgit".equals(getScmProvider()));
159 configureCredentials(getScmRepository(), "mySecret");
160 super.testCheckOutCommandTest();
161 }
162 }