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

Create PDF's in Angular / Typescript

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

Angular 5 - Ahead of Time build configuration for rollup