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