/src/main/java/org/jwall/web/audit/net/NetworkEventServer.java

https://bitbucket.org/Shuro/org.jwall.web.audit · Java · 200 lines · 108 code · 32 blank · 60 comment · 1 complexity · 37789c8f4d40c1450eb9a2d52e7dfe4a MD5 · raw file

  1. /*
  2. * Copyright (C) 2007-2010 Christian Bockermann <chris@jwall.org>
  3. *
  4. * This file is part of the web-audit library.
  5. *
  6. * web-audit library is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * The web-audit library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. package org.jwall.web.audit.net;
  21. import java.io.File;
  22. import java.io.FileInputStream;
  23. import java.io.InputStream;
  24. import java.net.InetAddress;
  25. import java.net.ServerSocket;
  26. import java.net.Socket;
  27. import java.security.KeyStore;
  28. import java.util.Collection;
  29. import javax.net.ssl.KeyManager;
  30. import javax.net.ssl.KeyManagerFactory;
  31. import javax.net.ssl.SSLContext;
  32. import javax.net.ssl.SSLException;
  33. import javax.net.ssl.SSLServerSocketFactory;
  34. import org.jwall.web.audit.AuditEvent;
  35. import org.jwall.web.audit.AuditEventListener;
  36. import org.jwall.web.audit.util.Authenticator;
  37. import org.slf4j.Logger;
  38. import org.slf4j.LoggerFactory;
  39. /**
  40. *
  41. * This class implements a small event-server thread. It will listen on
  42. * a socket and wait for a <code>NetworkAuditEventSource</code> to connect
  43. * and push all events to the connected event-sources.
  44. *
  45. * <b>This class is not well-tested!</b>
  46. *
  47. * @author Christian Bockermann &lt;chris@jwall.org&gt;
  48. *
  49. */
  50. public class NetworkEventServer
  51. extends Thread
  52. implements AuditEventListener
  53. {
  54. public final static int CLIENT_POLL_TIME = 256;
  55. private static Logger log = LoggerFactory.getLogger( "NetworkEventServer" );
  56. ServerSocket socket;
  57. Authenticator users = null;
  58. Dispatcher dispatcher;
  59. public NetworkEventServer(String s, Authenticator auth)
  60. throws Exception
  61. {
  62. this(s, 10001, auth);
  63. }
  64. public NetworkEventServer(String serv, int port, Authenticator auth)
  65. throws Exception
  66. {
  67. users = auth;
  68. dispatcher = new Dispatcher( CLIENT_POLL_TIME );
  69. socket = new ServerSocket(port, 10, InetAddress.getByName(serv) );
  70. }
  71. public NetworkEventServer(int port, Authenticator auth)
  72. throws Exception
  73. {
  74. users = auth;
  75. dispatcher = new Dispatcher( CLIENT_POLL_TIME );
  76. //dispatcher.start();
  77. socket = new ServerSocket(port, 10 );
  78. }
  79. private NetworkEventServer(ServerSocket ssocket, Authenticator auth){
  80. users = auth;
  81. dispatcher = new Dispatcher( CLIENT_POLL_TIME );
  82. //dispatcher.start();
  83. socket = ssocket;
  84. }
  85. public void start(){
  86. super.start();
  87. dispatcher.start();
  88. }
  89. public static NetworkEventServer createSSLEventServer(File keyFile, String pass, int port, Authenticator auth)
  90. throws Exception
  91. {
  92. return createSSLEventServer(new FileInputStream(keyFile), pass, port, auth);
  93. }
  94. public static NetworkEventServer createSSLEventServer(InputStream keyIn, int port, Authenticator auth)
  95. throws Exception
  96. {
  97. return createSSLEventServer( keyIn, "geheim", port, auth);
  98. }
  99. /**
  100. * This method creates a new NetworkEventServer that is based on an SSL-enabled server socket. Compared to
  101. * the non-SSL case, the additional parameters are the <code>keyStream</code> and the <code>pass</code>, which
  102. * refer to the stream that is used to read the private/public key pair from. The password is used to decrypt
  103. * the private key from the <code>keyStream</code>.
  104. *
  105. * @param keyStream The stream to read the public/private key pair from.
  106. * @param pass The password to decrypt the key information.
  107. * @param port The port on which this server will accept connections.
  108. * @param auth This map contains a set of login/password pairs used to authenticate users.
  109. * @return The SSL-enabled server instance.
  110. * @throws Exception In case the server socket could not be created or something went wrong with the key decryption.
  111. */
  112. public static NetworkEventServer createSSLEventServer(InputStream keyStream, String pass, int port, Authenticator auth)
  113. throws Exception
  114. {
  115. char[] passphrase = pass.toCharArray();
  116. KeyStore keystore = KeyStore.getInstance("JKS");
  117. keystore.load( keyStream ,passphrase );
  118. // Now we initialize a KeyManagerFactory with the KeyStore
  119. KeyManagerFactory kmf =
  120. KeyManagerFactory.getInstance("SunX509");
  121. kmf.init(keystore, passphrase);
  122. // Now we create an SSLContext and initialize it with
  123. // KeyManagers from the KeyManagerFactory
  124. SSLContext context = SSLContext.getInstance("TLS");
  125. KeyManager[] keyManagers = kmf.getKeyManagers();
  126. context.init(keyManagers, null, null);
  127. // First we need a SocketFactory that will create
  128. // SSL server sockets.
  129. SSLServerSocketFactory ssf = context.getServerSocketFactory();
  130. ServerSocket ss = ssf.createServerSocket(port);
  131. NetworkEventServer srv = new NetworkEventServer(ss, auth);
  132. return srv;
  133. }
  134. public void run(){
  135. while(true){
  136. try {
  137. Socket sock = socket.accept();
  138. NetworkClientWorkerThread worker = new NetworkClientWorkerThread(sock, users, this);
  139. dispatcher.registerClient( worker );
  140. worker.start();
  141. } catch (SSLException se) {
  142. log.error( "Cannot establish SSL-socket connection due to ssl-problems: {}", se.getMessage() );
  143. } catch (Exception e) {
  144. e.printStackTrace();
  145. }
  146. }
  147. }
  148. /**
  149. *
  150. * @see org.jwall.web.audit.AuditEventListener#eventArrived(org.jwall.web.audit.AuditEvent)
  151. */
  152. public void eventArrived(AuditEvent e){
  153. dispatcher.enqueueEvents( e );
  154. }
  155. public void eventsArrived( Collection<AuditEvent> events ){
  156. for( AuditEvent evt: events )
  157. eventArrived( evt );
  158. }
  159. /**
  160. * This method is used to unregister one of the client thread from the dispatcher. The call is simply
  161. * delegated to the dispatcher itself.
  162. *
  163. * @param t The client thread to unregister.
  164. */
  165. public void unregisterClient(NetworkClientWorkerThread t){
  166. dispatcher.unregisterClient( t );
  167. }
  168. }