diff options
Diffstat (limited to 'src/test/java')
5 files changed, 393 insertions, 6 deletions
diff --git a/src/test/java/com/gitblit/tests/GitBlitSuite.java b/src/test/java/com/gitblit/tests/GitBlitSuite.java index c015c847..5a7dcea1 100644 --- a/src/test/java/com/gitblit/tests/GitBlitSuite.java +++ b/src/test/java/com/gitblit/tests/GitBlitSuite.java @@ -61,10 +61,11 @@ import com.gitblit.utils.JGitUtils; MarkdownUtilsTest.class, JGitUtilsTest.class, SyndicationUtilsTest.class,
DiffUtilsTest.class, MetricUtilsTest.class, X509UtilsTest.class,
GitBlitTest.class, FederationTests.class, RpcTests.class, GitServletTest.class, GitDaemonTest.class,
- GroovyScriptTest.class, LuceneExecutorTest.class, RepositoryModelTest.class,
+ SshDaemonTest.class, GroovyScriptTest.class, LuceneExecutorTest.class, RepositoryModelTest.class,
FanoutServiceTest.class, Issue0259Test.class, Issue0271Test.class, HtpasswdAuthenticationTest.class,
ModelUtilsTest.class, JnaUtilsTest.class, LdapSyncServiceTest.class, FileTicketServiceTest.class, - BranchTicketServiceTest.class, RedisTicketServiceTest.class, AuthenticationManagerTest.class }) + BranchTicketServiceTest.class, RedisTicketServiceTest.class, AuthenticationManagerTest.class,
+ SshKeysDispatcherTest.class }) public class GitBlitSuite {
public static final File BASEFOLDER = new File("data");
@@ -78,10 +79,12 @@ public class GitBlitSuite { static int port = 8280;
static int gitPort = 8300;
static int shutdownPort = 8281;
+ static int sshPort = 39418;
public static String url = "http://localhost:" + port;
public static String gitServletUrl = "http://localhost:" + port + "/git";
public static String gitDaemonUrl = "git://localhost:" + gitPort;
+ public static String sshDaemonUrl = "ssh://admin@localhost:" + sshPort;
public static String account = "admin";
public static String password = "admin";
@@ -135,10 +138,15 @@ public class GitBlitSuite { Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
- GitBlitServer.main("--httpPort", "" + port, "--httpsPort", "0", "--shutdownPort",
- "" + shutdownPort, "--gitPort", "" + gitPort, "--repositoriesFolder",
- "\"" + GitBlitSuite.REPOSITORIES.getAbsolutePath() + "\"", "--userService",
- GitBlitSuite.USERSCONF.getAbsolutePath(), "--settings", GitBlitSuite.SETTINGS.getAbsolutePath(),
+ GitBlitServer.main(
+ "--httpPort", "" + port,
+ "--httpsPort", "0",
+ "--shutdownPort", "" + shutdownPort,
+ "--gitPort", "" + gitPort,
+ "--sshPort", "" + sshPort,
+ "--repositoriesFolder", GitBlitSuite.REPOSITORIES.getAbsolutePath(),
+ "--userService", GitBlitSuite.USERSCONF.getAbsolutePath(),
+ "--settings", GitBlitSuite.SETTINGS.getAbsolutePath(),
"--baseFolder", "data");
}
});
diff --git a/src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java b/src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java new file mode 100644 index 00000000..5d24b401 --- /dev/null +++ b/src/test/java/com/gitblit/tests/JschConfigTestSessionFactory.java @@ -0,0 +1,33 @@ +package com.gitblit.tests;
+
+import java.security.KeyPair;
+
+import org.eclipse.jgit.transport.JschConfigSessionFactory;
+import org.eclipse.jgit.transport.OpenSshConfig;
+import org.eclipse.jgit.util.FS;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+public class JschConfigTestSessionFactory extends JschConfigSessionFactory {
+
+ final KeyPair keyPair;
+
+ public JschConfigTestSessionFactory(KeyPair keyPair) {
+ this.keyPair = keyPair;
+ }
+
+ @Override
+ protected void configure(OpenSshConfig.Host host, Session session) {
+ session.setConfig("StrictHostKeyChecking", "no");
+ }
+
+ @Override
+ protected JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
+ JSch jsch = super.getJSch(hc, fs);
+// jsch.removeAllIdentity();
+// jsch.addIdentity("unittest", keyPair.getPrivate().getEncoded(), keyPair.getPublic().getEncoded(), null);
+ return jsch;
+ }
+}
\ No newline at end of file diff --git a/src/test/java/com/gitblit/tests/SshDaemonTest.java b/src/test/java/com/gitblit/tests/SshDaemonTest.java new file mode 100644 index 00000000..dcaeaff8 --- /dev/null +++ b/src/test/java/com/gitblit/tests/SshDaemonTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.tests; + +import java.io.File; +import java.text.MessageFormat; +import java.util.List; + +import org.apache.sshd.ClientSession; +import org.apache.sshd.SshClient; +import org.eclipse.jgit.api.CloneCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.SshSessionFactory; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.util.FileUtils; +import org.junit.Test; + +import com.gitblit.Constants; +import com.gitblit.Constants.AccessRestrictionType; +import com.gitblit.Constants.AuthorizationControl; +import com.gitblit.models.RepositoryModel; +import com.gitblit.utils.JGitUtils; + +public class SshDaemonTest extends SshUnitTest { + + static File ticgitFolder = new File(GitBlitSuite.REPOSITORIES, "working/ticgit"); + + String url = GitBlitSuite.sshDaemonUrl; + + @Test + public void testPublicKeyAuthentication() throws Exception { + SshClient client = getClient(); + ClientSession session = client.connect(username, "localhost", GitBlitSuite.sshPort).await().getSession(); + session.addPublicKeyIdentity(rwKeyPair); + assertTrue(session.auth().await().isSuccess()); + } + + @Test + public void testVersionCommand() throws Exception { + String result = testSshCommand("version"); + assertEquals(Constants.getGitBlitVersion(), result); + } + + @Test + public void testCloneCommand() throws Exception { + if (ticgitFolder.exists()) { + GitBlitSuite.close(ticgitFolder); + FileUtils.delete(ticgitFolder, FileUtils.RECURSIVE); + } + + // set clone restriction + RepositoryModel model = repositories().getRepositoryModel("ticgit.git"); + model.accessRestriction = AccessRestrictionType.CLONE; + model.authorizationControl = AuthorizationControl.NAMED; + repositories().updateRepositoryModel(model.name, model, false); + + JschConfigTestSessionFactory sessionFactory = new JschConfigTestSessionFactory(roKeyPair); + SshSessionFactory.setInstance(sessionFactory); + + CloneCommand clone = Git.cloneRepository(); + clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password)); + clone.setURI(MessageFormat.format("{0}/ticgit.git", url)); + clone.setDirectory(ticgitFolder); + clone.setBare(false); + clone.setCloneAllBranches(true); + Git git = clone.call(); + List<RevCommit> commits = JGitUtils.getRevLog(git.getRepository(), 10); + GitBlitSuite.close(git); + assertEquals(10, commits.size()); + + // restore anonymous repository access + model.accessRestriction = AccessRestrictionType.NONE; + model.authorizationControl = AuthorizationControl.NAMED; + repositories().updateRepositoryModel(model.name, model, false); + } +} diff --git a/src/test/java/com/gitblit/tests/SshKeysDispatcherTest.java b/src/test/java/com/gitblit/tests/SshKeysDispatcherTest.java new file mode 100644 index 00000000..8ccdc5bf --- /dev/null +++ b/src/test/java/com/gitblit/tests/SshKeysDispatcherTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.tests; + +import java.security.KeyPair; +import java.util.List; + +import org.junit.Test; +import org.parboiled.common.StringUtils; + +import com.gitblit.Constants.AccessPermission; +import com.gitblit.transport.ssh.SshKey; + +/** + * Tests the Keys Dispatcher and it's commands. + * + * @author James Moger + * + */ +public class SshKeysDispatcherTest extends SshUnitTest { + + @Test + public void testKeysListCommand() throws Exception { + String result = testSshCommand("keys ls -L"); + List<SshKey> keys = getKeyManager().getKeys(username); + assertEquals(String.format("There are %d keys!", keys.size()), 2, keys.size()); + assertEquals(keys.get(0).getRawData() + "\n" + keys.get(1).getRawData(), result); + } + + @Test + public void testKeysWhichCommand() throws Exception { + String result = testSshCommand("keys which -L"); + List<SshKey> keys = getKeyManager().getKeys(username); + assertEquals(String.format("There are %d keys!", keys.size()), 2, keys.size()); + assertEquals(keys.get(0).getRawData(), result); + } + + @Test + public void testKeysRmCommand() throws Exception { + testSshCommand("keys rm 2"); + String result = testSshCommand("keys ls -L"); + List<SshKey> keys = getKeyManager().getKeys(username); + assertEquals(String.format("There are %d keys!", keys.size()), 1, keys.size()); + assertEquals(keys.get(0).getRawData(), result); + } + + @Test + public void testKeysRmAllByIndexCommand() throws Exception { + testSshCommand("keys rm 1 2"); + List<SshKey> keys = getKeyManager().getKeys(username); + assertEquals(String.format("There are %d keys!", keys.size()), 0, keys.size()); + try { + testSshCommand("keys ls -L"); + assertTrue("Authentication worked without a public key?!", false); + } catch (AssertionError e) { + assertTrue(true); + } + } + + @Test + public void testKeysRmAllCommand() throws Exception { + testSshCommand("keys rm ALL"); + List<SshKey> keys = getKeyManager().getKeys(username); + assertEquals(String.format("There are %d keys!", keys.size()), 0, keys.size()); + try { + testSshCommand("keys ls -L"); + assertTrue("Authentication worked without a public key?!", false); + } catch (AssertionError e) { + assertTrue(true); + } + } + + @Test + public void testKeysAddCommand() throws Exception { + KeyPair kp = generator.generateKeyPair(); + SshKey key = new SshKey(kp.getPublic()); + testSshCommand("keys add --permission R", key.getRawData()); + List<SshKey> keys = getKeyManager().getKeys(username); + assertEquals(String.format("There are %d keys!", keys.size()), 3, keys.size()); + assertEquals(AccessPermission.CLONE, keys.get(2).getPermission()); + + String result = testSshCommand("keys ls -L"); + StringBuilder sb = new StringBuilder(); + for (SshKey sk : keys) { + sb.append(sk.getRawData()); + sb.append('\n'); + } + sb.setLength(sb.length() - 1); + assertEquals(sb.toString(), result); + } + + @Test + public void testKeysCommentCommand() throws Exception { + List<SshKey> keys = getKeyManager().getKeys(username); + assertTrue(StringUtils.isEmpty(keys.get(0).getComment())); + String comment = "this is my comment"; + testSshCommand(String.format("keys comment 1 %s", comment)); + + keys = getKeyManager().getKeys(username); + assertEquals(comment, keys.get(0).getComment()); + } +} diff --git a/src/test/java/com/gitblit/tests/SshUnitTest.java b/src/test/java/com/gitblit/tests/SshUnitTest.java new file mode 100644 index 00000000..43b51b74 --- /dev/null +++ b/src/test/java/com/gitblit/tests/SshUnitTest.java @@ -0,0 +1,141 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.tests; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.SocketAddress; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PublicKey; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.sshd.ClientChannel; +import org.apache.sshd.ClientSession; +import org.apache.sshd.SshClient; +import org.apache.sshd.client.ServerKeyVerifier; +import org.apache.sshd.common.util.SecurityUtils; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; + +import com.gitblit.Constants.AccessPermission; +import com.gitblit.transport.ssh.IPublicKeyManager; +import com.gitblit.transport.ssh.MemoryKeyManager; +import com.gitblit.transport.ssh.SshKey; + +/** + * Base class for SSH unit tests. + */ +public abstract class SshUnitTest extends GitblitUnitTest { + + protected static final AtomicBoolean started = new AtomicBoolean(false); + protected static KeyPairGenerator generator; + protected KeyPair rwKeyPair; + protected KeyPair roKeyPair; + protected String username = "admin"; + protected String password = "admin"; + + @BeforeClass + public static void startGitblit() throws Exception { + generator = SecurityUtils.getKeyPairGenerator("RSA"); + started.set(GitBlitSuite.startGitblit()); + } + + @AfterClass + public static void stopGitblit() throws Exception { + if (started.get()) { + GitBlitSuite.stopGitblit(); + } + } + + protected MemoryKeyManager getKeyManager() { + IPublicKeyManager mgr = gitblit().getPublicKeyManager(); + if (mgr instanceof MemoryKeyManager) { + return (MemoryKeyManager) gitblit().getPublicKeyManager(); + } else { + throw new RuntimeException("unexpected key manager type " + mgr.getClass().getName()); + } + } + + @Before + public void prepare() { + rwKeyPair = generator.generateKeyPair(); + + MemoryKeyManager keyMgr = getKeyManager(); + keyMgr.addKey(username, new SshKey(rwKeyPair.getPublic())); + + roKeyPair = generator.generateKeyPair(); + SshKey sshKey = new SshKey(roKeyPair.getPublic()); + sshKey.setPermission(AccessPermission.CLONE); + keyMgr.addKey(username, sshKey); + } + + @After + public void tearDown() { + MemoryKeyManager keyMgr = getKeyManager(); + keyMgr.removeAllKeys(username); + } + + protected SshClient getClient() { + SshClient client = SshClient.setUpDefaultClient(); + client.setServerKeyVerifier(new ServerKeyVerifier() { + @Override + public boolean verifyServerKey(ClientSession sshClientSession, SocketAddress remoteAddress, PublicKey serverKey) { + return true; + } + }); + client.start(); + return client; + } + + protected String testSshCommand(String cmd) throws IOException, InterruptedException { + return testSshCommand(cmd, null); + } + + protected String testSshCommand(String cmd, String stdin) throws IOException, InterruptedException { + SshClient client = getClient(); + ClientSession session = client.connect(username, "localhost", GitBlitSuite.sshPort).await().getSession(); + session.addPublicKeyIdentity(rwKeyPair); + assertTrue(session.auth().await().isSuccess()); + + ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_EXEC, cmd); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + if (stdin != null) { + Writer w = new OutputStreamWriter(baos); + w.write(stdin); + w.close(); + } + channel.setIn(new ByteArrayInputStream(baos.toByteArray())); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream err = new ByteArrayOutputStream(); + channel.setOut(out); + channel.setErr(err); + channel.open(); + + channel.waitFor(ClientChannel.CLOSED, 0); + + String result = out.toString().trim(); + channel.close(false); + client.stop(); + return result; + } +} |