SSHTools Knowledgebase
Information and FAQs about SSHTools products
  
Search  
   
Browse by Category
SSHTools Knowledgebase .: SSHD Maverick .: Getting Started with Maverick SSHD

Getting Started with Maverick SSHD

Pre-Requisite
Maverick SSH Daemon API
SSH Client

Resources
SSHTerm Professional Multi-protocol Client http://www.3sp.com/

What It Does
The Maverick SSHD API enables the development of robust, high performance SSH-enabled server applications. This feature-rich API can be used to custom-build a server to suit each user or organisations specific security-related needs. In this series of articles we show the reader step-by-step how to introduce increasingly more advanced functionality into their Maverick SSH Server; by the end of which the user should have a fully working and functionality-rich SSH server application.

This opening tutorial sets the foundation by creating an SSH Server with basic SFTP file transfer capabilities. At the end of this article the reader should have a fully working SSH Server running and should be able to use a client application such as SSHTerm Professional to instantly connect and begin transferring files securely.

How It Works
Establishing The Framework
The first step in creating a Maverick SSH Server is to establish the SSH framework; authentication mechanisms, communications mechanisms, protocol requirements and all neccsary resourcing control. This is a very complex and time consuming process with the developer required to have first-hand knowledge of the SSH protocol and additional knowlege in topics as cryptography. However, with the SSHD API all this hard work has been done for us, encapsulated within a single abstract SshDaemon class, the starting point of this article.

To begin taking advantage of all this functionality that sits under the hood of this class all we need to do is extend it.

public class ExampleSSHD extends SshDaemon {

The SSHDamon class performs all the core processing of the server instance from servicing incoming requests, securing communication channels to authentication and data encryption. The complex communication framework of the SSH daemon is based on the Java NIO socket framework, a high performance non-blocking I/O architecture that enables the server to service communication requests asynchronously. This sets the foundation for the high performance, efficient communications framework incorporated within the server API.

Configuration
As part of extending the SSHDaemon class one is expected to implement the configure method. During startup of the service the server looks at this configuration method for details on how the server is to be set up.

protected void configure(ConfigurationContext context) throws IOException {

This method receives a ConfigurationContext that stores all the settings for the server instance. The minimal requirements that need to be configured are: Server Host Key, Authentication Scheme and for this example a Filesystem. There are many parameters that can be set and adjusted which all allow for a very flexible architecture and enables a developer to build a server to suit his or her requirements.

Host Verification
The first thing we define in our server is the host key in this example we have used RSA and DSA host keys.

When a client connects to the server instance the instance returns its' public key the connecting client verifies this by trying to identify it within its list of known hosts. If it is aware of this server then communication can proceed however, if the host is not recognised the user is prompted to whether he wishes to add this unknown host to its list of known hosts.

This loading and generating of keys is performed by the protected void loadOrGenerateHostKey(java.io.File key, java.lang.String type, int bitlength, ConfigurationContext context) method, the first time it is called the neccesary host key file is generated, but afterwards subsequent calls, for example when the server is restarted, this method will simply load the already generated key.

// Add an RSA key and preferably a DSA key as well to avoid connection // errors with clients that only support one key type (F-Secure 4.3 for example) try { loadOrGenerateHostKey(new File("ssh_host_rsa_key"), SshKeyPairGenerator.SSH2_RSA, 1024, context); loadOrGenerateHostKey(new File("ssh_host_dsa_key"), SshKeyPairGenerator.SSH2_DSA, 1024, context); } catch(InvalidPassphraseException ex) { }

RSA and DSA are cryptographic algorithms used by the SSH Daemon in authenticating itself to the client.
RSA is a public key cipher which can be used both for encrypting messages and making digital signatures, the letters stand for the names of the inventors: Rivest, Shamir and Adleman and is patented by RSA technologies. Digital Signature Algorithm is a public key algorithm that is used as part of the Digital Signature Standard (DSS). DSA was developed by the US National Security Agency but unlike RSA it cannot be used for encryption, only for digital signature authentication.

Listening interfaces
Next we specify which interfaces and ports the server should listen on for any clients that wish to communicate. The addListeningInterface method allows interface and associated port number to be specified.

// Listen on multiple ports on all interfaces context.addListeningInterface("0.0.0.0", 22); context.addListeningInterface("0.0.0.0", 10022);

In the above snippet we have defined all interfaces be checked on ports 22 and 10022. If one only had one network interface then the above statement would be equivalent to writing:

context.addListeningInterface("127.0.0.1", 22); context.addListeningInterface("127.0.0.1", 10022); context.addListeningInterface("192.168.1.123", 22); context.addListeningInterface("192.168.1.123", 10022);

Authentication Banner
The setBannerMessage method allows the setting of a simply message that is broadcast to any client that connects to the server. In this example the server message that will be broadcast details how to connect to the server.

// Setup an authentication banner context.setBannerMessage("Use the username 'lee' to login with any password.");

Authentication Provider
The next thing we need to do is to implement the authentication mechanism that will be used by the instance. Since we will be allowing any requesting client to connect the instance needs to make sure that the connecting user is a valid user and is allowed to use the server. An authentication provider must extend and implement the required methods as defined by the NativeAuthenticationProvider. The methods and their purpose are detailed within the javadocs. However one of the methods that is worth mention is public boolean logonUser(byte[] sessionid, String username, SocketAddress ipAddress).

All valid users that are allowed to log into the system are defined within this method and in addition any neccesary password authentication must also carried out in this method. The extract below is take from the ExampleAuthenticationProvider.java an example implementation authentication provider that can be found within the examples folder.

public boolean logonUser(byte[] sessionid, String username, String password, SocketAddress ipAddress) throws com.maverick.sshd.platform.PasswordChangeException { if(username.equals("lee")) return true; if(username.equals("richard")) throw new PasswordChangeException(); return false; }

As can be seen the method defines the user 'lee' as the valid user. When an authentication request is received from the client the server looks up the authentication method name, for example "password" from the ConfigurationContext. The logon method is then expected to validate the password by whichever means necessary either implementing an authentication class as PasswordAuthentication or relying on inbuilt mechanisms such as calling ActiveDirectory APIs etc. This code is specific to each users requirement and needs to be handled appropriately since in our example no password will be checked we have no password processing code.

The ConfigurationConext::setAuthenticationProvider(java.lang.Class authenticationProvider) takes as its argument a class object as oppose to the convential class instance so that the server can independently manage instances of this class.

// Setup the authentication provider context.setAuthenticationProvider(ExampleAuthenticationProvider.class);

As the above code highlights for the sake of this example we have utilised the implemented Authentication Provider supplied as part of the API examples.

VirtualFileSystem
In order for our server to support SFTP the ConfigurationContext needs to be loaded with a file system. The Maverick SSHD API comes with an interface NativeFileSystemProvider that needs to be implemented to carry out necessary file system protocols. The interface requires implementation to a number of methods including closeFilesystem() getDefaultPath() makeDirectory() etc all the necessary commands required in a file system.

Unfortunately implementing one of these is beyond the scope of this article though the API comes with a ready to use file system, VirtualFileSystem.class, that implements the basic IO operations needed, via java.io.File, for any basic file system at a level to perform basic SFTP functionality an apt class for us to use in our example server.

// Tell the SSHD which file system were using context.setFileSystemProvider(VirtualFileSystem.class);

As the code above shows once again we simply supply this class as a parameter to the ConfigurationContext instance. The only thing we need to do for this file system to work us define our mount points.

Mount Points
Mount points are mappings between a name and an associated filesystem location for example, on a windows machine when we type c: the operating system has a link that ties this drive letter to the correct disk drive. In the same way our VirtualFileSystem requires mappings to allow mappings of the root directory and any others we wish to implement. Mounts are created by setting system properties, as a minimum the root file system must be provided, com.maverick.sshd.vfs.VFSRoot defines this directory mount. As the exert below shows, our root directory is C:

// Configure some VirtualFileSystem mounts and the VFS root System.setProperty("com.maverick.sshd.vfs.VFSRoot", "C:"); System.setProperty("com.maverick.sshd.vfs.VFSMount.1", "/public=P:"); System.setProperty("com.maverick.sshd.vfs.VFSMount.2", "/management=M:");

We also set two additional mounts com.maverick.sshd.vfs.VFSMount.1, com.maverick.sshd.vfs.VFSMount.2 which have been mapped to my personal filesystem; P: (my public drive) and M: (my management drive), these should be changed to your own directories or removed altogether.
NOTE:The setting of attributes is NOT supported within the virtual file system and by default users will have access to all files and folders. However this functionality can be achieved by implementing VFSPermissionHandler but this is beyond the scope of this article.

Thats all there is to it!

Main
Our server is now ready and configured all we need to do instantiate the instance and set it running.

public static void main(String[] args) throws Exception { LicenseManager.addLicense("----BEGIN SSHTools LICENSE----rn..."); ExampleSSHD sshd = new ExampleSSHD(); sshd.startup(); }

As the exert shows we install a valid license, create an instance of the class and call SSHDaemon::startup(). The first job this method does is load the configuration properties we have set above in our configuration method:

context = new ConfigurationContext(this); configure(context);

And only after succesfully loading does it continue with setting up the rest of the server.

Communication
Once the server is running user 'Lee' should be able to securely connect to our SSHD Server. Using any client that supports SFTP we can connect to our server and begin transferring files from the server's filesystem securely.

Fig1. Using an appropriate client files can be securely transferred

How To Run This Code
This attached zip file contains several source files. Unzip these into a new Java project and build.

2005 SSHTools Ltd, All Rights Reserved


How helpful was this article to you?

User Comments

Add Comment
No comments have been posted.


powered by Lore
© 2008 SSHTools Ltd. All Rights Reserved