]> source.dussan.org Git - gitblit.git/commitdiff
Update to SSHD 1.0.0
authorJames Moger <james.moger@gitblit.com>
Fri, 18 Sep 2015 12:30:29 +0000 (08:30 -0400)
committerJames Moger <james.moger@gitblit.com>
Fri, 18 Sep 2015 12:30:29 +0000 (08:30 -0400)
15 files changed:
.classpath
build.moxie
gitblit.iml
src/main/java/com/gitblit/transport/ssh/DisabledFilesystemFactory.java
src/main/java/com/gitblit/transport/ssh/FileKeyPairProvider.java [new file with mode: 0644]
src/main/java/com/gitblit/transport/ssh/NonForwardingFilter.java
src/main/java/com/gitblit/transport/ssh/SshDaemon.java
src/main/java/com/gitblit/transport/ssh/SshDaemonClient.java
src/main/java/com/gitblit/transport/ssh/SshKey.java
src/main/java/com/gitblit/transport/ssh/SshKeyAuthenticator.java
src/main/java/com/gitblit/transport/ssh/SshServerSession.java
src/main/java/com/gitblit/transport/ssh/SshServerSessionFactory.java
src/main/java/com/gitblit/transport/ssh/UsernamePasswordAuthenticator.java
src/test/java/com/gitblit/tests/SshDaemonTest.java
src/test/java/com/gitblit/tests/SshUnitTest.java

index 1c01cdff5bb3966c1cfff8ada08a5efd73f56c05..a04c9e2e20247ca9ed4f914e03e7dd218725ed69 100644 (file)
@@ -52,7 +52,7 @@
        <classpathentry kind="lib" path="ext/bcprov-jdk15on-1.52.jar" sourcepath="ext/src/bcprov-jdk15on-1.52.jar" />
        <classpathentry kind="lib" path="ext/bcmail-jdk15on-1.52.jar" sourcepath="ext/src/bcmail-jdk15on-1.52.jar" />
        <classpathentry kind="lib" path="ext/bcpkix-jdk15on-1.52.jar" sourcepath="ext/src/bcpkix-jdk15on-1.52.jar" />
-       <classpathentry kind="lib" path="ext/sshd-core-0.14.0.jar" sourcepath="ext/src/sshd-core-0.14.0.jar" />
+       <classpathentry kind="lib" path="ext/sshd-core-1.0.0.jar" sourcepath="ext/src/sshd-core-1.0.0.jar" />
        <classpathentry kind="lib" path="ext/mina-core-2.0.9.jar" sourcepath="ext/src/mina-core-2.0.9.jar" />
        <classpathentry kind="lib" path="ext/rome-0.9.jar" sourcepath="ext/src/rome-0.9.jar" />
        <classpathentry kind="lib" path="ext/jdom-1.0.jar" sourcepath="ext/src/jdom-1.0.jar" />
index 845a7a34ea075744155278551142f9d5e9344c8f..3958df8e6ca6c2b89c695a4bb779a5502cd8ca94 100644 (file)
@@ -111,7 +111,7 @@ properties: {
   bouncycastle.version : 1.52
   selenium.version : 2.28.0
   wikitext.version : 1.4
-  sshd.version: 0.14.0
+  sshd.version: 1.0.0
   mina.version: 2.0.9
   guice.version : 4.0-beta5
   # Gitblit maintains a fork of guice-servlet
index 9f896d1029bb7a5a4e3c712c110b91883eecfeab..d6982f35a0665f3509e827deb53c886aa6ad74fd 100644 (file)
       </library>
     </orderEntry>
     <orderEntry type="module-library">
-      <library name="sshd-core-0.14.0.jar">
+      <library name="sshd-core-1.0.0.jar">
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/ext/sshd-core-0.14.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/sshd-core-1.0.0.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="jar://$MODULE_DIR$/ext/src/sshd-core-0.14.0.jar!/" />
+          <root url="jar://$MODULE_DIR$/ext/src/sshd-core-1.0.0.jar!/" />
         </SOURCES>
       </library>
     </orderEntry>
index de661a4d97d24a34b8510d08df9c82764cf31021..9bab3b8eeb4e6bdf66696e1a06198e614279e2a9 100644 (file)
 package com.gitblit.transport.ssh;
 
 import java.io.IOException;
+import java.nio.file.FileSystem;
 
-import org.apache.sshd.common.Session;
 import org.apache.sshd.common.file.FileSystemFactory;
-import org.apache.sshd.common.file.FileSystemView;
-import org.apache.sshd.common.file.SshFile;
+import org.apache.sshd.common.session.Session;
 
 public class DisabledFilesystemFactory implements FileSystemFactory {
 
-       @Override
-       public FileSystemView createFileSystemView(Session session) throws IOException {
-               return new FileSystemView() {
-                       @Override
-                       public SshFile getFile(SshFile baseDir, String file) {
-                               return null;
-                       }
-
-                       @Override
-                       public SshFile getFile(String file) {
-                               return null;
-                       }
-
-                       @Override
-                       public FileSystemView getNormalizedView() {
-                               return null;
-                       }
-               };
-       }
+        /**
+     * Create user specific file system.
+     *
+     * @param session The session created for the user
+     * @return The current {@link FileSystem} for the provided session
+     * @throws java.io.IOException when the filesystem can not be created
+     */
+    @Override
+       public FileSystem createFileSystem(Session session) throws IOException {
+       return null;
+    }
 }
diff --git a/src/main/java/com/gitblit/transport/ssh/FileKeyPairProvider.java b/src/main/java/com/gitblit/transport/ssh/FileKeyPairProvider.java
new file mode 100644 (file)
index 0000000..db0741e
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.transport.ssh;
+
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.security.KeyPair;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
+import org.apache.sshd.common.util.SecurityUtils;
+import org.bouncycastle.openssl.PEMDecryptorProvider;
+import org.bouncycastle.openssl.PEMEncryptedKeyPair;
+import org.bouncycastle.openssl.PEMKeyPair;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.PasswordFinder;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
+
+/**
+ * This host key provider loads private keys from the specified files.
+ *
+ * Note that this class has a direct dependency on BouncyCastle and won't work
+ * unless it has been correctly registered as a security provider.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class FileKeyPairProvider extends AbstractKeyPairProvider {
+
+    private String[] files;
+    private PasswordFinder passwordFinder;
+
+    public FileKeyPairProvider() {
+    }
+
+    public FileKeyPairProvider(String[] files) {
+        this.files = files;
+    }
+
+    public FileKeyPairProvider(String[] files, PasswordFinder passwordFinder) {
+        this.files = files;
+        this.passwordFinder = passwordFinder;
+    }
+
+    public String[] getFiles() {
+        return files;
+    }
+
+    public void setFiles(String[] files) {
+        this.files = files;
+    }
+
+    public PasswordFinder getPasswordFinder() {
+        return passwordFinder;
+    }
+
+    public void setPasswordFinder(PasswordFinder passwordFinder) {
+        this.passwordFinder = passwordFinder;
+    }
+
+    public Iterable<KeyPair> loadKeys() {
+        if (!SecurityUtils.isBouncyCastleRegistered()) {
+            throw new IllegalStateException("BouncyCastle must be registered as a JCE provider");
+        }
+        return new Iterable<KeyPair>() {
+            @Override
+                       public Iterator<KeyPair> iterator() {
+                return new Iterator<KeyPair>() {
+                    private final Iterator<String> iterator = Arrays.asList(files).iterator();
+                    private KeyPair nextKeyPair;
+                    private boolean nextKeyPairSet = false;
+                    @Override
+                                       public boolean hasNext() {
+                        return nextKeyPairSet || setNextObject();
+                    }
+                    @Override
+                                       public KeyPair next() {
+                        if (!nextKeyPairSet) {
+                            if (!setNextObject()) {
+                                throw new NoSuchElementException();
+                            }
+                        }
+                        nextKeyPairSet = false;
+                        return nextKeyPair;
+                    }
+                    @Override
+                                       public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                    private boolean setNextObject() {
+                        while (iterator.hasNext()) {
+                            String file = iterator.next();
+                            nextKeyPair = doLoadKey(file);
+                            if (nextKeyPair != null) {
+                                nextKeyPairSet = true;
+                                return true;
+                            }
+                        }
+                        return false;
+                    }
+
+                };
+            }
+        };
+    }
+
+    protected KeyPair doLoadKey(String file) {
+        try {
+            PEMParser r = new PEMParser(new InputStreamReader(new FileInputStream(file)));
+            try {
+                Object o = r.readObject();
+
+                JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter();
+                pemConverter.setProvider("BC");
+                if (passwordFinder != null && o instanceof PEMEncryptedKeyPair) {
+                    JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder();
+                    PEMDecryptorProvider pemDecryptor = decryptorBuilder.build(passwordFinder.getPassword());
+                    o = pemConverter.getKeyPair(((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor));
+                }
+
+                if (o instanceof PEMKeyPair) {
+                    o = pemConverter.getKeyPair((PEMKeyPair)o);
+                    return (KeyPair) o;
+                } else if (o instanceof KeyPair) {
+                    return (KeyPair) o;
+                }
+            } finally {
+                r.close();
+            }
+        } catch (Exception e) {
+            log.warn("Unable to read key " + file, e);
+        }
+        return null;
+    }
+
+}
index 4bd75d598c574c52e4a8d6f763d5c2cb221349f7..29f7750dcfaff75136a708f872f97d423a50ba2c 100644 (file)
  */
 package com.gitblit.transport.ssh;
 
-import org.apache.sshd.common.ForwardingFilter;
-import org.apache.sshd.common.Session;
 import org.apache.sshd.common.SshdSocketAddress;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.server.forward.ForwardingFilter;
 
 public class NonForwardingFilter implements ForwardingFilter {
+
        @Override
-       public boolean canConnect(SshdSocketAddress address, Session session) {
+       public boolean canConnect(Type type, SshdSocketAddress address, Session session) {
                return false;
        }
 
index 68a2e901fcd6c7ae302d00df41359838ab125549..b6fae25ee6a194180d3051560b4d644bc951967f 100644 (file)
@@ -28,20 +28,19 @@ import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.sshd.SshServer;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.io.IoServiceFactoryFactory;
 import org.apache.sshd.common.io.mina.MinaServiceFactoryFactory;
 import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
-import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.util.SecurityUtils;
-import org.apache.sshd.server.UserAuth;
+import org.apache.sshd.server.SshServer;
 import org.apache.sshd.server.auth.CachingPublicKeyAuthenticator;
-import org.apache.sshd.server.auth.UserAuthKeyboardInteractive;
-import org.apache.sshd.server.auth.UserAuthPassword;
-import org.apache.sshd.server.auth.UserAuthPublicKey;
+import org.apache.sshd.server.auth.UserAuth;
+import org.apache.sshd.server.auth.UserAuthKeyboardInteractiveFactory;
+import org.apache.sshd.server.auth.UserAuthPasswordFactory;
+import org.apache.sshd.server.auth.UserAuthPublicKeyFactory;
 import org.apache.sshd.server.auth.gss.GSSAuthenticator;
-import org.apache.sshd.server.auth.gss.UserAuthGSS;
+import org.apache.sshd.server.auth.gss.UserAuthGSSFactory;
 import org.bouncycastle.openssl.PEMWriter;
 import org.eclipse.jgit.internal.JGitText;
 import org.slf4j.Logger;
@@ -156,17 +155,17 @@ public class SshDaemon {
                        switch (authenticatorName) {
                        case "gssapi-with-mic":
                                if(gssAuthenticator != null) {
-                                       userAuthFactories.add(new UserAuthGSS.Factory());
+                                       userAuthFactories.add(new UserAuthGSSFactory());
                                }
                                break;
                        case "publickey":
-                               userAuthFactories.add(new UserAuthPublicKey.Factory());
+                               userAuthFactories.add(new UserAuthPublicKeyFactory());
                                break;
                        case "password":
-                               userAuthFactories.add(new UserAuthPassword.Factory());
+                               userAuthFactories.add(new UserAuthPasswordFactory());
                                break;
                        case "keyboard-interactive":
-                               userAuthFactories.add(new UserAuthKeyboardInteractive.Factory());
+                               userAuthFactories.add(new UserAuthKeyboardInteractiveFactory());
                                break;
                        default:
                                log.error("Unknown ssh authenticator: '{}'", authenticatorName);
@@ -257,7 +256,7 @@ public class SshDaemon {
                        try {
                                ((SshCommandFactory) sshd.getCommandFactory()).stop();
                                sshd.stop();
-                       } catch (InterruptedException e) {
+                       } catch (IOException e) {
                                log.error("SSH Daemon stop interrupted", e);
                        }
                }
index a5d4c3dd1e70a3844166a15e89f05c85079d0c21..af25251b5b006706ca477e890b14530f617bae84 100644 (file)
@@ -17,7 +17,7 @@ package com.gitblit.transport.ssh;
 
 import java.net.SocketAddress;
 
-import org.apache.sshd.common.Session.AttributeKey;
+import org.apache.sshd.common.session.Session.AttributeKey;
 
 import com.gitblit.models.UserModel;
 
index 9c99d1a5fc9bb44140c908ccfdbf4da38c3ea1aa..9fd1005adb5b3e2308c8cb94df1c2cc464413663 100644 (file)
@@ -22,7 +22,8 @@ import java.util.List;
 
 import org.apache.commons.codec.binary.Base64;
 import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.util.Buffer;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 import org.eclipse.jgit.lib.Constants;
 
 import com.gitblit.Constants.AccessPermission;
@@ -72,7 +73,7 @@ public class SshKey implements Serializable {
                        }
                        final byte[] bin = Base64.decodeBase64(Constants.encodeASCII(parts[1]));
                        try {
-                               publicKey = new Buffer(bin).getRawPublicKey();
+                               publicKey = new ByteArrayBuffer(bin).getRawPublicKey();
                        } catch (SshException e) {
                                throw new RuntimeException(e);
                        }
@@ -145,7 +146,7 @@ public class SshKey implements Serializable {
        public String getRawData() {
                if (rawData == null && publicKey != null) {
                        // build the raw data manually from the public key
-                       Buffer buf = new Buffer();
+                       Buffer buf = new ByteArrayBuffer();
 
                        // 1: identify the algorithm
                        buf.putRawPublicKey(publicKey);
index c28a2ed68dec5525a498c51949c80a276d343580..dc9d8a4e54ecaefd29b4427d5eb1c36963fb9695 100644 (file)
@@ -19,7 +19,7 @@ import java.security.PublicKey;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.sshd.server.PublickeyAuthenticator;
+import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
 import org.apache.sshd.server.session.ServerSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
index d12a6be286acf0fc44a2d9a37b3b3f8adb9416e7..02504ec8807931dc9c8661222b4a156d13e3ebda 100644 (file)
@@ -19,10 +19,10 @@ import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.future.SshFutureListener;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.server.ServerFactoryManager;
-import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.server.session.ServerSessionImpl;
 
 // Expose addition of close session listeners
-class SshServerSession extends ServerSession {
+class SshServerSession extends ServerSessionImpl {
 
        SshServerSession(ServerFactoryManager server, IoSession ioSession) throws Exception {
                super(server, ioSession);
index 0c018f02dfb47008084f7fe4549c3438f4bbbb6d..bc67cec0cf5ea9b207212874be0c7803a42a1e6b 100644 (file)
@@ -67,6 +67,6 @@ public class SshServerSessionFactory extends SessionFactory {
 
        @Override
        protected AbstractSession doCreateSession(IoSession ioSession) throws Exception {
-               return new SshServerSession(server, ioSession);
+               return new SshServerSession(getServer(), ioSession);
        }
 }
index d7c4fe5e00d9fab0849f70f9b3af123967eebfb2..a6d77ec440f530e2928708b87f3b297bc1ed928f 100644 (file)
@@ -17,7 +17,7 @@ package com.gitblit.transport.ssh;
 
 import java.util.Locale;
 
-import org.apache.sshd.server.PasswordAuthenticator;
+import org.apache.sshd.server.auth.password.PasswordAuthenticator;
 import org.apache.sshd.server.session.ServerSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
index dcaeaff8f2e876c9db68eec3a2cc542c8dc020ee..c5deb7d514463da5bda509b7d76cdd90f4f66d73 100644 (file)
@@ -19,8 +19,8 @@ import java.io.File;
 import java.text.MessageFormat;
 import java.util.List;
 
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.SshClient;
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.session.ClientSession;
 import org.eclipse.jgit.api.CloneCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.revwalk.RevCommit;
index 3def700db6e401a1b75e77c5acbc507f884237a6..453f304366d39863d43d08fa51dc8cc8d9c5238a 100644 (file)
@@ -28,14 +28,14 @@ import java.util.ArrayList;
 import java.util.List;
 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.client.SshClient;
+import org.apache.sshd.client.auth.UserAuth;
+import org.apache.sshd.client.auth.UserAuthPublicKeyFactory;
+import org.apache.sshd.client.channel.ClientChannel;
+import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.util.SecurityUtils;
-import org.apache.sshd.client.UserAuth;
-import org.apache.sshd.client.auth.UserAuthPublicKey;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -108,7 +108,7 @@ public abstract class SshUnitTest extends GitblitUnitTest {
                        }
                });
                List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<>();
-               userAuthFactories.add(new UserAuthPublicKey.Factory());
+               userAuthFactories.add(new UserAuthPublicKeyFactory());
                client.setUserAuthFactories(userAuthFactories);
                client.start();
                return client;