You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2015/03/17 18:35:31 UTC

[1/4] mina-sshd git commit: [SSHD-427] Avoid duplicate SFTP protocol definitions

Repository: mina-sshd
Updated Branches:
  refs/heads/master 91a721e94 -> 4039a11ae


[SSHD-427] Avoid duplicate SFTP protocol definitions

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/6debaf59
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/6debaf59
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/6debaf59

Branch: refs/heads/master
Commit: 6debaf591d63bf352eef870b5e23840d15827a0d
Parents: 91a721e
Author: Guillaume Nodet <gn...@apache.org>
Authored: Tue Mar 17 12:04:15 2015 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Tue Mar 17 12:05:04 2015 +0100

----------------------------------------------------------------------
 .../java/org/apache/sshd/client/SftpClient.java |  29 +--
 .../sshd/client/sftp/DefaultSftpClient.java     | 122 +---------
 .../sshd/client/sftp/SftpFileChannel.java       |   4 +-
 .../client/sftp/SftpFileSystemProvider.java     |  20 +-
 .../apache/sshd/common/sftp/SftpConstants.java  | 223 +++++++++++++++++++
 .../apache/sshd/server/sftp/SftpSubsystem.java  | 199 +----------------
 .../src/test/java/org/apache/sshd/SftpTest.java |  18 +-
 7 files changed, 267 insertions(+), 348 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6debaf59/sshd-core/src/main/java/org/apache/sshd/client/SftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SftpClient.java
index 4001aaf..ce1b00e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SftpClient.java
@@ -26,35 +26,16 @@ import java.util.Collection;
 import java.util.EnumSet;
 import java.util.concurrent.TimeUnit;
 
+import static org.apache.sshd.common.sftp.SftpConstants.S_IFDIR;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IFLNK;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IFMT;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IFREG;
+
 /**
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public interface SftpClient extends AutoCloseable {
 
-    //
-    // Permission flags
-    //
-    int S_IFMT =   0170000;  // bitmask for the file type bitfields
-    int S_IFSOCK = 0140000;  // socket
-    int S_IFLNK =  0120000;  // symbolic link
-    int S_IFREG =  0100000;  // regular file
-    int S_IFBLK =  0060000;  // block device
-    int S_IFDIR =  0040000;  // directory
-    int S_IFCHR =  0020000;  // character device
-    int S_IFIFO =  0010000;  // fifo
-    int S_ISUID =  0004000;  // set UID bit
-    int S_ISGID =  0002000;  // set GID bit
-    int S_ISVTX =  0001000;  // sticky bit
-    int S_IRUSR =  0000400;
-    int S_IWUSR =  0000200;
-    int S_IXUSR =  0000100;
-    int S_IRGRP =  0000040;
-    int S_IWGRP =  0000020;
-    int S_IXGRP =  0000010;
-    int S_IROTH =  0000004;
-    int S_IWOTH =  0000002;
-    int S_IXOTH =  0000001;
-
     enum OpenMode {
         Read,
         Write,

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6debaf59/sshd-core/src/main/java/org/apache/sshd/client/sftp/DefaultSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/sftp/DefaultSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/sftp/DefaultSftpClient.java
index a793cc6..99e60af 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/sftp/DefaultSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/sftp/DefaultSftpClient.java
@@ -41,125 +41,13 @@ import org.apache.sshd.client.SftpException;
 import org.apache.sshd.client.channel.ChannelSubsystem;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.util.Buffer;
-import org.apache.sshd.server.sftp.SftpSubsystem;
+
+import static org.apache.sshd.common.sftp.SftpConstants.*;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class DefaultSftpClient implements SftpClient {
-
-    public static final int SSH_FXP_INIT =             1;
-    public static final int SSH_FXP_VERSION =          2;
-    public static final int SSH_FXP_OPEN =             3;
-    public static final int SSH_FXP_CLOSE =            4;
-    public static final int SSH_FXP_READ =             5;
-    public static final int SSH_FXP_WRITE =            6;
-    public static final int SSH_FXP_LSTAT =            7;
-    public static final int SSH_FXP_FSTAT =            8;
-    public static final int SSH_FXP_SETSTAT =          9;
-    public static final int SSH_FXP_FSETSTAT =        10;
-    public static final int SSH_FXP_OPENDIR =         11;
-    public static final int SSH_FXP_READDIR =         12;
-    public static final int SSH_FXP_REMOVE =          13;
-    public static final int SSH_FXP_MKDIR =           14;
-    public static final int SSH_FXP_RMDIR =           15;
-    public static final int SSH_FXP_REALPATH =        16;
-    public static final int SSH_FXP_STAT =            17;
-    public static final int SSH_FXP_RENAME =          18;
-    public static final int SSH_FXP_READLINK =        19;
-    public static final int SSH_FXP_SYMLINK =         20;
-    public static final int SSH_FXP_LINK =            21; // v6
-    public static final int SSH_FXP_BLOCK =           22; // v6
-    public static final int SSH_FXP_UNBLOCK =         23; // v6
-    public static final int SSH_FXP_STATUS =         101;
-    public static final int SSH_FXP_HANDLE =         102;
-    public static final int SSH_FXP_DATA =           103;
-    public static final int SSH_FXP_NAME =           104;
-    public static final int SSH_FXP_ATTRS =          105;
-    public static final int SSH_FXP_EXTENDED =       200;
-    public static final int SSH_FXP_EXTENDED_REPLY = 201;
-
-    public static final int SSH_FX_OK =                           0;
-    public static final int SSH_FX_EOF =                          1;
-    public static final int SSH_FX_NO_SUCH_FILE =                 2;
-    public static final int SSH_FX_PERMISSION_DENIED =            3;
-    public static final int SSH_FX_FAILURE =                      4;
-    public static final int SSH_FX_BAD_MESSAGE =                  5;
-    public static final int SSH_FX_NO_CONNECTION =                6;
-    public static final int SSH_FX_CONNECTION_LOST =              7;
-    public static final int SSH_FX_OP_UNSUPPORTED =               8;
-    public static final int SSH_FX_FILE_ALREADY_EXISTS =         11;
-    public static final int SSH_FX_LOCK_CONFLICT =               17;
-
-    public static final int SSH_FILEXFER_ATTR_SIZE =            0x00000001;
-    public static final int SSH_FILEXFER_ATTR_UIDGID =          0x00000002;
-    public static final int SSH_FILEXFER_ATTR_PERMISSIONS =     0x00000004;
-    public static final int SSH_FILEXFER_ATTR_ACMODTIME =       0x00000008; // v3 naming convention
-    public static final int SSH_FILEXFER_ATTR_ACCESSTIME =      0x00000008; // v4
-    public static final int SSH_FILEXFER_ATTR_CREATETIME =      0x00000010; // v4
-    public static final int SSH_FILEXFER_ATTR_MODIFYTIME =      0x00000020; // v4
-    public static final int SSH_FILEXFER_ATTR_ACL =             0x00000040; // v4
-    public static final int SSH_FILEXFER_ATTR_OWNERGROUP =      0x00000080; // v4
-    public static final int SSH_FILEXFER_ATTR_SUBSECOND_TIMES = 0x00000100; // v4
-    public static final int SSH_FILEXFER_ATTR_EXTENDED =        0x80000000;
-
-    public static final int SSH_FXF_READ =   0x00000001;
-    public static final int SSH_FXF_WRITE =  0x00000002;
-    public static final int SSH_FXF_APPEND = 0x00000004;
-    public static final int SSH_FXF_CREAT =  0x00000008;
-    public static final int SSH_FXF_TRUNC =  0x00000010;
-    public static final int SSH_FXF_EXCL =   0x00000020;
-
-    public static final int SSH_FILEXFER_TYPE_REGULAR =      1;
-    public static final int SSH_FILEXFER_TYPE_DIRECTORY =    2;
-    public static final int SSH_FILEXFER_TYPE_SYMLINK =      3;
-    public static final int SSH_FILEXFER_TYPE_SPECIAL =      4;
-    public static final int SSH_FILEXFER_TYPE_UNKNOWN =      5;
-    public static final int SSH_FILEXFER_TYPE_SOCKET =       6; // v5
-    public static final int SSH_FILEXFER_TYPE_CHAR_DEVICE =  7; // v5
-    public static final int SSH_FILEXFER_TYPE_BLOCK_DEVICE = 8; // v5
-    public static final int SSH_FILEXFER_TYPE_FIFO         = 9; // v5
-
-    public static final int SSH_FXF_ACCESS_DISPOSITION = 0x00000007;
-    public static final int SSH_FXF_CREATE_NEW =         0x00000000;
-    public static final int SSH_FXF_CREATE_TRUNCATE =    0x00000001;
-    public static final int SSH_FXF_OPEN_EXISTING =      0x00000002;
-    public static final int SSH_FXF_OPEN_OR_CREATE =     0x00000003;
-    public static final int SSH_FXF_TRUNCATE_EXISTING =  0x00000004;
-    public static final int SSH_FXF_APPEND_DATA =        0x00000008;
-    public static final int SSH_FXF_APPEND_DATA_ATOMIC = 0x00000010;
-    public static final int SSH_FXF_TEXT_MODE =          0x00000020;
-    public static final int SSH_FXF_READ_LOCK =          0x00000040;
-    public static final int SSH_FXF_WRITE_LOCK =         0x00000080;
-    public static final int SSH_FXF_DELETE_LOCK =        0x00000100;
-
-    public static final int SSH_FXP_RENAME_OVERWRITE = 0x00000001;
-    public static final int SSH_FXP_RENAME_ATOMIC =    0x00000002;
-    public static final int SSH_FXP_RENAME_NATIVE =    0x00000004;
-
-    public static final int ACE4_READ_DATA            = 0x00000001;
-    public static final int ACE4_LIST_DIRECTORY       = 0x00000001;
-    public static final int ACE4_WRITE_DATA           = 0x00000002;
-    public static final int ACE4_ADD_FILE             = 0x00000002;
-    public static final int ACE4_APPEND_DATA          = 0x00000004;
-    public static final int ACE4_ADD_SUBDIRECTORY     = 0x00000004;
-    public static final int ACE4_READ_NAMED_ATTRS     = 0x00000008;
-    public static final int ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
-    public static final int ACE4_EXECUTE              = 0x00000020;
-    public static final int ACE4_DELETE_CHILD         = 0x00000040;
-    public static final int ACE4_READ_ATTRIBUTES      = 0x00000080;
-    public static final int ACE4_WRITE_ATTRIBUTES     = 0x00000100;
-    public static final int ACE4_DELETE               = 0x00010000;
-    public static final int ACE4_READ_ACL             = 0x00020000;
-    public static final int ACE4_WRITE_ACL            = 0x00040000;
-    public static final int ACE4_WRITE_OWNER          = 0x00080000;
-    public static final int ACE4_SYNCHRONIZE          = 0x00100000;
-
-    public static int SFTP_V3 = 3;
-    public static int SFTP_V4 = 4;
-    public static int SFTP_V5 = 5;
-    public static int SFTP_V6 = 6;
-
     private final ClientSession clientSession;
     private final ChannelSubsystem channel;
     private final Map<Integer, Buffer> messages;
@@ -837,7 +725,7 @@ public class DefaultSftpClient implements SftpClient {
         Buffer buffer = new Buffer();
         buffer.putString(path);
         if (version >= SFTP_V4) {
-            buffer.putInt(SftpSubsystem.SSH_FILEXFER_ATTR_ALL);
+            buffer.putInt(SSH_FILEXFER_ATTR_ALL);
         }
         return checkAttributes(receive(send(SSH_FXP_STAT, buffer)));
     }
@@ -846,7 +734,7 @@ public class DefaultSftpClient implements SftpClient {
         Buffer buffer = new Buffer();
         buffer.putString(path);
         if (version >= SFTP_V4) {
-            buffer.putInt(SftpSubsystem.SSH_FILEXFER_ATTR_ALL);
+            buffer.putInt(SSH_FILEXFER_ATTR_ALL);
         }
         return checkAttributes(receive(send(SSH_FXP_LSTAT, buffer)));
     }
@@ -855,7 +743,7 @@ public class DefaultSftpClient implements SftpClient {
         Buffer buffer = new Buffer();
         buffer.putString(handle.id);
         if (version >= SFTP_V4) {
-            buffer.putInt(SftpSubsystem.SSH_FILEXFER_ATTR_ALL);
+            buffer.putInt(SSH_FILEXFER_ATTR_ALL);
         }
         return checkAttributes(receive(send(SSH_FXP_FSTAT, buffer)));
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6debaf59/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
index 52a02d0..e599793 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
@@ -37,6 +37,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.sshd.client.SftpClient;
 import org.apache.sshd.client.SftpException;
 
+import static org.apache.sshd.common.sftp.SftpConstants.SSH_FX_LOCK_CONFLICT;
+
 public class SftpFileChannel extends FileChannel {
 
     final SftpPath p;
@@ -288,7 +290,7 @@ public class SftpFileChannel extends FileChannel {
         try {
             sftp.lock(handle, position, size, 0);
         } catch (SftpException e) {
-            if (e.getStatus() == DefaultSftpClient.SSH_FX_LOCK_CONFLICT) {
+            if (e.getStatus() == SSH_FX_LOCK_CONFLICT) {
                 throw new OverlappingFileLockException();
             }
             throw e;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6debaf59/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
index c9f9a70..cc77055 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
@@ -65,11 +65,22 @@ import org.apache.sshd.ClientSession;
 import org.apache.sshd.SshBuilder;
 import org.apache.sshd.SshClient;
 import org.apache.sshd.client.SftpClient;
+import org.apache.sshd.client.SftpClient.Attributes;
 import org.apache.sshd.client.SftpException;
 import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.sftp.SftpConstants;
 import org.apache.sshd.common.util.IoUtils;
 
-import static org.apache.sshd.client.SftpClient.*;
+import static org.apache.sshd.common.sftp.SftpConstants.SFTP_V3;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IRGRP;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IROTH;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IRUSR;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IWGRP;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IWOTH;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IWUSR;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IXGRP;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IXOTH;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IXUSR;
 
 public class SftpFileSystemProvider extends FileSystemProvider {
 
@@ -220,7 +231,8 @@ public class SftpFileSystemProvider extends FileSystemProvider {
             try {
                 sftp.mkdir(dir.toString());
             } catch (SftpException e) {
-                if (sftp.getVersion() == 3 && e.getStatus() == DefaultSftpClient.SSH_FX_FAILURE) {
+                int sftpStatus=e.getStatus();
+                if ((sftp.getVersion() == SFTP_V3) && (sftpStatus == SftpConstants.SSH_FX_FAILURE)) {
                     try {
                         Attributes attributes = sftp.stat(dir.toString());
                         if (attributes != null) {
@@ -230,7 +242,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
                         e.addSuppressed(e2);
                     }
                 }
-                if (e.getStatus() == DefaultSftpClient.SSH_FX_FILE_ALREADY_EXISTS) {
+                if (sftpStatus == SftpConstants.SSH_FX_FILE_ALREADY_EXISTS) {
                     throw new FileAlreadyExistsException(p.toString());
                 }
                 throw e;
@@ -463,7 +475,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
                                 attributes = client.lstat(p.toString());
                             }
                         } catch (SftpException e) {
-                            if (e.getStatus() == DefaultSftpClient.SSH_FX_NO_SUCH_FILE) {
+                            if (e.getStatus() == SftpConstants.SSH_FX_NO_SUCH_FILE) {
                                 throw new NoSuchFileException(p.toString());
                             }
                             throw e;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6debaf59/sshd-core/src/main/java/org/apache/sshd/common/sftp/SftpConstants.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/sftp/SftpConstants.java b/sshd-core/src/main/java/org/apache/sshd/common/sftp/SftpConstants.java
new file mode 100644
index 0000000..80d0667
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/sftp/SftpConstants.java
@@ -0,0 +1,223 @@
+/*
+ * 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 org.apache.sshd.common.sftp;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class SftpConstants {
+
+    public static final int SSH_FXP_INIT =             1;
+    public static final int SSH_FXP_VERSION =          2;
+    public static final int SSH_FXP_OPEN =             3;
+    public static final int SSH_FXP_CLOSE =            4;
+    public static final int SSH_FXP_READ =             5;
+    public static final int SSH_FXP_WRITE =            6;
+    public static final int SSH_FXP_LSTAT =            7;
+    public static final int SSH_FXP_FSTAT =            8;
+    public static final int SSH_FXP_SETSTAT =          9;
+    public static final int SSH_FXP_FSETSTAT =        10;
+    public static final int SSH_FXP_OPENDIR =         11;
+    public static final int SSH_FXP_READDIR =         12;
+    public static final int SSH_FXP_REMOVE =          13;
+    public static final int SSH_FXP_MKDIR =           14;
+    public static final int SSH_FXP_RMDIR =           15;
+    public static final int SSH_FXP_REALPATH =        16;
+    public static final int SSH_FXP_STAT =            17;
+    public static final int SSH_FXP_RENAME =          18;
+    public static final int SSH_FXP_READLINK =        19;
+    public static final int SSH_FXP_SYMLINK =         20; // v3 -> v5
+    public static final int SSH_FXP_LINK =            21; // v6
+    public static final int SSH_FXP_BLOCK =           22; // v6
+    public static final int SSH_FXP_UNBLOCK =         23; // v6
+    public static final int SSH_FXP_STATUS =         101;
+    public static final int SSH_FXP_HANDLE =         102;
+    public static final int SSH_FXP_DATA =           103;
+    public static final int SSH_FXP_NAME =           104;
+    public static final int SSH_FXP_ATTRS =          105;
+    public static final int SSH_FXP_EXTENDED =       200;
+    public static final int SSH_FXP_EXTENDED_REPLY = 201;
+
+    public static final int SSH_FX_OK =                           0;
+    public static final int SSH_FX_EOF =                          1;
+    public static final int SSH_FX_NO_SUCH_FILE =                 2;
+    public static final int SSH_FX_PERMISSION_DENIED =            3;
+    public static final int SSH_FX_FAILURE =                      4;
+    public static final int SSH_FX_BAD_MESSAGE =                  5;
+    public static final int SSH_FX_NO_CONNECTION =                6;
+    public static final int SSH_FX_CONNECTION_LOST =              7;
+    public static final int SSH_FX_OP_UNSUPPORTED =               8;
+    public static final int SSH_FX_INVALID_HANDLE =               9;
+    public static final int SSH_FX_NO_SUCH_PATH =                10;
+    public static final int SSH_FX_FILE_ALREADY_EXISTS =         11;
+    public static final int SSH_FX_WRITE_PROTECT =               12;
+    public static final int SSH_FX_NO_MEDIA =                    13;
+    public static final int SSH_FX_NO_SPACE_ON_FILESYSTEM =      14;
+    public static final int SSH_FX_QUOTA_EXCEEDED =              15;
+    public static final int SSH_FX_UNKNOWN_PRINCIPLE =           16;
+    public static final int SSH_FX_LOCK_CONFLICT =               17;
+    public static final int SSH_FX_DIR_NOT_EMPTY =               18;
+    public static final int SSH_FX_NOT_A_DIRECTORY =             19;
+    public static final int SSH_FX_INVALID_FILENAME =            20;
+    public static final int SSH_FX_LINK_LOOP =                   21;
+    public static final int SSH_FX_CANNOT_DELETE =               22;
+    public static final int SSH_FX_INVALID_PARAMETER =           23;
+    public static final int SSH_FX_FILE_IS_A_DIRECTORY =         24;
+    public static final int SSH_FX_BYTE_RANGE_LOCK_CONFLICT =    25;
+    public static final int SSH_FX_BYTE_RANGE_LOCK_REFUSED =     26;
+    public static final int SSH_FX_DELETE_PENDING =              27;
+    public static final int SSH_FX_FILE_CORRUPT =                28;
+    public static final int SSH_FX_OWNER_INVALID =               29;
+    public static final int SSH_FX_GROUP_INVALID =               30;
+    public static final int SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK = 31;
+
+    public static final int SSH_FILEXFER_ATTR_SIZE =              0x00000001;
+    public static final int SSH_FILEXFER_ATTR_UIDGID =            0x00000002;
+    public static final int SSH_FILEXFER_ATTR_PERMISSIONS =       0x00000004;
+    public static final int SSH_FILEXFER_ATTR_ACMODTIME =         0x00000008; // v3 naming convention
+    public static final int SSH_FILEXFER_ATTR_ACCESSTIME =        0x00000008; // v4
+    public static final int SSH_FILEXFER_ATTR_CREATETIME =        0x00000010; // v4
+    public static final int SSH_FILEXFER_ATTR_MODIFYTIME =        0x00000020; // v4
+    public static final int SSH_FILEXFER_ATTR_ACL =               0x00000040; // v4
+    public static final int SSH_FILEXFER_ATTR_OWNERGROUP =        0x00000080; // v4
+    public static final int SSH_FILEXFER_ATTR_SUBSECOND_TIMES =   0x00000100; // v5
+    public static final int SSH_FILEXFER_ATTR_BITS =              0x00000200; // v5
+    public static final int SSH_FILEXFER_ATTR_ALLOCATION_SIZE =   0x00000400; // v6
+    public static final int SSH_FILEXFER_ATTR_TEXT_HINT =         0x00000800; // v6
+    public static final int SSH_FILEXFER_ATTR_MIME_TYPE =         0x00001000; // v6
+    public static final int SSH_FILEXFER_ATTR_LINK_COUNT =        0x00002000; // v6
+    public static final int SSH_FILEXFER_ATTR_UNTRANSLATED_NAME = 0x00004000; // v6
+    public static final int SSH_FILEXFER_ATTR_CTIME =             0x00008000; // v6
+    public static final int SSH_FILEXFER_ATTR_EXTENDED =          0x80000000;
+
+    public static final int SSH_FILEXFER_ATTR_ALL =               0x0000FFFF; // All attributes
+
+    public static final int SSH_FILEXFER_ATTR_FLAGS_READONLY =         0x00000001;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_SYSTEM =           0x00000002;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_HIDDEN =           0x00000004;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_CASE_INSENSITIVE = 0x00000008;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_ARCHIVE =          0x00000010;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_ENCRYPTED =        0x00000020;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_COMPRESSED =       0x00000040;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_SPARSE =           0x00000080;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_APPEND_ONLY =      0x00000100;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_IMMUTABLE =        0x00000200;
+    public static final int SSH_FILEXFER_ATTR_FLAGS_SYNC =             0x00000400;
+
+    public static final int SSH_FILEXFER_TYPE_REGULAR =      1;
+    public static final int SSH_FILEXFER_TYPE_DIRECTORY =    2;
+    public static final int SSH_FILEXFER_TYPE_SYMLINK =      3;
+    public static final int SSH_FILEXFER_TYPE_SPECIAL =      4;
+    public static final int SSH_FILEXFER_TYPE_UNKNOWN =      5;
+    public static final int SSH_FILEXFER_TYPE_SOCKET =       6; // v5
+    public static final int SSH_FILEXFER_TYPE_CHAR_DEVICE =  7; // v5
+    public static final int SSH_FILEXFER_TYPE_BLOCK_DEVICE = 8; // v5
+    public static final int SSH_FILEXFER_TYPE_FIFO         = 9; // v5
+
+    public static final int SSH_FXF_READ =   0x00000001;
+    public static final int SSH_FXF_WRITE =  0x00000002;
+    public static final int SSH_FXF_APPEND = 0x00000004;
+    public static final int SSH_FXF_CREAT =  0x00000008;
+    public static final int SSH_FXF_TRUNC =  0x00000010;
+    public static final int SSH_FXF_EXCL =   0x00000020;
+    public static final int SSH_FXF_TEXT =   0x00000040;
+
+    public static final int SSH_FXF_ACCESS_DISPOSITION = 0x00000007;
+    public static final int SSH_FXF_CREATE_NEW =         0x00000000;
+    public static final int SSH_FXF_CREATE_TRUNCATE =    0x00000001;
+    public static final int SSH_FXF_OPEN_EXISTING =      0x00000002;
+    public static final int SSH_FXF_OPEN_OR_CREATE =     0x00000003;
+    public static final int SSH_FXF_TRUNCATE_EXISTING =  0x00000004;
+    public static final int SSH_FXF_APPEND_DATA =        0x00000008;
+    public static final int SSH_FXF_APPEND_DATA_ATOMIC = 0x00000010;
+    public static final int SSH_FXF_TEXT_MODE =          0x00000020;
+    public static final int SSH_FXF_READ_LOCK =          0x00000040;
+    public static final int SSH_FXF_WRITE_LOCK =         0x00000080;
+    public static final int SSH_FXF_DELETE_LOCK =        0x00000100;
+
+    public static final int SSH_FXP_RENAME_OVERWRITE = 0x00000001;
+    public static final int SSH_FXP_RENAME_ATOMIC =    0x00000002;
+    public static final int SSH_FXP_RENAME_NATIVE =    0x00000004;
+
+    public static final int SSH_FXP_REALPATH_NO_CHECK    = 0x00000001;
+    public static final int SSH_FXP_REALPATH_STAT_IF     = 0x00000002;
+    public static final int SSH_FXP_REALPATH_STAT_ALWAYS = 0x00000003;
+
+    public static final int SSH_FXF_RENAME_OVERWRITE =  0x00000001;
+    public static final int SSH_FXF_RENAME_ATOMIC =     0x00000002;
+    public static final int SSH_FXF_RENAME_NATIVE =     0x00000004;
+
+    public static final int ACE4_ACCESS_ALLOWED_ACE_TYPE      = 0x00000000;
+    public static final int ACE4_ACCESS_DENIED_ACE_TYPE       = 0x00000001;
+    public static final int ACE4_SYSTEM_AUDIT_ACE_TYPE        = 0x00000002;
+    public static final int ACE4_SYSTEM_ALARM_ACE_TYPE        = 0x00000003;
+
+    public static final int ACE4_FILE_INHERIT_ACE             = 0x00000001;
+    public static final int ACE4_DIRECTORY_INHERIT_ACE        = 0x00000002;
+    public static final int ACE4_NO_PROPAGATE_INHERIT_ACE     = 0x00000004;
+    public static final int ACE4_INHERIT_ONLY_ACE             = 0x00000008;
+    public static final int ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
+    public static final int ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
+    public static final int ACE4_IDENTIFIER_GROUP             = 0x00000040;
+
+    public static final int ACE4_READ_DATA            = 0x00000001;
+    public static final int ACE4_LIST_DIRECTORY       = 0x00000001;
+    public static final int ACE4_WRITE_DATA           = 0x00000002;
+    public static final int ACE4_ADD_FILE             = 0x00000002;
+    public static final int ACE4_APPEND_DATA          = 0x00000004;
+    public static final int ACE4_ADD_SUBDIRECTORY     = 0x00000004;
+    public static final int ACE4_READ_NAMED_ATTRS     = 0x00000008;
+    public static final int ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
+    public static final int ACE4_EXECUTE              = 0x00000020;
+    public static final int ACE4_DELETE_CHILD         = 0x00000040;
+    public static final int ACE4_READ_ATTRIBUTES      = 0x00000080;
+    public static final int ACE4_WRITE_ATTRIBUTES     = 0x00000100;
+    public static final int ACE4_DELETE               = 0x00010000;
+    public static final int ACE4_READ_ACL             = 0x00020000;
+    public static final int ACE4_WRITE_ACL            = 0x00040000;
+    public static final int ACE4_WRITE_OWNER          = 0x00080000;
+    public static final int ACE4_SYNCHRONIZE          = 0x00100000;
+
+    public static final int S_IFMT =   0170000;  // bitmask for the file type bitfields
+    public static final int S_IFSOCK = 0140000;  // socket
+    public static final int S_IFLNK =  0120000;  // symbolic link
+    public static final int S_IFREG =  0100000;  // regular file
+    public static final int S_IFBLK =  0060000;  // block device
+    public static final int S_IFDIR =  0040000;  // directory
+    public static final int S_IFCHR =  0020000;  // character device
+    public static final int S_IFIFO =  0010000;  // fifo
+    public static final int S_ISUID =  0004000;  // set UID bit
+    public static final int S_ISGID =  0002000;  // set GID bit
+    public static final int S_ISVTX =  0001000;  // sticky bit
+    public static final int S_IRUSR =  0000400;
+    public static final int S_IWUSR =  0000200;
+    public static final int S_IXUSR =  0000100;
+    public static final int S_IRGRP =  0000040;
+    public static final int S_IWGRP =  0000020;
+    public static final int S_IXGRP =  0000010;
+    public static final int S_IROTH =  0000004;
+    public static final int S_IWOTH =  0000002;
+    public static final int S_IXOTH =  0000001;
+
+    public static int SFTP_V3 = 3;
+    public static int SFTP_V4 = 4;
+    public static int SFTP_V5 = 5;
+    public static int SFTP_V6 = 6;
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6debaf59/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
index 16fc902..721fe8a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
@@ -90,6 +90,8 @@ import org.apache.sshd.server.session.ServerSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.sshd.common.sftp.SftpConstants.*;
+
 /**
  * SFTP subsystem
  *
@@ -174,203 +176,6 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
     public static final String ALL_SFTP_IMPL = "3,4,5,6";
     public static final int  MAX_PACKET_LENGTH = 1024 * 16;
 
-    public static final int SSH_FXP_INIT =             1;
-    public static final int SSH_FXP_VERSION =          2;
-    public static final int SSH_FXP_OPEN =             3;
-    public static final int SSH_FXP_CLOSE =            4;
-    public static final int SSH_FXP_READ =             5;
-    public static final int SSH_FXP_WRITE =            6;
-    public static final int SSH_FXP_LSTAT =            7;
-    public static final int SSH_FXP_FSTAT =            8;
-    public static final int SSH_FXP_SETSTAT =          9;
-    public static final int SSH_FXP_FSETSTAT =        10;
-    public static final int SSH_FXP_OPENDIR =         11;
-    public static final int SSH_FXP_READDIR =         12;
-    public static final int SSH_FXP_REMOVE =          13;
-    public static final int SSH_FXP_MKDIR =           14;
-    public static final int SSH_FXP_RMDIR =           15;
-    public static final int SSH_FXP_REALPATH =        16;
-    public static final int SSH_FXP_STAT =            17;
-    public static final int SSH_FXP_RENAME =          18;
-    public static final int SSH_FXP_READLINK =        19;
-    public static final int SSH_FXP_SYMLINK =         20; // v3 -> v5
-    public static final int SSH_FXP_LINK =            21; // v6
-    public static final int SSH_FXP_BLOCK =           22; // v6
-    public static final int SSH_FXP_UNBLOCK =         23; // v6
-    public static final int SSH_FXP_STATUS =         101;
-    public static final int SSH_FXP_HANDLE =         102;
-    public static final int SSH_FXP_DATA =           103;
-    public static final int SSH_FXP_NAME =           104;
-    public static final int SSH_FXP_ATTRS =          105;
-    public static final int SSH_FXP_EXTENDED =       200;
-    public static final int SSH_FXP_EXTENDED_REPLY = 201;
-
-    public static final int SSH_FX_OK =                           0;
-    public static final int SSH_FX_EOF =                          1;
-    public static final int SSH_FX_NO_SUCH_FILE =                 2;
-    public static final int SSH_FX_PERMISSION_DENIED =            3;
-    public static final int SSH_FX_FAILURE =                      4;
-    public static final int SSH_FX_BAD_MESSAGE =                  5;
-    public static final int SSH_FX_NO_CONNECTION =                6;
-    public static final int SSH_FX_CONNECTION_LOST =              7;
-    public static final int SSH_FX_OP_UNSUPPORTED =               8;
-    public static final int SSH_FX_INVALID_HANDLE =               9;
-    public static final int SSH_FX_NO_SUCH_PATH =                10;
-    public static final int SSH_FX_FILE_ALREADY_EXISTS =         11;
-    public static final int SSH_FX_WRITE_PROTECT =               12;
-    public static final int SSH_FX_NO_MEDIA =                    13;
-    public static final int SSH_FX_NO_SPACE_ON_FILESYSTEM =      14;
-    public static final int SSH_FX_QUOTA_EXCEEDED =              15;
-    public static final int SSH_FX_UNKNOWN_PRINCIPLE =           16;
-    public static final int SSH_FX_LOCK_CONFLICT =               17;
-    public static final int SSH_FX_DIR_NOT_EMPTY =               18;
-    public static final int SSH_FX_NOT_A_DIRECTORY =             19;
-    public static final int SSH_FX_INVALID_FILENAME =            20;
-    public static final int SSH_FX_LINK_LOOP =                   21;
-    public static final int SSH_FX_CANNOT_DELETE =               22;
-    public static final int SSH_FX_INVALID_PARAMETER =           23;
-    public static final int SSH_FX_FILE_IS_A_DIRECTORY =         24;
-    public static final int SSH_FX_BYTE_RANGE_LOCK_CONFLICT =    25;
-    public static final int SSH_FX_BYTE_RANGE_LOCK_REFUSED =     26;
-    public static final int SSH_FX_DELETE_PENDING =              27;
-    public static final int SSH_FX_FILE_CORRUPT =                28;
-    public static final int SSH_FX_OWNER_INVALID =               29;
-    public static final int SSH_FX_GROUP_INVALID =               30;
-    public static final int SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK = 31;
-
-    public static final int SSH_FILEXFER_ATTR_SIZE =              0x00000001;
-    public static final int SSH_FILEXFER_ATTR_UIDGID =            0x00000002;
-    public static final int SSH_FILEXFER_ATTR_PERMISSIONS =       0x00000004;
-    public static final int SSH_FILEXFER_ATTR_ACMODTIME =         0x00000008; // v3 naming convention
-    public static final int SSH_FILEXFER_ATTR_ACCESSTIME =        0x00000008; // v4
-    public static final int SSH_FILEXFER_ATTR_CREATETIME =        0x00000010; // v4
-    public static final int SSH_FILEXFER_ATTR_MODIFYTIME =        0x00000020; // v4
-    public static final int SSH_FILEXFER_ATTR_ACL =               0x00000040; // v4
-    public static final int SSH_FILEXFER_ATTR_OWNERGROUP =        0x00000080; // v4
-    public static final int SSH_FILEXFER_ATTR_SUBSECOND_TIMES =   0x00000100; // v5
-    public static final int SSH_FILEXFER_ATTR_BITS =              0x00000200; // v5
-    public static final int SSH_FILEXFER_ATTR_ALLOCATION_SIZE =   0x00000400; // v6
-    public static final int SSH_FILEXFER_ATTR_TEXT_HINT =         0x00000800; // v6
-    public static final int SSH_FILEXFER_ATTR_MIME_TYPE =         0x00001000; // v6
-    public static final int SSH_FILEXFER_ATTR_LINK_COUNT =        0x00002000; // v6
-    public static final int SSH_FILEXFER_ATTR_UNTRANSLATED_NAME = 0x00004000; // v6
-    public static final int SSH_FILEXFER_ATTR_CTIME =             0x00008000; // v6
-    public static final int SSH_FILEXFER_ATTR_EXTENDED =          0x80000000;
-
-    public static final int SSH_FILEXFER_ATTR_ALL =               0x0000FFFF; // All attributes
-
-    public static final int SSH_FILEXFER_ATTR_FLAGS_READONLY =         0x00000001;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_SYSTEM =           0x00000002;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_HIDDEN =           0x00000004;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_CASE_INSENSITIVE = 0x00000008;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_ARCHIVE =          0x00000010;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_ENCRYPTED =        0x00000020;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_COMPRESSED =       0x00000040;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_SPARSE =           0x00000080;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_APPEND_ONLY =      0x00000100;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_IMMUTABLE =        0x00000200;
-    public static final int SSH_FILEXFER_ATTR_FLAGS_SYNC =             0x00000400;
-
-    public static final int SSH_FILEXFER_TYPE_REGULAR =      1;
-    public static final int SSH_FILEXFER_TYPE_DIRECTORY =    2;
-    public static final int SSH_FILEXFER_TYPE_SYMLINK =      3;
-    public static final int SSH_FILEXFER_TYPE_SPECIAL =      4;
-    public static final int SSH_FILEXFER_TYPE_UNKNOWN =      5;
-    public static final int SSH_FILEXFER_TYPE_SOCKET =       6; // v5
-    public static final int SSH_FILEXFER_TYPE_CHAR_DEVICE =  7; // v5
-    public static final int SSH_FILEXFER_TYPE_BLOCK_DEVICE = 8; // v5
-    public static final int SSH_FILEXFER_TYPE_FIFO         = 9; // v5
-
-    public static final int SSH_FXF_READ =   0x00000001;
-    public static final int SSH_FXF_WRITE =  0x00000002;
-    public static final int SSH_FXF_APPEND = 0x00000004;
-    public static final int SSH_FXF_CREAT =  0x00000008;
-    public static final int SSH_FXF_TRUNC =  0x00000010;
-    public static final int SSH_FXF_EXCL =   0x00000020;
-    public static final int SSH_FXF_TEXT =   0x00000040;
-
-    public static final int SSH_FXF_ACCESS_DISPOSITION = 0x00000007;
-    public static final int SSH_FXF_CREATE_NEW =         0x00000000;
-    public static final int SSH_FXF_CREATE_TRUNCATE =    0x00000001;
-    public static final int SSH_FXF_OPEN_EXISTING =      0x00000002;
-    public static final int SSH_FXF_OPEN_OR_CREATE =     0x00000003;
-    public static final int SSH_FXF_TRUNCATE_EXISTING =  0x00000004;
-    public static final int SSH_FXF_APPEND_DATA =        0x00000008;
-    public static final int SSH_FXF_APPEND_DATA_ATOMIC = 0x00000010;
-    public static final int SSH_FXF_TEXT_MODE =          0x00000020;
-    public static final int SSH_FXF_READ_LOCK =          0x00000040;
-    public static final int SSH_FXF_WRITE_LOCK =         0x00000080;
-    public static final int SSH_FXF_DELETE_LOCK =        0x00000100;
-
-    public static final int SSH_FXP_RENAME_OVERWRITE = 0x00000001;
-    public static final int SSH_FXP_RENAME_ATOMIC =    0x00000002;
-    public static final int SSH_FXP_RENAME_NATIVE =    0x00000004;
-
-    public static final int SSH_FXP_REALPATH_NO_CHECK    = 0x00000001;
-    public static final int SSH_FXP_REALPATH_STAT_IF     = 0x00000002;
-    public static final int SSH_FXP_REALPATH_STAT_ALWAYS = 0x00000003;
-
-    public static final int SSH_FXF_RENAME_OVERWRITE =  0x00000001;
-    public static final int SSH_FXF_RENAME_ATOMIC =     0x00000002;
-    public static final int SSH_FXF_RENAME_NATIVE =     0x00000004;
-
-    public static final int ACE4_ACCESS_ALLOWED_ACE_TYPE      = 0x00000000;
-    public static final int ACE4_ACCESS_DENIED_ACE_TYPE       = 0x00000001;
-    public static final int ACE4_SYSTEM_AUDIT_ACE_TYPE        = 0x00000002;
-    public static final int ACE4_SYSTEM_ALARM_ACE_TYPE        = 0x00000003;
-
-    public static final int ACE4_FILE_INHERIT_ACE             = 0x00000001;
-    public static final int ACE4_DIRECTORY_INHERIT_ACE        = 0x00000002;
-    public static final int ACE4_NO_PROPAGATE_INHERIT_ACE     = 0x00000004;
-    public static final int ACE4_INHERIT_ONLY_ACE             = 0x00000008;
-    public static final int ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
-    public static final int ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
-    public static final int ACE4_IDENTIFIER_GROUP             = 0x00000040;
-
-    public static final int ACE4_READ_DATA            = 0x00000001;
-    public static final int ACE4_LIST_DIRECTORY       = 0x00000001;
-    public static final int ACE4_WRITE_DATA           = 0x00000002;
-    public static final int ACE4_ADD_FILE             = 0x00000002;
-    public static final int ACE4_APPEND_DATA          = 0x00000004;
-    public static final int ACE4_ADD_SUBDIRECTORY     = 0x00000004;
-    public static final int ACE4_READ_NAMED_ATTRS     = 0x00000008;
-    public static final int ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
-    public static final int ACE4_EXECUTE              = 0x00000020;
-    public static final int ACE4_DELETE_CHILD         = 0x00000040;
-    public static final int ACE4_READ_ATTRIBUTES      = 0x00000080;
-    public static final int ACE4_WRITE_ATTRIBUTES     = 0x00000100;
-    public static final int ACE4_DELETE               = 0x00010000;
-    public static final int ACE4_READ_ACL             = 0x00020000;
-    public static final int ACE4_WRITE_ACL            = 0x00040000;
-    public static final int ACE4_WRITE_OWNER          = 0x00080000;
-    public static final int ACE4_SYNCHRONIZE          = 0x00100000;
-
-    public static final int S_IFMT =   0170000;  // bitmask for the file type bitfields
-    public static final int S_IFSOCK = 0140000;  // socket
-    public static final int S_IFLNK =  0120000;  // symbolic link
-    public static final int S_IFREG =  0100000;  // regular file
-    public static final int S_IFBLK =  0060000;  // block device
-    public static final int S_IFDIR =  0040000;  // directory
-    public static final int S_IFCHR =  0020000;  // character device
-    public static final int S_IFIFO =  0010000;  // fifo
-    public static final int S_ISUID =  0004000;  // set UID bit
-    public static final int S_ISGID =  0002000;  // set GID bit
-    public static final int S_ISVTX =  0001000;  // sticky bit
-    public static final int S_IRUSR =  0000400;
-    public static final int S_IWUSR =  0000200;
-    public static final int S_IXUSR =  0000100;
-    public static final int S_IRGRP =  0000040;
-    public static final int S_IWGRP =  0000020;
-    public static final int S_IXGRP =  0000010;
-    public static final int S_IROTH =  0000004;
-    public static final int S_IWOTH =  0000002;
-    public static final int S_IXOTH =  0000001;
-
-    public static int SFTP_V3 = 3;
-    public static int SFTP_V4 = 4;
-    public static int SFTP_V5 = 5;
-    public static int SFTP_V6 = 6;
-
     private ExitCallback callback;
     private InputStream in;
     private OutputStream out;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6debaf59/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SftpTest.java b/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
index 78cb70a..e39bd57 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
@@ -33,7 +33,6 @@ import com.jcraft.jsch.ChannelSftp;
 import com.jcraft.jsch.JSch;
 import com.jcraft.jsch.SftpException;
 import org.apache.sshd.client.SftpClient;
-import org.apache.sshd.client.sftp.DefaultSftpClient;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.util.Buffer;
 import org.apache.sshd.common.util.OsUtils;
@@ -52,7 +51,16 @@ import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.apache.sshd.common.sftp.SftpConstants.SSH_FX_FILE_ALREADY_EXISTS;
+import static org.apache.sshd.common.sftp.SftpConstants.SSH_FX_NO_SUCH_FILE;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IRUSR;
+import static org.apache.sshd.common.sftp.SftpConstants.S_IWUSR;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 public class SftpTest extends BaseTest {
 
@@ -143,7 +151,7 @@ public class SftpTest extends BaseTest {
         
                 // NOTE: on Windows files are always readable
                 int	perms=sftp.stat(file).perms;
-                int	permsMask=SftpClient.S_IWUSR | (isWindows ? 0 : SftpClient.S_IRUSR);
+                int	permsMask=S_IWUSR | (isWindows ? 0 : S_IRUSR);
                 Assert.assertEquals("Mismatched permissions - 0x" + Integer.toHexString(perms), 0, (perms & permsMask));
         
                 javaFile.setWritable(true, false);
@@ -474,7 +482,7 @@ public class SftpTest extends BaseTest {
             sftp.rename("target/sftp/test2.txt", "target/sftp/test3.txt");
             fail("Expected an SftpException");
         } catch (org.apache.sshd.client.SftpException e) {
-            assertEquals(DefaultSftpClient.SSH_FX_NO_SUCH_FILE, e.getStatus());
+            assertEquals(SSH_FX_NO_SUCH_FILE, e.getStatus());
         }
 
         try (OutputStream os = sftp.write("target/sftp/test2.txt")) {
@@ -485,7 +493,7 @@ public class SftpTest extends BaseTest {
             sftp.rename("target/sftp/test.txt", "target/sftp/test2.txt");
             fail("Expected an SftpException");
         } catch (org.apache.sshd.client.SftpException e) {
-            assertEquals(DefaultSftpClient.SSH_FX_FILE_ALREADY_EXISTS, e.getStatus());
+            assertEquals(SSH_FX_FILE_ALREADY_EXISTS, e.getStatus());
         }
         sftp.rename("target/sftp/test.txt", "target/sftp/test2.txt", SftpClient.CopyMode.Overwrite);
     }


[2/4] mina-sshd git commit: [SSHD-429] Take into account local file separator when sending/receiving files via SCP

Posted by gn...@apache.org.
[SSHD-429] Take into account local file separator when sending/receiving files via SCP


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/043c7df2
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/043c7df2
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/043c7df2

Branch: refs/heads/master
Commit: 043c7df206e95181137498b63d4cfab3d9cebe12
Parents: 6debaf5
Author: Guillaume Nodet <gn...@apache.org>
Authored: Tue Mar 17 12:07:46 2015 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Tue Mar 17 12:07:46 2015 +0100

----------------------------------------------------------------------
 .../java/org/apache/sshd/common/scp/ScpHelper.java  | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/043c7df2/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
index d73be2a..c5f6ae6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
@@ -20,6 +20,7 @@ package org.apache.sshd.common.scp;
 
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
+import java.io.File;
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -161,7 +162,8 @@ public class ScpHelper {
         }
         Path file;
         if (Files.exists(path) && Files.isDirectory(path)) {
-            file = path.resolve(name);
+            String localName = name.replace('/', File.separatorChar);
+            file = path.resolve(localName);
         } else if (!Files.exists(path) && Files.exists(path.getParent()) && Files.isDirectory(path.getParent())) {
             file = path;
         } else {
@@ -242,7 +244,8 @@ public class ScpHelper {
 
         Path file;
         if (Files.exists(path) && Files.isDirectory(path)) {
-            file = path.resolve(name);
+            String localName = name.replace('/', File.separatorChar);
+            file = path.resolve(localName);
         } else if (Files.exists(path) && Files.isRegularFile(path)) {
             file = path;
         } else if (!Files.exists(path) && Files.exists(path.getParent()) && Files.isDirectory(path.getParent())) {
@@ -310,7 +313,7 @@ public class ScpHelper {
                 }
                 String[] included = new DirectoryScanner(basedir, pattern).scan();
                 for (String path : included) {
-                    Path file = fileSystem.getPath(basedir + "/" + path);
+                    Path file = resolveLocalPath(basedir + "/" + path);
                     if (Files.isRegularFile(file)) {
                         sendFile(file, preserve, bufferSize);
                     } else if (Files.isDirectory(file)) {
@@ -332,7 +335,7 @@ public class ScpHelper {
                     basedir = pattern.substring(0, lastSep);
                     pattern = pattern.substring(lastSep + 1);
                 }
-                Path file = fileSystem.getPath(basedir + "/" + pattern);
+                Path file = resolveLocalPath(basedir + "/" + pattern);
                 if (!Files.exists(file)) {
                     throw new IOException(file + ": no such file or directory");
                 }
@@ -351,6 +354,11 @@ public class ScpHelper {
         }
     }
 
+    protected Path resolveLocalPath(String path) {
+        String localPath = (path == null) ? null : path.replace('/', File.separatorChar);
+        return fileSystem.getPath(localPath);
+    }
+
     public void sendFile(Path path, boolean preserve, int bufferSize) throws IOException {
         if (log.isDebugEnabled()) {
             log.debug("Sending file {}", path);


[4/4] mina-sshd git commit: [SSHD-431] Use a Builder to initialize and create an SftpSubsystem Factory

Posted by gn...@apache.org.
[SSHD-431] Use a Builder to initialize and create an SftpSubsystem Factory

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/4039a11a
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/4039a11a
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/4039a11a

Branch: refs/heads/master
Commit: 4039a11ae5ee37a4ee90157123d7c7f0f8b4d434
Parents: eac1704
Author: Guillaume Nodet <gn...@apache.org>
Authored: Tue Mar 17 18:21:19 2015 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Tue Mar 17 18:35:19 2015 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/sshd/SshServer.java    |   4 +-
 .../apache/sshd/server/sftp/SftpSubsystem.java  |  91 ++-----------
 .../sshd/server/sftp/SftpSubsystemFactory.java  | 130 +++++++++++++++++++
 .../server/sftp/UnsupportedAttributePolicy.java |  36 +++++
 .../test/java/org/apache/sshd/ServerTest.java   |   4 +-
 .../org/apache/sshd/SftpFileSystemTest.java     |  12 +-
 .../src/test/java/org/apache/sshd/SftpTest.java |  16 +--
 .../server/sftp/SftpSubsystemFactoryTest.java   |  96 ++++++++++++++
 .../sshd/git/pack/GitPackCommandTest.java       |   3 +-
 .../apache/sshd/git/pgm/GitPgmCommandTest.java  |   3 +-
 10 files changed, 296 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/main/java/org/apache/sshd/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/SshServer.java
index e72750d..a98f5b0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/SshServer.java
@@ -64,7 +64,7 @@ import org.apache.sshd.server.session.ServerConnectionService;
 import org.apache.sshd.server.session.ServerSession;
 import org.apache.sshd.server.session.ServerUserAuthService;
 import org.apache.sshd.server.session.SessionFactory;
-import org.apache.sshd.server.sftp.SftpSubsystem;
+import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.apache.sshd.server.shell.ProcessShellFactory;
 
 /**
@@ -483,7 +483,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
                 return new ProcessShellFactory(command.split(" "), ttyOptions).create();
             }
         }).build());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.start();
 
         Thread.sleep(Long.MAX_VALUE);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
index 721fe8a..77f09b5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
@@ -75,7 +75,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.file.FileSystemAware;
 import org.apache.sshd.common.util.Buffer;
 import org.apache.sshd.common.util.IoUtils;
@@ -101,66 +100,6 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
 
     protected final Logger log = LoggerFactory.getLogger(getClass());
 
-    public static class Factory implements NamedFactory<Command> {
-
-        public static final String NAME = "sftp";
-
-    	private final ExecutorService	executors;
-    	private final boolean shutdownExecutor;
-
-    	public Factory() {
-    		this(null);
-    	}
-
-        /**
-         * @param executorService The {@link ExecutorService} to be used by
-         *                        the {@link SftpSubsystem} command when starting execution. If
-         *                        {@code null} then a single-threaded ad-hoc service is used.
-         *                        <B>Note:</B> the service will <U>not</U> be shutdown when the
-         *                        subsystem is closed - unless it is the ad-hoc service, which will be
-         *                        shutdown regardless
-         * @see Factory(ExecutorService, boolean)}
-         */
-        public Factory(ExecutorService executorService) {
-        	this(executorService, false);
-        }
-
-        /**
-         * @param executorService The {@link ExecutorService} to be used by
-         *                        the {@link SftpSubsystem} command when starting execution. If
-         *                        {@code null} then a single-threaded ad-hoc service is used.
-         * @param shutdownOnExit  If {@code true} the {@link ExecutorService#shutdownNow()}
-         *                        will be called when subsystem terminates - unless it is the ad-hoc
-         *                        service, which will be shutdown regardless
-         */
-        public Factory(ExecutorService executorService, boolean shutdownOnExit) {
-        	executors = executorService;
-        	shutdownExecutor = shutdownOnExit;
-        }
-
-        public ExecutorService getExecutorService() {
-        	return executors;
-        }
-        
-        public boolean isShutdownOnExit() {
-        	return shutdownExecutor;
-        }
-
-        public Command create() {
-            return new SftpSubsystem(getExecutorService(), isShutdownOnExit());
-        }
-
-        public String getName() {
-            return NAME;
-        }
-    }
-
-    public enum UnsupportedAttributePolicy {
-        Ignore,
-        Warn,
-        ThrowException
-    }
-
     /**
      * Properties key for the maximum of available open handles per session.
      */
@@ -194,7 +133,7 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
     private final Map<String, byte[]> extensions = new HashMap<>();
     private final Map<String, Handle> handles = new HashMap<>();
 
-    private UnsupportedAttributePolicy unsupportedAttributePolicy = UnsupportedAttributePolicy.Warn;
+    private final UnsupportedAttributePolicy unsupportedAttributePolicy;
 
     protected static abstract class Handle implements java.io.Closeable {
         private Path file;
@@ -378,22 +317,6 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
         }
     }
 
-    public SftpSubsystem() {
-        this(null);
-    }
-
-    /**
-     * @param executorService The {@link ExecutorService} to be used by
-     *                        the {@link SftpSubsystem} command when starting execution. If
-     *                        {@code null} then a single-threaded ad-hoc service is used.
-     *                        <b>Note:</b> the service will <U>not</U> be shutdown when the
-     *                        subsystem is closed - unless it is the ad-hoc service
-     * @see #SftpSubsystem(ExecutorService, boolean)
-     */
-    public SftpSubsystem(ExecutorService executorService) {
-        this(executorService, false);
-    }
-
     /**
      * @param executorService The {@link ExecutorService} to be used by
      *                        the {@link SftpSubsystem} command when starting execution. If
@@ -401,15 +324,25 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
      * @param shutdownOnExit  If {@code true} the {@link ExecutorService#shutdownNow()}
      *                        will be called when subsystem terminates - unless it is the ad-hoc
      *                        service, which will be shutdown regardless
+     * @param policy The {@link UnsupportedAttributePolicy} to use if failed to access
+     * some local file attributes
      * @see ThreadUtils#newSingleThreadExecutor(String)
      */
-    public SftpSubsystem(ExecutorService executorService, boolean shutdownOnExit) {
+    public SftpSubsystem(ExecutorService executorService, boolean shutdownOnExit, UnsupportedAttributePolicy policy) {
         if ((executors = executorService) == null) {
             executors = ThreadUtils.newSingleThreadExecutor(getClass().getSimpleName());
             shutdownExecutor = true;    // we always close the ad-hoc executor service
         } else {
             shutdownExecutor = shutdownOnExit;
         }
+        
+        if ((unsupportedAttributePolicy=policy) == null) {
+            throw new IllegalArgumentException("No policy provided");
+        }
+    }
+
+    public final UnsupportedAttributePolicy getUnsupportedAttributePolicy() {
+        return unsupportedAttributePolicy;
     }
 
     public void setSession(ServerSession session) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystemFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystemFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystemFactory.java
new file mode 100644
index 0000000..2b98fb3
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystemFactory.java
@@ -0,0 +1,130 @@
+/*
+ * 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 org.apache.sshd.server.sftp;
+
+import java.util.concurrent.ExecutorService;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.util.ObjectBuilder;
+import org.apache.sshd.server.Command;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class SftpSubsystemFactory implements NamedFactory<Command>, Cloneable {
+    public static final String NAME = "sftp";
+    public static final UnsupportedAttributePolicy DEFAULT_POLICY = UnsupportedAttributePolicy.Warn;
+
+    public static class Builder implements ObjectBuilder<SftpSubsystemFactory> {
+        private final SftpSubsystemFactory factory = new SftpSubsystemFactory();
+
+        public Builder() {
+            super();
+        }
+
+        public Builder withExecutorService(ExecutorService service) {
+            factory.setExecutorService(service);
+            return this;
+        }
+
+        public Builder withShutdownOnExit(boolean shutdown) {
+            factory.setShutdownOnExit(shutdown);
+            return this;
+        }
+
+        public Builder withUnsupportedAttributePolicy(UnsupportedAttributePolicy p) {
+            factory.setUnsupportedAttributePolicy(p);
+            return this;
+        }
+
+        public SftpSubsystemFactory build() {
+            // return a clone so that each invocation returns a different instance - avoid shared instances
+            return factory.clone();
+        }
+    }
+
+    private ExecutorService executors;
+    private boolean shutdownExecutor;
+    private UnsupportedAttributePolicy policy = DEFAULT_POLICY;
+
+    public SftpSubsystemFactory() {
+        super();
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public ExecutorService getExecutorService() {
+        return executors;
+    }
+
+    /**
+     * @param service The {@link ExecutorService} to be used by the {@link SftpSubsystem}
+     *                command when starting execution. If {@code null} then a single-threaded ad-hoc service is used.
+     */
+    public void setExecutorService(ExecutorService service) {
+        executors = service;
+    }
+
+    public boolean isShutdownOnExit() {
+        return shutdownExecutor;
+    }
+
+    /**
+     * @param shutdownOnExit If {@code true} the {@link ExecutorService#shutdownNow()}
+     *                       will be called when subsystem terminates - unless it is the ad-hoc service, which
+     *                       will be shutdown regardless
+     */
+    public void setShutdownOnExit(boolean shutdownOnExit) {
+        shutdownExecutor = shutdownOnExit;
+    }
+
+    public UnsupportedAttributePolicy getUnsupportedAttributePolicy() {
+        return policy;
+    }
+
+    /**
+     * @param p The {@link UnsupportedAttributePolicy} to use if failed to access
+     *          some local file attributes
+     */
+    public void setUnsupportedAttributePolicy(UnsupportedAttributePolicy p) {
+        if (p == null) {
+            throw new IllegalArgumentException("No policy provided");
+        }
+
+        policy = p;
+    }
+
+    public Command create() {
+        return new SftpSubsystem(getExecutorService(), isShutdownOnExit(), getUnsupportedAttributePolicy());
+    }
+
+    @Override
+    public SftpSubsystemFactory clone() {
+        try {
+            return getClass().cast(super.clone());  // shallow clone is good enough
+        } catch (CloneNotSupportedException e) {
+            throw new UnsupportedOperationException("Unexpected clone exception", e);   // unexpected since we implement cloneable
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/main/java/org/apache/sshd/server/sftp/UnsupportedAttributePolicy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/sftp/UnsupportedAttributePolicy.java b/sshd-core/src/main/java/org/apache/sshd/server/sftp/UnsupportedAttributePolicy.java
new file mode 100644
index 0000000..f9a1472
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/sftp/UnsupportedAttributePolicy.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.sshd.server.sftp;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public enum UnsupportedAttributePolicy {
+    Ignore,
+    Warn,
+    ThrowException;
+
+    public static final Set<UnsupportedAttributePolicy> VALUES =
+            Collections.unmodifiableSet(EnumSet.allOf(UnsupportedAttributePolicy.class));
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/ServerTest.java b/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
index 8e2ccee..3c7e5bb 100644
--- a/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
@@ -55,7 +55,7 @@ import org.apache.sshd.server.CommandFactory;
 import org.apache.sshd.server.Environment;
 import org.apache.sshd.server.ExitCallback;
 import org.apache.sshd.server.command.ScpCommandFactory;
-import org.apache.sshd.server.sftp.SftpSubsystem;
+import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.apache.sshd.util.BaseTest;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
@@ -419,7 +419,7 @@ public class ServerTest extends BaseTest {
         sshd.getProperties().put(SshServer.IDLE_TIMEOUT, "10000");
         sshd.setPort(8001);
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setCommandFactory(new ScpCommandFactory());
         sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/test/java/org/apache/sshd/SftpFileSystemTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SftpFileSystemTest.java b/sshd-core/src/test/java/org/apache/sshd/SftpFileSystemTest.java
index f550045..2eb9309 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SftpFileSystemTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SftpFileSystemTest.java
@@ -18,6 +18,10 @@
  */
 package org.apache.sshd;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
@@ -46,7 +50,7 @@ import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.util.OsUtils;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.command.ScpCommandFactory;
-import org.apache.sshd.server.sftp.SftpSubsystem;
+import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.apache.sshd.util.BaseTest;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
@@ -55,10 +59,6 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 public class SftpFileSystemTest extends BaseTest {
 
     private SshServer sshd;
@@ -68,7 +68,7 @@ public class SftpFileSystemTest extends BaseTest {
     public void setUp() throws Exception {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setCommandFactory(new ScpCommandFactory());
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SftpTest.java b/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
index e39bd57..c2b4832 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SftpTest.java
@@ -38,7 +38,7 @@ import org.apache.sshd.common.util.Buffer;
 import org.apache.sshd.common.util.OsUtils;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.command.ScpCommandFactory;
-import org.apache.sshd.server.sftp.SftpSubsystem;
+import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.apache.sshd.util.BaseTest;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
@@ -72,7 +72,7 @@ public class SftpTest extends BaseTest {
     public void setUp() throws Exception {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setCommandFactory(new ScpCommandFactory());
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
@@ -125,7 +125,7 @@ public class SftpTest extends BaseTest {
                     h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Read));
                     // NOTE: on Windows files are always readable
                     // see https://svn.apache.org/repos/asf/harmony/enhanced/java/branches/java6/classlib/modules/luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java
-                    Assert.assertTrue("Empty read should have failed", isWindows);
+                    assertTrue("Empty read should have failed", isWindows);
                     sftp.close(h);
                 } catch (IOException e) {
                     if (isWindows) {
@@ -139,20 +139,20 @@ public class SftpTest extends BaseTest {
                 } catch (IOException e) {
                     // ok
                 }
-        
+
                 try {
                     h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Truncate));
                     // NOTE: on Windows files are always readable
-                    Assert.assertTrue("Empty truncate should have failed", isWindows);
+                    assertTrue("Empty truncate should have failed", isWindows);
                     sftp.close(h);
                 } catch (IOException e) {
                     // ok
                 }
-        
+
                 // NOTE: on Windows files are always readable
                 int	perms=sftp.stat(file).perms;
                 int	permsMask=S_IWUSR | (isWindows ? 0 : S_IRUSR);
-                Assert.assertEquals("Mismatched permissions - 0x" + Integer.toHexString(perms), 0, (perms & permsMask));
+                assertEquals("Mismatched permissions - 0x" + Integer.toHexString(perms), 0, (perms & permsMask));
         
                 javaFile.setWritable(true, false);
         
@@ -174,7 +174,7 @@ public class SftpTest extends BaseTest {
                 try {
                     h = sftp.open(file, EnumSet.of(SftpClient.OpenMode.Read));
                     // NOTE: on Windows files are always readable
-                    Assert.assertTrue("Data read should have failed", isWindows);
+                    assertTrue("Data read should have failed", isWindows);
                     sftp.close(h);
                 } catch (IOException e) {
                     if (isWindows) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-core/src/test/java/org/apache/sshd/server/sftp/SftpSubsystemFactoryTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/sftp/SftpSubsystemFactoryTest.java b/sshd-core/src/test/java/org/apache/sshd/server/sftp/SftpSubsystemFactoryTest.java
new file mode 100644
index 0000000..dcd9fcb
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/server/sftp/SftpSubsystemFactoryTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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 org.apache.sshd.server.sftp;
+
+import java.util.concurrent.ExecutorService;
+
+import org.apache.sshd.util.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class SftpSubsystemFactoryTest extends BaseTest {
+    public SftpSubsystemFactoryTest() {
+        super();
+    }
+
+    /**
+     * Make sure that the builder returns a factory with the default values
+     * if no {@code withXXX} method is invoked
+     */
+    @Test
+    public void testBuilderDefaultFactoryValues() {
+        SftpSubsystemFactory factory = new SftpSubsystemFactory.Builder().build();
+        Assert.assertNull("Mismatched executor", factory.getExecutorService());
+        Assert.assertFalse("Mismatched shutdown state", factory.isShutdownOnExit());
+        Assert.assertSame("Mismatched unsupported attribute policy", SftpSubsystemFactory.DEFAULT_POLICY, factory.getUnsupportedAttributePolicy());
+    }
+
+    /**
+     * Make sure that the builder initializes correctly the built factory
+     */
+    @Test
+    public void testBuilderCorrectlyInitializesFactory() {
+        SftpSubsystemFactory.Builder builder = new SftpSubsystemFactory.Builder();
+        ExecutorService service = dummyExecutor();
+        SftpSubsystemFactory factory = builder.withExecutorService(service)
+                .withShutdownOnExit(true)
+                .build();
+        Assert.assertSame("Mismatched executor", service, factory.getExecutorService());
+        Assert.assertTrue("Mismatched shutdown state", factory.isShutdownOnExit());
+
+        for (UnsupportedAttributePolicy policy : UnsupportedAttributePolicy.VALUES) {
+            SftpSubsystemFactory actual = builder.withUnsupportedAttributePolicy(policy).build();
+            Assert.assertSame("Mismatched unsupported attribute policy", policy, actual.getUnsupportedAttributePolicy());
+        }
+    }
+
+    /**
+     * <UL>
+     * <LI>
+     * Make sure the builder returns new instances on every call to
+     * {@link SftpSubsystemFactory.Builder#build()} method
+     * </LI>
+     * <p/>
+     * <LI>
+     * Make sure values are preserved between successive invocations
+     * of the {@link SftpSubsystemFactory.Builder#build()} method
+     * </LI>
+     * </UL
+     */
+    @Test
+    public void testBuilderUniqueInstance() {
+        SftpSubsystemFactory.Builder builder = new SftpSubsystemFactory.Builder();
+        SftpSubsystemFactory f1 = builder.withExecutorService(dummyExecutor()).build();
+        SftpSubsystemFactory f2 = builder.build();
+        Assert.assertNotSame("No new instance built", f1, f2);
+        Assert.assertSame("Mismatched executors", f1.getExecutorService(), f2.getExecutorService());
+
+        SftpSubsystemFactory f3 = builder.withExecutorService(dummyExecutor()).build();
+        Assert.assertNotSame("Executor service not changed", f1.getExecutorService(), f3.getExecutorService());
+    }
+
+    private static ExecutorService dummyExecutor() {
+        return Mockito.mock(ExecutorService.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
index b27becb..fa3c5ec 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
@@ -30,6 +30,7 @@ import org.apache.sshd.git.util.EchoShellFactory;
 import org.apache.sshd.git.util.Utils;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.sftp.SftpSubsystem;
+import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.transport.CredentialsProvider;
 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
@@ -44,7 +45,7 @@ public class GitPackCommandTest {
         SshServer sshd = SshServer.setUpDefaultServer();
         sshd.setPort(8001);
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setCommandFactory(new GitPackCommandFactory("target/git/server"));
         sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4039a11a/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java b/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
index f45f60d..3d13af1 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
@@ -32,6 +32,7 @@ import org.apache.sshd.git.util.EchoShellFactory;
 import org.apache.sshd.git.util.Utils;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.sftp.SftpSubsystem;
+import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.eclipse.jgit.api.Git;
 import org.junit.Test;
 
@@ -50,7 +51,7 @@ public class GitPgmCommandTest {
         SshServer sshd = SshServer.setUpDefaultServer();
         sshd.setPort(8001);
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setCommandFactory(new GitPgmCommandFactory("target/git/pgm"));
         sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());


[3/4] mina-sshd git commit: [SSHD-430] Expose supported built-in ciphers as an Enum

Posted by gn...@apache.org.
[SSHD-430] Expose supported built-in ciphers as an Enum

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/eac1704e
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/eac1704e
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/eac1704e

Branch: refs/heads/master
Commit: eac1704e05d23a562512dc6d2bde387c3cea07e9
Parents: 043c7df
Author: Guillaume Nodet <gn...@apache.org>
Authored: Tue Mar 17 16:10:52 2015 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Tue Mar 17 18:06:11 2015 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/sshd/SshBuilder.java   |  85 ++++---
 .../org/apache/sshd/common/NamedFactory.java    |  27 ++-
 .../apache/sshd/common/cipher/AES128CBC.java    |   9 +-
 .../apache/sshd/common/cipher/AES128CTR.java    |   9 +-
 .../apache/sshd/common/cipher/AES192CBC.java    |   9 +-
 .../apache/sshd/common/cipher/AES192CTR.java    |   9 +-
 .../apache/sshd/common/cipher/AES256CBC.java    |   9 +-
 .../apache/sshd/common/cipher/AES256CTR.java    |   9 +-
 .../apache/sshd/common/cipher/ARCFOUR128.java   |   9 +-
 .../apache/sshd/common/cipher/ARCFOUR256.java   |   9 +-
 .../apache/sshd/common/cipher/BlowfishCBC.java  |   9 +-
 .../sshd/common/cipher/BuiltinCiphers.java      | 234 +++++++++++++++++++
 .../apache/sshd/common/cipher/CipherNone.java   |  12 +-
 .../apache/sshd/common/cipher/CipherUtils.java  |  58 +++++
 .../apache/sshd/common/cipher/TripleDESCBC.java |   9 +-
 .../apache/sshd/common/util/GenericUtils.java   |  92 ++++++++
 .../java/org/apache/sshd/SshBuilderTest.java    |  81 +++++++
 .../sshd/common/cipher/BuiltinCiphersTest.java  |  94 ++++++++
 .../java/org/apache/sshd/util/BaseTest.java     |  39 +++-
 19 files changed, 748 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java b/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
index b87d994..bac6163 100644
--- a/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
@@ -18,10 +18,9 @@
  */
 package org.apache.sshd;
 
-import java.security.InvalidKeyException;
+import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.sshd.client.ServerKeyVerifier;
@@ -38,16 +37,7 @@ import org.apache.sshd.common.Random;
 import org.apache.sshd.common.RequestHandler;
 import org.apache.sshd.common.Signature;
 import org.apache.sshd.common.TcpipForwarderFactory;
-import org.apache.sshd.common.cipher.AES128CBC;
-import org.apache.sshd.common.cipher.AES128CTR;
-import org.apache.sshd.common.cipher.AES192CBC;
-import org.apache.sshd.common.cipher.AES192CTR;
-import org.apache.sshd.common.cipher.AES256CBC;
-import org.apache.sshd.common.cipher.AES256CTR;
-import org.apache.sshd.common.cipher.ARCFOUR128;
-import org.apache.sshd.common.cipher.ARCFOUR256;
-import org.apache.sshd.common.cipher.BlowfishCBC;
-import org.apache.sshd.common.cipher.TripleDESCBC;
+import org.apache.sshd.common.cipher.BuiltinCiphers;
 import org.apache.sshd.common.compression.CompressionNone;
 import org.apache.sshd.common.file.FileSystemFactory;
 import org.apache.sshd.common.file.nativefs.NativeFileSystemFactory;
@@ -89,6 +79,9 @@ public class SshBuilder {
         return new ServerBuilder();
     }
 
+    /**
+     * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+     */
     protected static class BaseBuilder<T extends AbstractFactoryManager, S extends BaseBuilder<T, S>> implements ObjectBuilder<T> {
 
         protected Factory<T> factory = null;
@@ -142,7 +135,7 @@ public class SshBuilder {
             }
 
             if (cipherFactories == null) {
-                cipherFactories = setUpDefaultCiphers();
+                cipherFactories = setUpDefaultCiphers(false);
             }
 
             // Compression is not enabled by default
@@ -260,32 +253,48 @@ public class SshBuilder {
             return (S) this;
         }
 
-        protected static List<NamedFactory<Cipher>> setUpDefaultCiphers() {
-            List<NamedFactory<Cipher>> avail = new LinkedList<NamedFactory<Cipher>>();
-            avail.add(new AES128CTR.Factory());
-            avail.add(new AES192CTR.Factory());
-            avail.add(new AES256CTR.Factory());
-            avail.add(new ARCFOUR128.Factory());
-            avail.add(new ARCFOUR256.Factory());
-            avail.add(new AES128CBC.Factory());
-            avail.add(new TripleDESCBC.Factory());
-            avail.add(new BlowfishCBC.Factory());
-            avail.add(new AES192CBC.Factory());
-            avail.add(new AES256CBC.Factory());
-
-            for (Iterator<NamedFactory<Cipher>> i = avail.iterator(); i.hasNext(); ) {
-                final NamedFactory<Cipher> f = i.next();
-                try {
-                    final Cipher c = f.create();
-                    final byte[] key = new byte[c.getBlockSize()];
-                    final byte[] iv = new byte[c.getIVSize()];
-                    c.init(Cipher.Mode.Encrypt, key, iv);
-                } catch (InvalidKeyException e) {
-                    i.remove();
-                } catch (Exception e) {
-                    i.remove();
+        /**
+         * The default {@link BuiltinCiphers} setup in order of preference
+         * as specified by <A HREF="https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5">
+         * ssh_config(5)</A> 
+         */
+        public static final List<BuiltinCiphers> DEFAULT_CIPHERS_PREFERENCE =
+                Collections.unmodifiableList(
+                        Arrays.asList(
+                                BuiltinCiphers.aes128ctr,
+                                BuiltinCiphers.aes192ctr,
+                                BuiltinCiphers.aes256ctr,
+                                BuiltinCiphers.arcfour256,
+                                BuiltinCiphers.arcfour128,
+                                BuiltinCiphers.aes128cbc,
+                                BuiltinCiphers.tripledescbc,
+                                BuiltinCiphers.blowfishcbc,
+                                // TODO add support for cast128-cbc cipher
+                                BuiltinCiphers.aes192cbc,
+                                BuiltinCiphers.aes256cbc
+                                // TODO add support for arcfour cipher
+                        ));
+        
+        /**
+         * @param ignoreUnsupported If {@code true} then all the default
+         * ciphers are included, regardless of whether they are currently
+         * supported by the JCE. Otherwise, only the supported ones out of the
+         * list are included
+         * @return A {@link List} of the default {@link NamedFactory}
+         * instances of the {@link Cipher}s according to the preference
+         * order defined by {@link #DEFAULT_CIPHERS_PREFERENCE}.
+         * <B>Note:</B> the list may be filtered to exclude unsupported JCE
+         * ciphers according to the <tt>ignoreUnsupported</tt> parameter
+         * @see BuiltinCiphers#isSupported()
+         */
+        protected static List<NamedFactory<Cipher>> setUpDefaultCiphers(boolean ignoreUnsupported) {
+            List<NamedFactory<Cipher>> avail = new ArrayList<NamedFactory<Cipher>>(DEFAULT_CIPHERS_PREFERENCE.size());
+            for (BuiltinCiphers c : DEFAULT_CIPHERS_PREFERENCE) {
+                if (ignoreUnsupported || c.isSupported()) {
+                    avail.add(c.create());
                 }
             }
+
             return avail;
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
index 47347b4..ba8d60f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
@@ -23,6 +23,8 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.sshd.common.util.GenericUtils;
+
 /**
  * A named factory is a factory identified by a name.
  * Such names are used mainly in the algorithm negotiation at the beginning of the SSH connection.
@@ -48,18 +50,19 @@ public interface NamedFactory<T> extends Factory<T> {
     	 * @return A {@link List} of all the factories names - in same order
     	 * as they appear in the input collection
     	 */
-    	public static <T> List<String> getNameList(Collection<NamedFactory<T>> factories) {
-    		if ((factories == null) || factories.isEmpty()) {
-    			return Collections.emptyList();
-    		}
-    		
-    		List<String>	names=new ArrayList<String>(factories.size());
-    		for (NamedFactory<T> f : factories) {
-    			names.add(f.getName());
-    		}
-    		
-    		return names;
-    	}
+        public static List<String> getNameList(Collection<? extends NamedFactory<?>> factories) {
+            if (GenericUtils.isEmpty(factories)) {
+                return Collections.emptyList();
+            }
+
+            List<String> names = new ArrayList<String>(factories.size());
+            for (NamedFactory<?> f : factories) {
+                names.add(f.getName());
+            }
+
+            return names;
+        }
+
         /**
          * Create an instance of the specified name by looking up the needed factory
          * in the list.

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CBC.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CBC.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CBC.java
index 3ea3870..39a1a08 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CBC.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CBC.java
@@ -32,9 +32,16 @@ public class AES128CBC extends BaseCipher {
      * Named factory for AES128CBC Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "aes128-cbc";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "aes128-cbc";
+            return NAME;
         }
+
         public Cipher create() {
             return new AES128CBC();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CTR.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CTR.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CTR.java
index 2a7dc3a..2cbfb21 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CTR.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES128CTR.java
@@ -32,9 +32,16 @@ public class AES128CTR extends BaseCipher {
      * Named factory for AES128CTR Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "aes128-ctr";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "aes128-ctr";
+            return NAME;
         }
+
         public Cipher create() {
             return new AES128CTR();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CBC.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CBC.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CBC.java
index 87ffdeb..3d26f76 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CBC.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CBC.java
@@ -32,9 +32,16 @@ public class AES192CBC extends BaseCipher {
      * Named factory for AES192CBC Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "aes192-cbc";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "aes192-cbc";
+            return NAME;
         }
+
         public Cipher create() {
             return new AES192CBC();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CTR.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CTR.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CTR.java
index d44c06c..cf13b9f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CTR.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES192CTR.java
@@ -32,9 +32,16 @@ public class AES192CTR extends BaseCipher {
      * Named factory for AES192CBC Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "aes192-ctr";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "aes192-ctr";
+            return NAME;
         }
+
         public Cipher create() {
             return new AES192CTR();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CBC.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CBC.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CBC.java
index 736e594..38122d8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CBC.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CBC.java
@@ -32,9 +32,16 @@ public class AES256CBC extends BaseCipher {
      * Named factory for AES256CBC Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "aes256-cbc";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "aes256-cbc";
+            return NAME;
         }
+
         public Cipher create() {
             return new AES256CBC();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CTR.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CTR.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CTR.java
index 608fc43..718017f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CTR.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/AES256CTR.java
@@ -32,9 +32,16 @@ public class AES256CTR extends BaseCipher {
      * Named factory for AES256CTR Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "aes256-ctr";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "aes256-ctr";
+            return NAME;
         }
+
         public Cipher create() {
             return new AES256CTR();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR128.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR128.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR128.java
index 4ff5f1d..33d6a6e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR128.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR128.java
@@ -32,9 +32,16 @@ public class ARCFOUR128 extends BaseRC4Cipher {
      * Named factory for ARCFOUR128 Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "arcfour128";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "arcfour128";
+            return NAME;
         }
+
         public Cipher create() {
             return new ARCFOUR128();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR256.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR256.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR256.java
index fed8176..500c1b7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR256.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ARCFOUR256.java
@@ -32,9 +32,16 @@ public class ARCFOUR256 extends BaseRC4Cipher {
      * Named factory for AES128CTR Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "arcfour256";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "arcfour256";
+            return NAME;
         }
+
         public Cipher create() {
             return new ARCFOUR256();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/BlowfishCBC.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BlowfishCBC.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BlowfishCBC.java
index 6a76ad1..b2c6135 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BlowfishCBC.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BlowfishCBC.java
@@ -32,9 +32,16 @@ public class BlowfishCBC extends BaseCipher {
      * Named factory for BlowfishCBC Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "blowfish-cbc";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "blowfish-cbc";
+            return NAME;
         }
+
         public Cipher create() {
             return new BlowfishCBC();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
new file mode 100644
index 0000000..74c45f1
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
@@ -0,0 +1,234 @@
+/*
+ * 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 org.apache.sshd.common.cipher;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.sshd.common.Cipher;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.util.GenericUtils;
+
+/**
+ * Provides easy access to the currently implemented ciphers
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public enum BuiltinCiphers implements NamedFactory<NamedFactory<Cipher>> {
+    none(CipherNone.Factory.NAME, CipherNone.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new CipherNone.Factory();
+        }
+    },
+    aes128cbc(AES128CBC.Factory.NAME, AES128CBC.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new AES128CBC.Factory();
+        }
+    },
+    aes128ctr(AES128CTR.Factory.NAME, AES128CTR.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new AES128CTR.Factory();
+        }
+    },
+    aes192cbc(AES192CBC.Factory.NAME, AES192CBC.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new AES192CBC.Factory();
+        }
+    },
+    aes192ctr(AES192CTR.Factory.NAME, AES192CTR.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new AES192CTR.Factory();
+        }
+    },
+    aes256cbc(AES256CBC.Factory.NAME, AES256CBC.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new AES256CBC.Factory();
+        }
+    },
+    aes256ctr(AES256CTR.Factory.NAME, AES256CTR.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new AES256CTR.Factory();
+        }
+    },
+    arcfour128(ARCFOUR128.Factory.NAME, ARCFOUR128.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new ARCFOUR128.Factory();
+        }
+    },
+    arcfour256(ARCFOUR256.Factory.NAME, ARCFOUR256.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new ARCFOUR256.Factory();
+        }
+    },
+    blowfishcbc(BlowfishCBC.Factory.NAME, BlowfishCBC.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new BlowfishCBC.Factory();
+        }
+    },
+    tripledescbc(TripleDESCBC.Factory.NAME, TripleDESCBC.class) {
+        @Override
+        public NamedFactory<Cipher> create() {
+            return new TripleDESCBC.Factory();
+        }
+    };
+
+    private final String factoryName;
+    private Class<? extends Cipher> cipherType;
+
+    @Override
+    public final String getName() {
+        return factoryName;
+    }
+
+    public final Class<? extends Cipher> getCipherType() {
+        return cipherType;
+    }
+
+    BuiltinCiphers(String facName, Class<? extends Cipher> cipherClass) {
+        factoryName = facName;
+        cipherType = cipherClass;
+    }
+
+    private final AtomicReference<Boolean> _supported = new AtomicReference<>(null);
+
+    /**
+     * @return {@code true} if the current JVM configuration supports this
+     * cipher - e.g., AES-256 requires the <A HREF="http://www.oracle.com/technetwork/java/javase/downloads/">
+     * Java Cryptography Extension (JCE)</A>
+     */
+    public boolean isSupported() {
+        Boolean value;
+        synchronized (_supported) {
+            if ((value = _supported.get()) == null) {
+                // see BaseBuilder#fillWithDefaultValues
+                try {
+                    Exception t = CipherUtils.checkSupported(create());
+                    value = t == null;
+                } catch (Exception e) {
+                    value = Boolean.FALSE;
+                }
+
+                _supported.set(value);
+            }
+        }
+
+        return value;
+    }
+
+    public static final Set<BuiltinCiphers> VALUES =
+            Collections.unmodifiableSet(EnumSet.allOf(BuiltinCiphers.class));
+
+    /**
+     * @param s The {@link Enum}'s name - ignored if {@code null}/empty
+     * @return The matching {@link BuiltinCiphers} whose {@link Enum#name()} matches
+     * (case <U>insensitive</U>) the provided argument - {@code null} if no match
+     */
+    public static BuiltinCiphers fromString(String s) {
+        if (GenericUtils.isEmpty(s)) {
+            return null;
+        }
+
+        for (BuiltinCiphers c : VALUES) {
+            if (s.equalsIgnoreCase(c.name())) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @param factory The {@link NamedFactory} for the cipher - ignored if {@code null}
+     * @return The matching {@link BuiltinCiphers} whose factory name matches
+     * (case <U>insensitive</U>) the cipher factory name
+     * @see #fromFactoryName(String)
+     */
+    public static BuiltinCiphers fromFactory(NamedFactory<Cipher> factory) {
+        if (factory == null) {
+            return null;
+        } else {
+            return fromFactoryName(factory.getName());
+        }
+    }
+
+    /**
+     * @param n The factory name - ignored if {@code null}/empty
+     * @return The matching {@link BuiltinCiphers} whose factory name matches
+     * (case <U>insensitive</U>) the provided name - {@code null} if no match
+     */
+    public static BuiltinCiphers fromFactoryName(String n) {
+        if (GenericUtils.isEmpty(n)) {
+            return null;
+        }
+
+        for (BuiltinCiphers c : VALUES) {
+            if (n.equalsIgnoreCase(c.getName())) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @param c The {@link Cipher} instance - ignored if {@code null}
+     * @return The matching {@link BuiltinCiphers} - {@code null} if no match
+     * @see #fromCipherType(Class)
+     */
+    public static BuiltinCiphers fromCipher(Cipher c) {
+        if (c == null) {
+            return null;
+        } else {
+            return fromCipherType(c.getClass());
+        }
+    }
+
+    /**
+     * @param type The cipher type - ignored if {@code null} or not a
+     *             {@link Cipher} derived class
+     * @return The matching {@link BuiltinCiphers} - {@code null} if no match
+     */
+    public static BuiltinCiphers fromCipherType(Class<?> type) {
+        if ((type == null) || (!Cipher.class.isAssignableFrom(type))) {
+            return null;
+        }
+
+        for (BuiltinCiphers c : VALUES) {
+            Class<?> t = c.getCipherType();
+            if (t.isAssignableFrom(type)) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
index 65c921b..95c82d9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
@@ -35,9 +35,16 @@ public class CipherNone implements Cipher {
      * Named factory for the no-op Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "none";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "none";
+            return NAME;
         }
+
         public Cipher create() {
             return new CipherNone();
         }
@@ -52,9 +59,10 @@ public class CipherNone implements Cipher {
     }
 
     public void init(Mode mode, byte[] bytes, byte[] bytes1) throws Exception {
+        // ignored - always succeeds
     }
 
     public void update(byte[] input, int inputOffset, int inputLen) throws Exception {
+        // ignored - always succeeds
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java
new file mode 100644
index 0000000..45070f6
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java
@@ -0,0 +1,58 @@
+/*
+ * 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 org.apache.sshd.common.cipher;
+
+import org.apache.sshd.common.Cipher;
+import org.apache.sshd.common.Factory;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class CipherUtils {
+    /**
+     * Checks if the provided cipher factory instance generates a cipher
+     * that is supported by the JCE
+     * @param f The cipher factory instance
+     * @return The {@link Exception} that the {@link Cipher#init(org.apache.sshd.common.Cipher.Mode, byte[], byte[])}
+     * call has thrown - {@code null} if successful (i.e., cipher supported)
+     * @see <A HREF="http://www.oracle.com/technetwork/java/javase/downloads/">Java Cryptography Extension (JCE)</A>
+     */
+    public static Exception checkSupported(Factory<? extends Cipher> f) {
+        return checkSupported(f.create());
+    }
+
+    /**
+     * Checks if the provided cipher is supported by the JCE
+     * @param c The {@link Cipher} to be checked
+     * @return The {@link Exception} that the {@link Cipher#init(org.apache.sshd.common.Cipher.Mode, byte[], byte[])}
+     * call has thrown - {@code null} if successful (i.e., cipher supported)
+     * @see <A HREF="http://www.oracle.com/technetwork/java/javase/downloads/">Java Cryptography Extension (JCE)</A>
+     */
+    public static Exception checkSupported(Cipher c) {
+        try {
+            byte[] key=new byte[c.getBlockSize()];
+            byte[] iv=new byte[c.getIVSize()];
+            c.init(Cipher.Mode.Encrypt, key, iv);
+            return null;
+        } catch(Exception e) {
+            return e;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/cipher/TripleDESCBC.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/TripleDESCBC.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/TripleDESCBC.java
index bb194c3..5cdae9a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/TripleDESCBC.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/TripleDESCBC.java
@@ -32,9 +32,16 @@ public class TripleDESCBC extends BaseCipher {
      * Named factory for TripleDESCBC Cipher
      */
     public static class Factory implements NamedFactory<Cipher> {
+        public static final String NAME = "3des-cbc";
+
+        public Factory() {
+            super();
+        }
+
         public String getName() {
-            return "3des-cbc";
+            return NAME;
         }
+
         public Cipher create() {
             return new TripleDESCBC();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
new file mode 100644
index 0000000..b02c7ec
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
@@ -0,0 +1,92 @@
+/*
+ * 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 org.apache.sshd.common.util;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class GenericUtils {
+    public static final int length(CharSequence cs) {
+        if (cs == null) {
+            return 0;
+        } else {
+            return cs.length();
+        }
+    }
+
+    public static final boolean isEmpty(CharSequence cs) {
+        if (length(cs) <= 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    public static final int size(Collection<?> c) {
+        if (c == null) {
+            return 0;
+        } else {
+            return c.size();
+        }
+    }
+
+    public static final boolean isEmpty(Collection<?> c) {
+        if (size(c) <= 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static final int size(Map<?,?> m) {
+        if (m == null) {
+            return 0;
+        } else {
+            return m.size();
+        }
+    }
+
+    public static final boolean isEmpty(Map<?,?> m) {
+        if (size(m) <= 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static final int length(Object ... a) {
+        if (a == null) {
+            return 0;
+        } else {
+            return a.length;
+        }
+    }
+
+    public static final boolean isEmpty(Object ... a) {
+        if (length(a) <= 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java b/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
new file mode 100644
index 0000000..a1d9a39
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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 org.apache.sshd;
+
+import java.util.List;
+
+import org.apache.sshd.SshBuilder.BaseBuilder;
+import org.apache.sshd.common.Cipher;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.cipher.BuiltinCiphers;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.util.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class SshBuilderTest extends BaseTest {
+    public SshBuilderTest() {
+        super();
+    }
+
+    /**
+     * Make sure that {@link BaseBuilder#setUpDefaultCiphers(boolean)} returns
+     * the correct result - i.e., according to the {@code ingoreUnsupported}
+     * parameter and in the defined preference order
+     */
+    @Test
+    public void testSetUpDefaultCiphers() {
+        for (boolean ignoreUnsupported : new boolean[] { true, false }) {
+            List<NamedFactory<Cipher>>  ciphers=BaseBuilder.setUpDefaultCiphers(ignoreUnsupported);
+            int                         numCiphers=GenericUtils.size(ciphers);
+            // make sure returned list size matches expected count
+            if (ignoreUnsupported) {
+                Assert.assertEquals("Incomplete full ciphers size", BaseBuilder.DEFAULT_CIPHERS_PREFERENCE.size(), numCiphers);
+            } else {
+                int expectedCount=0;
+                for (BuiltinCiphers c : BaseBuilder.DEFAULT_CIPHERS_PREFERENCE) {
+                    if (c.isSupported()) {
+                        expectedCount++;
+                    }
+                }
+                Assert.assertEquals("Incomplete supported ciphers size", expectedCount, numCiphers);
+            }
+            
+            // make sure order is according to the default preference list
+            List<String>    cipherNames=NamedFactory.Utils.getNameList(ciphers);
+            int             nameIndex=0;
+            for (BuiltinCiphers c : BaseBuilder.DEFAULT_CIPHERS_PREFERENCE) {
+                if ((!c.isSupported()) && (!ignoreUnsupported)) {
+                    continue;
+                }
+                
+                String  expectedName=c.getName();
+                Assert.assertTrue("Out of actual ciphers for expected=" + expectedName, nameIndex < numCiphers);
+                
+                String  actualName=cipherNames.get(nameIndex);
+                Assert.assertEquals("Mismatched cipher at position " + nameIndex + " for ignoreUnsupported=" + ignoreUnsupported, expectedName, actualName);
+                nameIndex++;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
new file mode 100644
index 0000000..f9e2f04
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 org.apache.sshd.common.cipher;
+
+import org.apache.sshd.common.Cipher;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.util.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class BuiltinCiphersTest extends BaseTest {
+    public BuiltinCiphersTest() {
+        super();
+    }
+
+    @Test
+    public void testFromEnumName() {
+        for (BuiltinCiphers expected : BuiltinCiphers.VALUES) {
+            String  name=expected.name();
+
+            for (int index=0; index < name.length(); index++) {
+                BuiltinCiphers  actual=BuiltinCiphers.fromString(name);
+                Assert.assertSame(name + " - mismatched enum values", expected, actual);
+                name = shuffleCase(name);   // prepare for next time
+            }
+        }
+    }
+
+    @Test
+    public void testFromFactoryName() {
+        for (BuiltinCiphers expected : BuiltinCiphers.VALUES) {
+            String  name=expected.getName();
+            
+            for (int index=0; index < name.length(); index++) {
+                BuiltinCiphers  actual=BuiltinCiphers.fromFactoryName(name);
+                Assert.assertSame(name + " - mismatched enum values", expected, actual);
+                name = shuffleCase(name);   // prepare for next time
+            }
+        }
+    }
+
+    @Test
+    public void testFromFactory() {
+        for (BuiltinCiphers expected : BuiltinCiphers.VALUES) {
+            if (!expected.isSupported()) {
+                System.out.append("Skip unsupported cipher: ").println(expected);
+                continue;
+            }
+            
+            NamedFactory<Cipher>    factory=expected.create();
+            Assert.assertEquals(expected.name() + " - mismatched factory names", expected.getName(), factory.getName());
+
+            BuiltinCiphers  actual=BuiltinCiphers.fromFactory(factory);
+            Assert.assertSame(expected.getName() + " - mismatched enum values", expected, actual);
+        }
+    }
+
+    @Test
+    public void testFromCipher() {
+        for (BuiltinCiphers expected : BuiltinCiphers.VALUES) {
+            if (!expected.isSupported()) {
+                System.out.append("Skip unsupported cipher: ").println(expected);
+                continue;
+            }
+            
+            NamedFactory<Cipher>    factory=expected.create();
+            Cipher                  cipher=factory.create();
+            assertObjectInstanceOf(expected.name() + " - mismatched cipher type", expected.getCipherType(), cipher);
+
+            BuiltinCiphers  actual=BuiltinCiphers.fromCipher(cipher);
+            Assert.assertSame(expected.getName() + " - mismatched enum values", expected, actual);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eac1704e/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java b/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
index 49b8f31..205c889 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
@@ -18,10 +18,13 @@
  */
 package org.apache.sshd.util;
 
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.File;
 
+import org.apache.sshd.common.util.GenericUtils;
 import org.junit.Rule;
 import org.junit.rules.TestName;
 import org.junit.rules.TestWatcher;
@@ -57,12 +60,44 @@ public abstract class BaseTest extends TestWatcher {
         System.out.println("\nFinished " + description.getClassName() + ":" + description.getMethodName() + " in " + duration + " ms\n");
     }
 
-    public static final File assertHierarchyTargetFolderExists(File folder) {
+    /* ------------------- Useful extra test helpers ---------------------- */
+
+    public static String shuffleCase(CharSequence cs) {
+        if (GenericUtils.isEmpty(cs)) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder(cs.length());
+        for (int index = 0; index < cs.length(); index++) {
+            char ch = cs.charAt(index);
+            double v = Math.random();
+            if (Double.compare(v, 0.3d) < 0) {
+                ch = Character.toUpperCase(ch);
+            } else if ((Double.compare(v, 0.3d) >= 0) && (Double.compare(v, 0.6d) < 0)) {
+                ch = Character.toLowerCase(ch);
+            }
+            sb.append(ch);
+        }
+
+        return sb.toString();
+    }
+
+    /* ----------------------- Useful extra assertions --------------------- */
+
+    public static File assertHierarchyTargetFolderExists(File folder) {
         if (!folder.exists()) {
             assertTrue("Failed to create hierarchy of " + folder.getAbsolutePath(), folder.mkdirs());
         }
         
         return folder;
     }
-
+    
+    public static void assertObjectInstanceOf(String message, Class<?> expected, Object obj) {
+        assertNotNull(message + " - no actual object", obj);
+        
+        Class<?>    actual=obj.getClass();
+        if (!expected.isAssignableFrom(actual)) {
+            fail(message + " - actual object type (" + actual.getName() + ") incompatible with expected (" + expected.getName() + ")");
+        }
+    }
 }