added tls code to client

This commit is contained in:
Aidan Hahn 2019-05-19 12:21:00 -07:00
parent 5d66a9880c
commit 3021a1d405
No known key found for this signature in database
GPG key ID: 327711E983899316
2 changed files with 96 additions and 51 deletions

View file

@ -51,7 +51,7 @@ openssl genrsa -passout pass:${CLTCAPASS} -aes256 -out $CLIENT_PATH/private.key
echo "[+] Generating Client signing request"
openssl req -passin pass:${CLTCAPASS} -new -key $CLIENT_PATH/private.key -out $CLIENT_PATH/request.csr -subj "/CN=${CLIENT_CN}"
echo "[+] Generating Client certificate "
openssl x509 -req -passin pass:${CLTCAPASS} -days 365 -in $CLIENT_PATH/request.csr -CA $CLIENT_PATH/ca.crt -CAkey $CLIENT_PATH/ca.key -set_serial 01 -out $CLIENT_PATH/server.crt
openssl x509 -req -passin pass:${CLTCAPASS} -days 365 -in $CLIENT_PATH/request.csr -CA $CLIENT_PATH/ca.crt -CAkey $CLIENT_PATH/ca.key -set_serial 01 -out $CLIENT_PATH/client.crt
echo "[+] Removing passphrase from client key"
openssl rsa -passin pass:${CLTCAPASS} -in $CLIENT_PATH/private.key -out $CLIENT_PATH/private.key
@ -61,7 +61,7 @@ openssl genrsa -passout pass:dontusethiskey -aes256 -out $TEST_PATH/private.key
echo "[+] Generating test signing request"
openssl req -passin pass:dontusethiskey -new -key $TEST_PATH/private.key -out $TEST_PATH/request.csr -subj "/CN=${DontUseMe}"
echo "[+] Generating test certificate "
openssl x509 -req -passin pass:dontusethiskey -days 365 -in $TEST_PATH/request.csr -CA $TEST_PATH/ca.crt -CAkey $TEST_PATH/ca.key -set_serial 01 -out $TEST_PATH/server.crt
openssl x509 -req -passin pass:dontusethiskey -days 365 -in $TEST_PATH/request.csr -CA $TEST_PATH/ca.crt -CAkey $TEST_PATH/ca.key -set_serial 01 -out $TEST_PATH/test.crt
echo "[+] Removing passphrase from test key"
openssl rsa -passin pass:dontusethiskey -in $TEST_PATH/private.key -out $TEST_PATH/private.key
@ -75,4 +75,4 @@ echo "[+] creating combine trust store"
cat $SERVER_PATH/ca.crt $CLIENT_PATH/ca.crt > resources/truststore.pem
echo "[+] initiating gradle build"
./gradlew clear build
./gradlew clean build

View file

@ -11,6 +11,13 @@ package JobServ;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyChannelBuilder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import javax.net.ssl.SSLException;
import java.io.File;
import java.util.InputMismatchException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@ -23,7 +30,8 @@ import java.util.Scanner;
*/
public class JobServClient {
/* The client should not use the same logging module as the server.
/*
* The client should not use the same logging module as the server.
* In a more robust product the server logging module will take advantage of system level
* log aggregators such as journalctl, which the client should not be writing to on the users system
*/
@ -31,33 +39,49 @@ public class JobServClient {
private final ManagedChannel channel;
/* blockingStub is used when the client needs to block until the server responds
/*
* blockingStub is used when the client needs to block until the server responds
* the client doesnt nessesarily need to support asynchronously firing off commands
* in this shell-like interface it would be disconcerting to get multiple returns out of order
* in this shell-like interface it would be disconcerting to get multiple returns out of order
*/
private final ShellServerGrpc.ShellServerBlockingStub blockingStub;
// Constructor connects to server
public JobServClient(String host, int port) {
this(ManagedChannelBuilder.forAddress(host, port)
// TODO: MTLS
.usePlaintext()
.build());
}
// private overload of constructor, used in the above constructor
JobServClient(ManagedChannel channel) {
this.channel = channel;
blockingStub = ShellServerGrpc.newBlockingStub(channel);
/*
* Constructor
* Creates an SslContext from cert, key, and trust store
* Creates a ManagedChannel object from SSL Parameters
* Spawns a new blockingStub for network operations with the server
*/
public JobServClient(String host,
int port,
String trustStore,
String clientCert,
String clientPrivateKey) throws SSLException {
SslContextBuilder builder = GrpcSslContexts.forClient();
builder.trustManager(new File(trustStore));
builder.keyManager(new File(clientCert), new File(clientPrivateKey));
this.channel = NettyChannelBuilder.forAddress(host, port)
.sslContext(builder.build())
.build();
blockingStub = ShellServerGrpc.newBlockingStub(this.channel);
}
/*
* shutdown()
* Gets called when you press cntrl+c
* takes at most 5 seconds to close its connection
*/
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
// sends the server a request for output from PID
// different from getProcessStatus in output expected from the server
// returns process output as string
/*
* getProcessInfo()
* sends the server a request for output from the process identified by 'pid'
* returns process output as string
*/
public String getProcessOutput(int pid) {
logger.info("[+] requesting output");
@ -77,8 +101,11 @@ public class JobServClient {
return response.getOutput();
}
// sends the server a command for a new job, blocks until response
// returns new pid of job
/*
* sendNewJobMessage()
* sends a shell command to the api server
* returns new pid of job
*/
public int sendNewJobMessage(String command) {
// thought of escaping this, but the vulnerability is only client side, from client user input.
logger.info("[+] Sending command to server");
@ -103,8 +130,11 @@ public class JobServClient {
return response.getPid();
}
// requests running status of job
// returns true if job still running else false
/*
* getProcessStatus()
* requests running status of process pid
* returns true if process still running else false
*/
public Boolean getProcessStatus(int pid) {
logger.info("[+] Requesting status of a job");
@ -124,9 +154,12 @@ public class JobServClient {
return response.getIsRunning();
}
// sends PID to server expecting the return cod eof a process
// function returns a 0-255 return code or 277 if still running
// or 278 if error in API
/*
* sends PID to server
* returns process exit code
* returns a 0-255 return code or 277 if still running
* or 278 if error in API
*/
public int getProcessReturn(int pid) {
logger.info("[+] Requesting return code of a job");
@ -146,8 +179,11 @@ public class JobServClient {
return response.getProcessReturnCode();
}
// send a PID to be killed, returns nothing
// logs warning if job status comes back still running
/*
* killProcess()
* send a PID to be killed, function returns nothing
* logs warning if job status comes back still running
*/
public void killProcess(int pid) {
logger.info("[+] Killing a job");
@ -169,40 +205,49 @@ public class JobServClient {
}
}
// Client entrypoint
/*
* main()
* Client entrypoint
* Parses arguments and calls the correct function
*/
public static void main(String[] args) throws Exception {
if (args.length == 1 && args[0] == "help"){
outputHelp();
}
// check args
if (args.length < 3) {
System.out.println("Usage: $ jobservclient host port command");
System.out.println("Or try client --help");
if (args.length < 7) {
System.out.println("Usage: $ ./jobserv-client privatekey, cert, truststore, host, port, command, args");
System.out.println("Or try $ ./jobserv-client help");
return;
}
// start client (or fail if port is improperly formatted)
// start client
// fails if port is improperly formatted or if an ssl exception occurs
JobServClient client;
try {
client = new JobServClient(args[0], Integer.parseInt(args[1]));
client = new JobServClient(args[0], Integer.parseInt(args[1]), args[2], args[1], args[0]);
} catch (NumberFormatException e) {
System.out.println("Invalid Port");
return;
} catch (SSLException e) {
System.out.println(e.getMessage());
return;
}
// declare up here so that multiple switch cases can use it
// declare pid up here so that multiple switch cases can use it
int candidatePid;
// parse remaining args
switch (args[2]) {
case "new":
if (args.length < 4) {
if (args.length < 7) {
System.out.println("Improper formatting, try client --help");
break;
}
String command = "";
for (int token = 3; token < args.length; token++) {
for (int token = 6; token < args.length; token++) {
command += " " + args[token];
}
@ -211,15 +256,15 @@ public class JobServClient {
break;
case "output":
if (args.length != 4) {
if (args.length != 7) {
System.out.println("Improper formatting, try client --help");
break;
}
try {
candidatePid = Integer.parseInt(args[3]);
candidatePid = Integer.parseInt(args[6]);
} catch (InputMismatchException e) {
System.out.println(args[3] + " is not a valid int, much less a valid pid");
System.out.println(args[6] + " is not a valid int, much less a valid pid");
break;
}
@ -228,16 +273,16 @@ public class JobServClient {
break;
case "status":
if (args.length != 4) {
if (args.length != 7) {
System.out.println("Improper formatting, try client --help");
break;
}
try {
candidatePid = Integer.parseInt(args[3]);
candidatePid = Integer.parseInt(args[6]);
} catch (InputMismatchException e) {
System.out.println(args[3] + " is not a valid int, much less a valid pid");
System.out.println(args[6] + " is not a valid int, much less a valid pid");
break;
}
@ -246,16 +291,16 @@ public class JobServClient {
break;
case "kill":
if (args.length != 4) {
if (args.length != 7) {
System.out.println("Improper formatting, try client --help");
break;
}
try {
candidatePid = Integer.parseInt(args[3]);
candidatePid = Integer.parseInt(args[6]);
} catch (InputMismatchException e) {
System.out.println(args[3] + " is not a valid int, much less a valid pid");
System.out.println(args[6] + " is not a valid int, much less a valid pid");
break;
}
@ -264,16 +309,16 @@ public class JobServClient {
break;
case "return":
if (args.length != 4) {
if (args.length != 7) {
System.out.println("Improper formatting, try client --help");
break;
}
try {
candidatePid = Integer.parseInt(args[3]);
candidatePid = Integer.parseInt(args[6]);
} catch (InputMismatchException e) {
System.out.println(args[3] + " is not a valid int, much less a valid pid");
System.out.println(args[6] + " is not a valid int, much less a valid pid");
break;
}