Apache FTP – a Java based FTP Server implementation

Apache FTP is a fully functioning ftp server completely implemented in Java. It is easily configurable via it’s java API and therefore ideal for testing.

Introduction
Using the Apache Server in your project is as easy as including the maven dependency.

<dependency>
            <groupId>org.apache.ftpserver</groupId>
            <artifactId>ftpserver-core</artifactId>
            <version>1.0.6</version>
</dependency>

and calling a couple of simple java methods.

new FtpServerFactory().createServer().start();

Well granted, the server would be rather useless, but it would be a fully fledged to server. Now onto some configuration.
For listening to a custom port you first need a listener factory, to create a listener and attach it to the server factory.

ListenerFactory listenerFactory = new ListenerFactory();
listenerFactory.setPort(this.port);
serverFactory.addListener("default", listenerFactory.createListener());

Further, to add users to your ftp server you need to add a User Manager:

UserManager um = new PropertiesUserManagerFactory().createUserManager();
BaseUser user = new BaseUser();
...
um.save(user);

Apache FTP Server inside a WAR deployed Web App
To deploy the server inside a webapp is a little bit tricky, because the file paths for the server’s root folder, as well as users’ home directories are configured as String properties. Fortunately we can use Spring to help us with determining the current folder.

<bean id="ftpServer" class="com.systemkern.ftp.server.FtpServerExample">
        <!-- ftp root relative to the context root -->
        <property name="ftpRoot" value="ftp"/>
</bean>

and use the File object provided by Spring to find out the absolute path:

public void setFtpRoot(File ftpRoot) {
    this.ftpRoot = ftpRoot;
}
 
...
 
String fullUserHome = this.ftpRoot.getAbsolutePath() +"/";
if (user.getHomeDirectory() != null
        && "/".equals( user.getHomeDirectory() ) == false)
    fullUserHome += user.getHomeDirectory();
cur.setHomeDirectory(fullUserHome);

Complete Reference File

The Spring Configuration

<bean id="ftpServer" class="com.systemkern.ftp.server.FtpServerExample">
    <property name="port" value="1234"/>
    <!-- ftp root relative to the context root -->
    <property name="ftpRoot" value="ftp"/>
    <property name="users">
        <list>
            <bean class="org.apache.ftpserver.usermanager.impl.BaseUser">
                <property name="name">          <value>user</value></property>
                <property name="password">      <value>pass</value></property>
                <property name="homeDirectory"> <value>/</value></property>
            </bean>
        </list>
    </property>
</bean>

The Java Test Class

package com.systemkern.ftp.server;
 
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PasswordEncryptor;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;

public class FtpServerTest {
    public static void main(String[] args) throws FtpException, IOException {
        FtpServerTest test = new FtpServerTest();
        test.users = new ArrayList<BaseUser>();
        BaseUser user = new BaseUser();
        user.setName("user");
        user.setPassword("pass");
        user.setHomeDirectory("ftp");
        test.users.add(user);
        test.init();
    }

    FtpServerFactory serverFactory = new FtpServerFactory();
    int port=21;
    ListenerFactory listenerFactory = new ListenerFactory();
    PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
    List<BaseUser> users = null;
    File ftpRoot; 
    FtpServer server;

    @PostConstruct
    public void init() throws FtpException, IOException {
        // set the port of the listener
        this.listenerFactory.setPort(this.port);
        // replace the default listener
        this.serverFactory.addListener("default", this.listenerFactory.createListener());
        //give write access to every user
        UserManager um = this.userManagerFactory.createUserManager();
        List<Authority> auths = Arrays.asList(new Authority[]{new WritePermission()});
        for (BaseUser cur : this.users) {
            String fullUserHome = this.ftpRoot.getAbsolutePath() +"/";
            if (cur.getHomeDirectory() != null && "/".equals( cur.getHomeDirectory() ) == false)
                fullUserHome += cur.getHomeDirectory();
            cur.setAuthorities(auths);
            cur.setHomeDirectory(fullUserHome);
            um.save(cur);
        }
         
        //start new server
        this.serverFactory.setUserManager( um );
        // start the server
        this.server = this.serverFactory.createServer();
        this.server.start();
         
    }
     
    @PreDestroy
    public void shutdown() {
        this.server.stop();
    }
     
     
/*
 * Getters and Setters
 */
    public void setPort(int port) {
        this.port = port;
    }

    public void setUsers(List<BaseUser> userList) {
        this.users = userList;
    }

    public void setFtpRoot(File ftpRoot) {
        this.ftpRoot = ftpRoot;
    }
}

How to configure SSH Key-Based authentification

SSH Key-Based authentication can be configured in two easy steps.
All you have to do is add the user-machine’s public key to the server’s authorized_keys file.
Therefore you have to:

  1. create a public key for your user-machine
  2. write the key to the server’s ~/.ssh/authorized_keys textfile

On your local machine a private-public ssh key pair is easily created executing the following command in your terminal app:
ssh-keygen

which will yield following output

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/systemkern/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/systemkern/.ssh/id_rsa.
Your public key has been saved in /Users/systemkern/.ssh/id_rsa.pub.
The key fingerprint is:
11:22:33:44:55:66:77:88:99:00:aa:bb:cc:dd:ee:ff systemkern@systemkerns-mac
The key's randomart image is:
+--[ RSA 2048]----+
| S *+ . |
| .. |
| o B + |
| o . |
| . o . |
| ... |
| * . oo o |
| . =E + |
| . o |
+-----------------+
systemkerns-mac:~$

The program will ask you where the key file should be created also showing the default name in the output. In this exapmple the private key file will be created under ~/.ssh with the name id_rsa. The public key can be found in the same directory in the file id_rsa.pub

The optional passphrase will provide some additional protection to your login. Only if the passphrase is entered the key based authentication will work.

you can then issue the following command to save the public key on the server:
cat ~/.ssh/id_rsa.pub | ssh user@server “mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys”

voila!
you can now log in to your server authenticated by ssh instead of by password.

Generic Singletons with C#

C# gives you most of the generic powers that also Java has. So if one were so inclined he could write a generic singleton class. This approach would free implementing classes (and their developers) from handling the instance reference and providing the getInstance() method. Granted this is not a lot of work per instance but even an avalanche is made up from tiny snowflakes.

This example was written to be used inside the Unity game development framework. Unity takes care of the initialisation, so we only have to worry about keeping the reference.

Two base classes are needed to get around some limitations of C# generic implementations. An untyped class which stands at the root of the inheritance tree (“AbstractValueController”) and a typed Class which extends this BaseClass (“ValueController”).

1) The untyped BaseClass which I chose to declare abstract to make it more distinguishable:

public class AbstractValueController : MonoBehaviour {
}

2) The typed Class which contains the actual singleton logic:

public abstract class ValueController<SubType> : AbstractValueController
		where SubType : AbstractValueController {

	//the reference is saved as the root type but gets casted upon retrieval
	protected static AbstractValueController instance;
	public static SubType Instance { get { return (SubType) instance; } }

	//the Awake() Method is part of the UnityFramework and very similar to a constructor
	public virtual void Awake() {
		instance = this;
	}
}

3) An example implementing class which you want to be a singleton:

//class is typed with its own type for the singleton logic to work
public class Controller : ValueController<Controller> {
	//no singleton code needed  ... neat
}

Fuzzy Logic with jFuzzyLogic

jFuzzyLogic is an easy to use library for fuzzy logic computations.
After adding the Package to your projects classpath you only need a couple of lines of code to include and run fuzzy logic computations. Basically it is just a matter of setting variables, running the computation and then later retrieving the output parameters.

fis.setVariable("input1", arg1);
fis.setVariable("input2", arg2);

// Evaluate
fis.evaluate();
Variable out = fis.getVariable("out");
System.out.println("Output = "+out.getValue());

Sources: