|
import java.io.BufferedReader;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStream;
|
|
import java.io.PrintWriter;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.ServerSocket;
|
|
import java.net.Socket;
|
|
import java.net.SocketAddress;
|
|
import java.security.InvalidAlgorithmParameterException;
|
|
import java.security.InvalidKeyException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.Security;
|
|
import java.security.spec.AlgorithmParameterSpec;
|
|
|
|
import javax.crypto.*;
|
|
import javax.crypto.spec.IvParameterSpec;
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
|
|
import org.apache.commons.codec.binary.Base64;
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
|
public class eSVDRP {
|
|
|
|
/**
|
|
* @param args
|
|
*/
|
|
|
|
static ServerSocket enc_sock;
|
|
static Socket svdrp_sock;
|
|
static Cipher ci_in;
|
|
static Cipher ci_out;
|
|
static BufferedReader net_read;
|
|
static PrintWriter net_write;
|
|
|
|
|
|
private static void sendEnc(String input)
|
|
{
|
|
|
|
byte[] data = input.getBytes();
|
|
|
|
try {
|
|
byte[] encdata = ci_out.doFinal(data);
|
|
String sendbuf = new String(Base64.encodeBase64(encdata));
|
|
net_write.write(sendbuf+"\n");
|
|
net_write.flush();
|
|
|
|
} catch (IllegalBlockSizeException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
} catch (BadPaddingException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
private static String readEnc() {
|
|
try {
|
|
while(!net_read.ready())
|
|
Thread.sleep(200);
|
|
|
|
String line = net_read.readLine();
|
|
byte[] data = Base64.decodeBase64(line);
|
|
byte[] unenc = ci_in.doFinal(data);
|
|
String data_str = new String(unenc);
|
|
return data_str;
|
|
|
|
} catch (IOException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
return null;
|
|
} catch (IllegalBlockSizeException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
} catch (BadPaddingException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
} catch (InterruptedException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
// TODO Auto-generated method stub
|
|
System.out.println("eSVDRP - Encrypted SVDRP Proxy");
|
|
|
|
//Settings lesen
|
|
BufferedReader settings;
|
|
try {
|
|
settings = new BufferedReader(new FileReader("/etc/esvdrp.conf"));
|
|
} catch (FileNotFoundException e2) {
|
|
// TODO Auto-generated catch block
|
|
System.err.println("/etc/esvdrp.conf not found. Please create it. Exiting");
|
|
return;
|
|
}
|
|
|
|
String vdr_host = "127.0.0.1";
|
|
int vdr_port = 2001;
|
|
int esvdrp_port = 2101;
|
|
String encKey = null;
|
|
|
|
try {
|
|
while(settings.ready())
|
|
{
|
|
String line = settings.readLine();
|
|
if(!line.contains("="))
|
|
continue;
|
|
|
|
String skey = line.split("=")[0];
|
|
String svalue = line.split("=")[1];
|
|
|
|
if(skey.equals("esvdrp_port"))
|
|
esvdrp_port = Integer.parseInt(svalue);
|
|
else if(skey.equals("vdrhost"))
|
|
vdr_host = svalue;
|
|
else if(skey.equals("vdrport"))
|
|
vdr_port = Integer.parseInt(svalue);
|
|
else if(skey.equals("key"))
|
|
encKey = svalue;
|
|
|
|
}
|
|
} catch (NumberFormatException e1) {
|
|
// TODO Auto-generated catch block
|
|
e1.printStackTrace();
|
|
} catch (IOException e1) {
|
|
// TODO Auto-generated catch block
|
|
e1.printStackTrace();
|
|
}
|
|
|
|
if(encKey.length() != 8)
|
|
{
|
|
System.err.println("Invalid Key-length. Please provide an Key with exact 8 Characters.");
|
|
return;
|
|
}
|
|
|
|
System.err.println("eSVDRP-Port:" + esvdrp_port + " - VDR: " + vdr_host + ":" + vdr_port + " - Key: " + encKey);
|
|
|
|
//Setup Encryption
|
|
try {
|
|
Security.addProvider(new BouncyCastleProvider());
|
|
//Key
|
|
SecretKey ci_key = new SecretKeySpec( encKey.getBytes(),"DES");
|
|
byte[] iv = new byte[]{(byte)0x8E, 0x12, 0x39, (byte)0x9C,0x07,0x72,0x6F, 0x5A};
|
|
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
|
|
//Inut Cipher
|
|
|
|
ci_in = Cipher.getInstance("DES/CFB8/NoPadding");
|
|
ci_in.init(Cipher.DECRYPT_MODE, ci_key,paramSpec);
|
|
ci_out = Cipher.getInstance("DES/CFB8/NoPadding");
|
|
ci_out.init(Cipher.ENCRYPT_MODE,ci_key,paramSpec);
|
|
|
|
System.out.println("Cipher Blocksize is " + ci_in.getBlockSize());
|
|
} catch (NoSuchAlgorithmException e1) {
|
|
// TODO Auto-generated catch block
|
|
e1.printStackTrace();
|
|
} catch (NoSuchPaddingException e1) {
|
|
// TODO Auto-generated catch block
|
|
e1.printStackTrace();
|
|
} catch (InvalidKeyException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
} catch (InvalidAlgorithmParameterException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
|
|
try {
|
|
enc_sock = new ServerSocket(esvdrp_port);
|
|
} catch (IOException e1) {
|
|
// TODO Auto-generated catch block
|
|
e1.printStackTrace();
|
|
}
|
|
|
|
System.out.println("Secure Connection Ready.");
|
|
while( true )
|
|
{
|
|
try {
|
|
Socket client = enc_sock.accept();
|
|
|
|
//Setup Encryption
|
|
System.out.println("Accepted Connection");
|
|
|
|
InputStream net_in = client.getInputStream();
|
|
OutputStream net_out = client.getOutputStream();
|
|
|
|
//Stringreader/writer
|
|
InputStreamReader isr = new InputStreamReader(net_in);
|
|
net_read = new BufferedReader(isr,8192);
|
|
net_write = new PrintWriter(net_out, true);
|
|
|
|
//Send greeting
|
|
String msg = "200-eSVDRP Proxy ready\n";
|
|
sendEnc(msg);
|
|
|
|
//Waiting for arraive of regreeting
|
|
int i = 0;
|
|
Boolean regreet_fail = false;
|
|
while(!net_read.ready())
|
|
{
|
|
Thread.sleep(100);
|
|
i++;
|
|
if(i > 20) //No Answer after 2secs kicks the Client
|
|
{
|
|
System.err.println("Timeout waiting for Client answer");
|
|
regreet_fail = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
String regreet = readEnc();
|
|
|
|
if(regreet == null)
|
|
regreet_fail = true;
|
|
else if(!regreet.startsWith("300")) //if returncode is wrong kick client
|
|
regreet_fail = true;
|
|
|
|
if(regreet_fail)
|
|
{
|
|
client.close();
|
|
System.out.println("Got no response");
|
|
continue;
|
|
}
|
|
|
|
System.out.println("-->Handshake ok");
|
|
|
|
//At this Point Connection is ready to compute SVDRP Request to VDR
|
|
|
|
//Establich Connection to VDR
|
|
SocketAddress sockaddr = new InetSocketAddress(vdr_host, vdr_port);
|
|
svdrp_sock = new Socket();
|
|
svdrp_sock.connect(sockaddr, 500);
|
|
|
|
InputStream vdr_net_in = svdrp_sock.getInputStream();
|
|
InputStreamReader vdr_isr = new InputStreamReader(vdr_net_in);
|
|
BufferedReader vdr_net_read = new BufferedReader(vdr_isr,8192);
|
|
OutputStream vdr_net_out = svdrp_sock.getOutputStream();
|
|
PrintWriter vdr_net_write = new PrintWriter(vdr_net_out, true);
|
|
|
|
//SVDRP Connection ready -- Pipe all to esvdrp
|
|
|
|
i = 0;
|
|
|
|
while(client.isConnected())
|
|
{
|
|
if(!svdrp_sock.isConnected())
|
|
break;
|
|
|
|
if(net_read.ready())
|
|
{
|
|
String read = readEnc();
|
|
if(read.startsWith("999"))
|
|
{
|
|
System.out.println("Session end requested from client");
|
|
break;
|
|
}
|
|
|
|
vdr_net_write.write(read + "\n");
|
|
vdr_net_write.flush();
|
|
System.out.println("Relaying Data to VDR: " + read);
|
|
i = 0;
|
|
}
|
|
else if(vdr_net_read.ready())
|
|
{
|
|
String read = vdr_net_read.readLine();
|
|
sendEnc(read);
|
|
i = 0;
|
|
}
|
|
else if(i > 2000)
|
|
break;
|
|
else
|
|
{
|
|
i++;
|
|
Thread.sleep(10);
|
|
System.out.print(".");
|
|
}
|
|
|
|
}
|
|
|
|
if(!svdrp_sock.isClosed())
|
|
svdrp_sock.close();
|
|
|
|
if(!client.isClosed())
|
|
client.close();
|
|
|
|
System.out.println("Session closed");
|
|
|
|
} catch (IOException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
break;
|
|
|
|
} catch (InterruptedException e) {
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|