/* Copyright 1999-2011 (c) My-Channels Copyright (c) 2012-2015 Software AG, Darmstadt, Germany and/or Software AG USA Inc., Reston, VA, USA, and/or its subsidiaries and/or its affiliates and/or their licensors. Use, reproduction, transfer, publication or disclosure is prohibited except as specifically provided for in your License Agreement with Software AG. */ package com.pcbsys.nirvana.apps; import com.pcbsys.nirvana.client.*; import com.pcbsys.nirvana.client.p2p.*; import java.util.StringTokenizer; import com.pcbsys.foundation.utils.fEnvironment; import java.io.*; /** * */ public class nP2PShellServer { private static void processArgs(String[] args){ switch (args.length){ case 1: if (args[0].equals("-?")) UsageEnv(); System.setProperty("SHELL",args[0]); break; } } private static void processEnvironmentVariable(String variable){ String laxVAR=System.getProperty("lax.nl.env."+variable); if (laxVAR!=null) System.setProperty(variable,laxVAR); } public static void main( String[] args ) { //Process command line arguments processArgs(args); //Process Environment Variables processEnvironmentVariable("RNAME"); processEnvironmentVariable("LOGLEVEL"); processEnvironmentVariable("HPROXY"); processEnvironmentVariable("HAUTH"); processEnvironmentVariable("CKEYSTORE"); processEnvironmentVariable("CKEYSTOREPASSWD"); processEnvironmentVariable("CAKEYSTORE"); processEnvironmentVariable("CAKEYSTOREPASSWD"); System.out.println("***********************************************************"); System.out.println("* *"); System.out.println("* WARNING WARNING WARNING WARNING WARNING WARNING WARNING *"); System.out.println("* This is a sample application demonstrating how to write *"); System.out.println("* a simple nirvana P2P service. This sample is extremely *"); System.out.println("* insecure and should NEVER be run on any production or *"); System.out.println("* secure hosts. The author accepts no liability for any *"); System.out.println("* damage caused *"); System.out.println("* *"); System.out.println("***********************************************************"); // Adjust the HTTP proxy settings fEnvironment.setProxyEnvironments(); // Install any ssl settings fEnvironment.setSSLEnvironments(); // Get the realm details String[] rproperties = new String[ 4 ]; int idx = 0; String shell = System.getProperty( "SHELL" ); String RNAME = System.getProperty( "RNAME" ); if (RNAME == null) { Usage(); System.exit(1); } if (shell == null) { Usage(); System.exit(1); } StringTokenizer st = new StringTokenizer( RNAME, "," ); while ( st.hasMoreTokens() ) { String someRNAME = (String)st.nextToken(); rproperties[ idx ] = someRNAME; idx++; } // Trim the array String[] rpropertiesTrimmed = new String[ idx ]; System.arraycopy( rproperties, 0, rpropertiesTrimmed, 0, idx ); if ( rpropertiesTrimmed.length == 0 ) { System.out.println( "No realm information supplied" ); System.exit( 1 ); } new nP2PShellServer( rpropertiesTrimmed, shell ); } public nP2PShellServer( String[] rprops, String shell ) { if (rprops == null) return; try { nSessionAttributes nsa = null; try { nsa = new nSessionAttributes( rprops ); } catch ( Exception ex ) { System.out.println( "Error creating Session Attributes. Please check your RNAME" ); System.exit( 1 ); } nServiceFactory factory = new nServiceFactory( nsa ); String srvName = "shell " + java.net.InetAddress.getLocalHost().getHostName(); String os = System.getProperty( "os.name" ); String srvDesc = new String( "Shell Server. Starts a shell and sends output to client on " + os ); nServerService server = factory.createStreamService( srvName, srvDesc ); while ( true ) { nStreamService serv = (nStreamService)server.accept(); new handler( serv, shell ); } } catch ( Exception ex ) { ex.printStackTrace(); } } public class handler { private nStreamService myService; private Process myProcess; private boolean isClosed = false; public handler( nStreamService serv, String shell ) throws IOException { myService = serv; myProcess = Runtime.getRuntime().exec( shell ); streamJoiner sj1 = new streamJoiner( serv.getInputStream(), myProcess.getOutputStream() ); streamJoiner sj2 = new streamJoiner( myProcess.getInputStream(), serv.getOutputStream() ); } public class streamJoiner extends Thread { private OutputStream myOs; private InputStream myIs; private int myBufPos; private flusher myFlusher; public streamJoiner( InputStream is, OutputStream os ) { myIs = is; myOs = os; start(); myFlusher = new flusher(); } public void run() { byte[] buffer = new byte[ 1000 ]; myBufPos = 0; try { while ( true ) { int size = myIs.read( buffer ); if ( size == -1 ) { synchronized ( myService ) { if ( !isClosed ) { myService.close(); isClosed = true; } } myProcess.destroy(); myFlusher.close(); return; } myOs.write( buffer, 0, size ); myBufPos += size; if ( myBufPos > 10000 ) { synchronized ( myOs ) { myOs.flush(); myBufPos = 0; } } } } catch ( Exception ex ) { ex.printStackTrace(); } try { synchronized ( myService ) { if ( !isClosed ) { myService.close(); isClosed = true; } } } catch ( Exception ex ) { } } public class flusher extends Thread { private boolean runLoop = true; public flusher() { start(); } public void close() { runLoop = false; } public void run() { try { while ( runLoop ) { Thread.sleep( 100 ); synchronized ( myOs ) { if ( isClosed ) { return; } if ( myBufPos != 0 ) { myOs.flush(); myBufPos = 0; } } } } catch ( Exception ex ) { } } } // End of flusher Inner Class } // End of streamJoiner Inner Class } // End of handler Inner Class /** * Prints the usage string for this class */ private static void Usage() { System.out.println( "Usage ...\n" ); System.out.println("np2pshellserver \n"); System.out.println( " \n"); System.out.println( " - The type of shell yoou want to offer. For example cmd for win32 or bash for unix" ); System.out.println( "\n\nNote: -? provides help on environment variables \n"); } private static void UsageEnv() { System.out.println( "\n\n(Environment Variables) \n"); System.out.println( "(RNAME) - One or more RNAME entries in the form protocol://host:port" ); System.out.println( " protocol - Can be one of nsp, nhp, nsps, or nhps, where:" ); System.out.println( " nsp - Specifies Nirvana Socket Protocol (nsp)" ); System.out.println( " nhp - Specifies Nirvana HTTP Protocol (nhp)" ); System.out.println( " nsps - Specifies Nirvana Socket Protocol Secure (nsps), i.e. using SSL/TLS" ); System.out.println( " nhps - Specifies Nirvana HTTP Protocol Secure (nhps), i.e. using SSL/TLS" ); System.out.println( " port - The port number of the server" ); System.out.println( "\nHint: - For multiple RNAME entries, use comma separated values which will be attempted in connection weight order\n" ); System.out.println( "(LOGLEVEL) - This determines how much information the nirvana api will output 0 = verbose 7 = quiet\n" ); System.out.println( "(CKEYSTORE) - If using SSL, the location of the keystore containing the client cert\n"); System.out.println( "(CKEYSTOREPASSWD) - If using SSL, the password for the keystore containing the client cert\n"); System.out.println( "(CAKEYSTORE) - If using SSL, the location of the ca truststore\n"); System.out.println( "(CAKEYSTOREPASSWD) - If using SSL, the password for the ca truststore\n"); System.out.println( "(HPROXY) - HTTP Proxy details in the form proxyhost:proxyport, where:" ); System.out.println( " proxyhost - The HTTP proxy host" ); System.out.println( " proxyport - The HTTP proxy port\n" ); System.out.println( "(HAUTH) - HTTP Proxy authentication details in the form user:pass, where:" ); System.out.println( " user - The HTTP proxy authentication username" ); System.out.println( " pass - The HTTP proxy authentication password\n" ); System.exit(1); } } // End of nP2PShellServer Class