Secure file transfer with Java and Versile

Just made an example of how to transfer a file over a secure and authenticated connection in pure Java - without having to use additional technology like ssh/scp. Versile has all you need for creating a secure and authenticated connection, and you'll decide what files you want to expose - nothing more - nothing less.

This is the file server (include versile.jar in your classpath - and create a file called "personregister.txt" in the working directory):

 package versileexample;  
 import java.io.File;  
 import java.io.FileNotFoundException;  
 import java.io.RandomAccessFile;  
 import java.security.interfaces.RSAPublicKey;  
 import java.util.logging.Level;  
 import java.util.logging.Logger;  
 import org.versile.Versile;  
 import org.versile.common.auth.VAuth;  
 import org.versile.common.auth.VCredentials;  
 import org.versile.common.auth.VPrivateCredentials;  
 import org.versile.common.peer.VInetSocketPeer;  
 import org.versile.common.peer.VPeer;  
 import org.versile.crypto.VDecentralIdentity;  
 import org.versile.crypto.VRSAKeyPair;  
 import org.versile.orb.entity.VObject;  
 import org.versile.orb.external.Publish;  
 import org.versile.orb.external.VExternal;  
 import org.versile.orb.link.VLinkAuth;  
 import org.versile.orb.service.VGatewayFactory;  
 import org.versile.reactor.service.VOPService;  
 import org.versile.vse.stream.VByteStreamer;  
 import org.versile.vse.stream.VSimpleFileStreamerData;  
 import org.versile.vse.stream.VStreamError;  
 /**  
  * A simple file server  
  */  
 public class VersileFileServerExample extends VExternal {  
   /**  
    * Remotely callable method returning stream to a shared file. We'll only share one file in this example.  
    * @return  
    * @throws VStreamError  
    * @throws FileNotFoundException   
    */  
   @Publish(show=true, ctx=false)    
   public VByteStreamer getSharedFile() throws VStreamError, FileNotFoundException {         
     VSimpleFileStreamerData.Config cfg = new VSimpleFileStreamerData.Config();  
     cfg.setReadable(true);  
     System.out.println("Returning stream to shared file");  
     // Return streamer to the textfile "personregister.txt"  
     return new VByteStreamer(  
         new VSimpleFileStreamerData(  
         new RandomAccessFile(new File("personregister.txt"), "r"),  
         cfg));  
   }  
   /**  
    * Factory class for remotely accessible service object  
    */  
   public static class Factory implements VGatewayFactory {  
     @Override  
     public VObject build() {        
       return new VersileFileServerExample();  
     }  
   }  
   public static void main(String[] args) throws Exception {  
     // Accept AGPL license  
     Versile.setInternalUseAGPL();  
     // Public key authorized for login  
     final RSAPublicKey authorizedKey = VRSAKeyPair.importPublicArmored(("-----BEGIN RSA PUBLIC KEY-----\n" +  
                     "MIGJAoGBAL80uZMXR6vclBMLL9OZS/bpIO6AIitZpEyTZ96qMbpkgoqP6Wi9ev1Isag3jsZORpPf\n" +  
                     "6OJfMEHAWcF5YxzzLKDd13fAswRzbF2VA+QRikJkT8OED1wseX5rZbo7CenStVd6JMecOUr7wsb9\n" +  
                     "MTY/fgcQyYY8u/yBaBUSLeoJfQPdAgMBAAE=\n" +  
                     "-----END RSA PUBLIC KEY-----").getBytes());  
     // Create server identity  
     VPrivateCredentials serverCredentials = new VPrivateCredentials(VDecentralIdentity.dia(1024, "VersileExample", "Versile", "Versile2014"));  
     // Create service  
     VOPService service = new VOPService(new Factory(), serverCredentials,   
         new VLinkAuth(new VAuth(true,false) {  
       /**  
        * Logic for which public keys to accept - this example only accepts the key above  
        * @param credentials  
        * @return   
        */  
       @Override  
       public synchronized boolean acceptCredentials(VCredentials credentials) {  
         if(authorizedKey.equals(credentials.getPublicKey())){  
           Logger.getLogger(getClass().getName()).info("Authorized link");  
           return true;  
         } else {  
           Logger.getLogger(getClass().getName()).info("Unknown public key");  
           return false;  
         }  
       }  
       /**  
        * We can also accept only specified peers - but in this example we'll just log the ip address of the client  
        * @param peer  
        * @return   
        */  
       @Override  
       public synchronized boolean acceptPeer(VPeer peer) {  
         VInetSocketPeer ipeer = (VInetSocketPeer)peer;  
         Logger.getLogger(getClass().getName()).  
             log(Level.INFO,   
             "Link auth request from {0}",   
             ipeer.getInetAddress().getHostString());        
         return super.acceptPeer(peer);  
       }            
     }));  
     // Start file server  
     service.start();  
   }  
 }  

And now a simple client for downloading the shared file (include versile.jar in your classpath):

 package versileexample;  
 import java.io.FileOutputStream;  
 import org.versile.Versile;  
 import org.versile.common.auth.VPrivateCredentials;  
 import org.versile.crypto.VDecentralIdentity;  
 import org.versile.crypto.VRSAKeyPair;  
 import org.versile.orb.entity.VProxy;  
 import org.versile.orb.link.VLinkReference;  
 import org.versile.reactor.url.VUrl;  
 import org.versile.vse.VSEResolver;  
 import org.versile.vse.stream.VByteStream;  
 import org.versile.vse.stream.VByteStreamerProxy;  
 public class VersileFileServerClientExample {  
   public static void main(String[] args) throws Exception {  
     // Versile license   
     Versile.setInternalUseAGPL();  
     // Enable streaming data types  
     VSEResolver.addToGlobalModules();  
     // Create credentials for logging into the server  
     VRSAKeyPair key = VDecentralIdentity.dia(1024, "test", "peter", "dfw/23hcFDawqaDreq");  
     VPrivateCredentials credentials = new VPrivateCredentials(key);  
     // Export public key (can be inserted into authorized key variable in server example)  
     System.out.println(new String(key.exportPublicArmoredPkcs()));  
     // Get proxy to server and connect  
     VProxy proxy = (VProxy) VUrl.resolve("vop://localhost/",credentials);  
     // Call method returning stream to shared file and connect to stream  
     VByteStreamerProxy streamer = (VByteStreamerProxy) proxy.call("getSharedFile", new Object[] {});  
     VByteStream stream = streamer.connect();  
     stream.waitActive();  
     // Read from stream and write to local file  
     FileOutputStream fos = new FileOutputStream("downloadedfile.txt");  
     byte[] filedata;  
     do {  
       filedata = stream.read(65536);        
       fos.write(filedata);  
     } while(filedata.length>0);  
     fos.close();  
     stream.close();      
     System.out.println("File downloaded and saved");  
     // Disconnect from server  
     ((VLinkReference)proxy.get())._v_link().shutdown(false);  
   }  
 }  

Comments

Popular posts from this blog

My VNC based development environment with Visual Studio Code running on Ubuntu

Intercepting and adjusting SQL generated by Eclipselink JPA

Exporting Kendo UI GRID to Excel with Java