blob: a003d0f541bf5d83ed48d163711b58f94a4dd761 [file] [log] [blame]
package org.apache.tomcat.jni;
import java.util.Properties;
import java.io.*;
import java.net.*;
import java.lang.*;
/** SSL Server server example
*
* @author Mladen Turk
* @version $Revision$, $Date$
*/
public class SSLServer {
public static String serverAddr = null;
public static int serverPort = 0;
public static int serverNmax = 0;
public static int serverNrun = 0;
public static long serverCtx = 0;
public static long serverPool = 0;
public static String serverCert = null;
public static String serverKey = null;
public static String serverCiphers = null;
public static String serverPassword = null;
public static String serverCAFile = null;
private static Acceptor serverAcceptor = null;
private static Object threadLock = new Object();
static {
try {
InputStream is = SSLServer.class.getResourceAsStream
("/org/apache/tomcat/jni/SSL.properties");
Properties props = new Properties();
props.load(is);
is.close();
serverAddr = props.getProperty("server.ip", "127.0.0.1");
serverPort = Integer.decode(props.getProperty("server.port", "4443")).intValue();
serverNmax = Integer.decode(props.getProperty("server.max", "1")).intValue();
serverCert = props.getProperty("server.cert", "server.pem");
serverKey = props.getProperty("server.key", null);
serverCAFile = props.getProperty("server.cacertificate", null);
serverCiphers = props.getProperty("server.ciphers", "ALL");
serverPassword = props.getProperty("server.password", null);
}
catch (Throwable t) {
; // Nothing
}
}
public SSLServer()
{
int i;
serverPool = Pool.create(0);
try {
/* Create SSL Context, one for each Virtual Host */
serverCtx = SSLContext.make(serverPool, SSL.SSL_PROTOCOL_SSLV2 | SSL.SSL_PROTOCOL_SSLV3, SSL.SSL_MODE_SERVER);
/* List the ciphers that the client is permitted to negotiate. */
SSLContext.setCipherSuite(serverCtx, serverCiphers);
/* Load Server key and certificate */
SSLContext.setCertificate(serverCtx, serverCert, serverKey, serverPassword, SSL.SSL_AIDX_RSA);
SSLContext.setVerify(serverCtx, SSL.SSL_CVERIFY_NONE, 10);
serverAcceptor = new Acceptor();
serverAcceptor.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void incThreads() {
synchronized(threadLock) {
serverNrun++;
}
}
public static void decThreads() {
synchronized(threadLock) {
serverNrun--;
}
}
/* Acceptor thread. Listens for new connections */
private class Acceptor extends Thread {
private long serverSock = 0;
private long inetAddress = 0;
private long pool = 0;
public Acceptor() throws Exception {
try {
pool = Pool.create(SSLServer.serverPool);
System.out.println("Accepting: " + SSLServer.serverAddr + ":" +
SSLServer.serverPort);
inetAddress = Address.info(SSLServer.serverAddr, Socket.APR_INET,
SSLServer.serverPort, 0,
pool);
serverSock = Socket.create(Socket.APR_INET, Socket.SOCK_STREAM,
Socket.APR_PROTO_TCP, pool);
int rc = Socket.bind(serverSock, inetAddress);
if (rc != 0) {
throw(new Exception("Can't create Acceptor: bind: " + Error.strerror(rc)));
}
Socket.listen(serverSock, 5);
}
catch( Exception ex ) {
ex.printStackTrace();
throw(new Exception("Can't create Acceptor"));
}
}
public void run() {
int i = 0;
try {
while (true) {
long clientSock = Socket.accept(serverSock);
System.out.println("Accepted id: " + i);
try {
long sa = Address.get(Socket.APR_REMOTE, clientSock);
Sockaddr raddr = new Sockaddr();
if (Address.fill(raddr, sa)) {
System.out.println("Remote Host: " + Address.getnameinfo(sa, 0));
System.out.println("Remote IP: " + Address.getip(sa) +
":" + raddr.port);
}
sa = Address.get(Socket.APR_LOCAL, clientSock);
Sockaddr laddr = new Sockaddr();
if (Address.fill(laddr, sa)) {
System.out.println("Local Host: " + laddr.hostname);
System.out.println("Local Server: " + Address.getnameinfo(sa, 0));
System.out.println("Local IP: " + Address.getip(sa) +
":" + laddr.port);
}
} catch (Exception e) {
// Ignore
e.printStackTrace();
}
Socket.timeoutSet(clientSock, 10000000);
SSLSocket.attach(SSLServer.serverCtx, clientSock);
i = SSLSocket.handshake(clientSock);
if (i == 0) {
Worker worker = new Worker(clientSock, i++,
this.getClass().getName());
SSLServer.incThreads();
worker.start();
}
else {
System.out.println("Handshake error: " + SSL.getLastError());
Socket.destroy(clientSock);
}
}
}
catch( Exception ex ) {
ex.printStackTrace();
}
}
}
private class Worker extends Thread {
private int workerId = 0;
private long clientSock = 0;
private byte [] wellcomeMsg = null;
public Worker(long clientSocket, int workerId, String from) {
this.clientSock = clientSocket;
this.workerId = workerId;
wellcomeMsg = ("SSLServer server id: " + this.workerId + " from " +
from + "\r\n").getBytes();
}
public void run() {
boolean doClose = false;
try {
Socket.send(clientSock, wellcomeMsg, 0, wellcomeMsg.length);
while (!doClose) {
/* Do a blocking read byte at a time */
byte [] buf = new byte[1];
int ret;
ret = Socket.recv(clientSock, buf, 0, 1);
if (ret != 1)
throw(new Exception("Socket.recv failed"));
if (buf[0] == '\n')
continue;
else if (buf[0] == '!') {
doClose = true;
}
Socket.send(clientSock, buf, 0, 1);
if (doClose) {
try {
byte [] msg = ("Bye from worker: " + workerId + "\r\n").getBytes();
Socket.send(clientSock, msg, 0, msg.length);
} catch(Exception e) { }
Socket.close(clientSock);
}
}
} catch (Exception e) {
Socket.destroy(clientSock);
e.printStackTrace();
}
Echo.decThreads();
System.out.println("Worker: " + workerId + " finished");
}
}
public static void main(String [] args) {
try {
Library.initialize(null);
SSL.initialize(null);
SSLServer server = new SSLServer();
} catch (Exception e) {
e.printStackTrace();
}
}
}