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