1 20 package org.lucane.server; 21 22 import org.lucane.common.concepts.*; 23 import org.lucane.common.crypto.KeyTool; 24 import org.lucane.server.acl.AccessController; 25 import org.lucane.server.auth.Authenticator; 26 import org.lucane.server.database.*; 27 import org.lucane.server.store.*; 28 import org.lucane.common.*; 29 import org.lucane.common.net.ClientSocketFactory; 30 import org.lucane.common.net.ObjectConnection; 31 import org.lucane.common.net.ServerSocketFactory; 32 33 import java.io.*; 34 import java.net.*; 35 import java.util.*; 36 37 40 public class Server 41 { 42 43 private String workingDirectory; 44 45 private static final String CONFIG_FILE = "etc/server-config.xml"; 46 private static final String LOG_FILE = "logs/lucane.log"; 47 public static final String APPLICATIONS_DIRECTORY = "applications/"; 48 public static final String VERSION = "0.7.5"; 49 50 private static Server instance = null; 52 public static Server getInstance() 53 { 54 return instance; 55 } 56 57 private ServerConfig config; 59 60 private ServerSocket plainSocket; 61 private ServerSocket sslSocket; 62 private Store store; 63 private Authenticator authenticator; 64 private AccessController accessController; 65 private DatabaseAbstractionLayer dbLayer; 66 private String privateKey; 67 68 71 private Server(ServerConfig config, String workingDirectory) 72 { 73 Server.instance = this; 74 this.config = config; 75 this.workingDirectory = workingDirectory; 76 this.dbLayer = null; 77 this.privateKey = "nokey"; 78 79 try { 80 dbLayer = DatabaseAbstractionLayer.createLayer(config); 81 Logging.getLogger().finer("dbLayer : " + dbLayer); 82 83 this.store = new Store(config); 84 } catch (Exception ex) { 85 Logging.getLogger().severe( 86 "#Err > Unable to connect to the database : " 87 + ex.getMessage()); 88 ex.printStackTrace(); 89 System.exit(1); 90 } 91 92 try { 93 this.authenticator = Authenticator.newInstance(config); 94 } catch (Exception e) { 95 Logging.getLogger().severe("Unable to get Authenticator instance."); 96 e.printStackTrace(); 97 System.exit(1); 98 } 99 100 try { 101 this.accessController = AccessController.newInstance(config); 102 } catch (Exception e) { 103 Logging.getLogger().severe("Unable to get AccessController instance."); 104 e.printStackTrace(); 105 System.exit(1); 106 } 107 } 108 109 112 private void initConnectInfo() 113 { 114 int port = config.getPort(); 115 String publicKey = "nokey"; 116 117 if(config.isSslEnabled()) 118 { 119 port = config.getSslPort(); 120 121 try { 122 this.privateKey = KeyTool.createPrivateStore("server", config.getSslPassword()); 123 publicKey = KeyTool.createPublicStore(privateKey, "server"); 124 } catch(Exception e) { 125 Logging.getLogger().severe("Unable to generate keypair : " + e); 126 System.exit(1); 127 } 128 } 129 130 ConnectInfo myConnectInfo = new ConnectInfo("server", 131 "not-used", 132 port, publicKey, "Server"); 133 ConnectInfoManager.getInstance().setServerInfo(myConnectInfo); 134 ConnectInfoManager.getInstance().addConnectInfo(myConnectInfo); 135 } 136 137 140 public void acceptConnections() 141 { 142 if(config.isSslEnabled()) 143 this.acceptSslConnections(); 144 145 this.acceptPlainConnections(); 146 } 147 148 private void acceptPlainConnections() 149 { 150 try { 151 this.plainSocket = ServerSocketFactory.getServerSocket(config.getPort()); 152 } catch (Exception e) { 153 Logging.getLogger().severe("#Err > Unable to listen on the port " + config.getPort() + "."); 154 e.printStackTrace(); 155 System.exit(1); 156 } 157 158 Runnable plain = new Runnable () { 159 public void run() { 160 while(!plainSocket.isClosed()) 161 { 162 try { 163 MessageHandler handler = new MessageHandler(plainSocket.accept()); 164 handler.start(); 165 } catch (IOException ex) { 166 if(!plainSocket.isClosed()) 167 Logging.getLogger().warning("#Err > Unable to accept connections."); 168 } 169 } 170 } 171 }; 172 173 new Thread (plain).start(); 174 Logging.getLogger().info("Accepting plain connections on port " + config.getPort()); 175 } 176 177 private void acceptSslConnections() 178 { 179 try { 180 this.sslSocket = ServerSocketFactory.getServerSocket(config.getSslPort(), 181 this.privateKey, "server", config.getSslPassword()); 182 } catch (Exception e) { 183 Logging.getLogger().severe("#Err > Unable to listen on the port " + config.getSslPort() + "."); 184 e.printStackTrace(); 185 System.exit(1); 186 } 187 188 Runnable ssl = new Runnable () { 189 public void run() { 190 while(!sslSocket.isClosed()) 191 { 192 try { 193 MessageHandler handler = new MessageHandler(sslSocket.accept()); 194 handler.start(); 195 } catch (IOException ex) { 196 if(!sslSocket.isClosed()) 197 Logging.getLogger().warning("#Err > Unable to accept connections."); 198 } 199 } 200 } 201 }; 202 203 new Thread (ssl).start(); 204 Logging.getLogger().info("Accepting SSL connections on port " + config.getSslPort()); 205 } 206 207 210 public void shutdown() 211 { 212 this.authenticator.disableLogin(); 213 ConnectInfoManager.getInstance().kickAllUsers(); 214 Logging.getLogger().info("Users disconnected."); 215 ServiceManager.getInstance().shutdownAllServices(); 216 Logging.getLogger().info("Services shutdowned."); 217 218 try { 219 this.plainSocket.close(); 220 if(config.isSslEnabled()) 221 this.sslSocket.close(); 222 223 Logging.getLogger().info("Socket closed."); 224 } catch (IOException e) { 225 Logging.getLogger().warning("Unable to close socket : " + e); 226 } 227 228 System.exit(0); 229 } 230 231 236 public void sendConnectInfo(String name, ObjectConnection oc) 237 { 238 ConnectInfo ci = ConnectInfoManager.getInstance().getConnectInfo(name); 239 if(ci != null) 240 { 241 try { 242 oc.write(ci); 243 } catch (Exception e) {} 244 } 245 else 246 { 247 try { 248 oc.write("unknown"); 249 } catch (Exception e) {} 250 } 251 } 252 253 256 public void sendUserList(ObjectConnection oc) 257 { 258 Vector v = new Vector(); 260 Iterator i = ConnectInfoManager.getInstance().getClientConnectInfos(); 261 while(i.hasNext()) 262 v.addElement(i.next()); 263 264 try { 266 oc.write(v); 267 } catch (Exception e) {} 268 } 269 270 public void sendServerConnectInfo(ObjectConnection oc) 271 { 272 try { 273 oc.write(ConnectInfoManager.getInstance().getServerInfo()); 274 } catch(Exception e) { 275 e.printStackTrace(); 276 } 277 } 278 279 285 public void sendPluginList(ObjectConnection oc, String source) 286 { 287 Vector plist = new Vector(); 288 Iterator plugins; 289 String line = ""; 290 291 try 292 { 293 UserConcept user = store.getUserStore().getUser(source); 294 plugins = store.getPluginStore().getAuthorizedPlugins(user); 295 296 while(plugins.hasNext()) 297 { 298 PluginConcept plugin = (PluginConcept)plugins.next(); 299 line = plugin.getName(); 300 line += " " + plugin.getVersion(); 301 plist.add(line); 302 } 303 oc.write(plist); 304 } 305 catch (Exception e) 306 { 307 Logging.getLogger().warning("Unable to send the plugin list."); 308 e.printStackTrace(); 309 } 310 } 311 312 317 public void sendPluginFile(ObjectConnection oc, String data) 318 { 319 DataInputStream dis = null; 320 try 321 { 322 dis = new DataInputStream(new FileInputStream(getWorkingDirectory()+APPLICATIONS_DIRECTORY + data + ".jar")); 323 byte[] buf = new byte[dis.available()]; 324 dis.readFully(buf); 325 oc.write(buf); 326 } 327 catch (Exception e) 328 { 329 Logging.getLogger().warning("Unable to send the file: " + data + ".jar"); 330 } 331 finally { 332 if(dis != null) 333 { 334 try { 335 dis.close(); 336 } catch(IOException ioe) {} 337 } 338 339 } 340 } 341 342 347 public void sendStartupPlugin(ObjectConnection oc, String source) 348 { 349 try 350 { 351 UserConcept user = store.getUserStore().getUser(source); 352 oc.write(user.getStartupPlugin()); 353 } 354 catch (Exception e) 355 { 356 } 357 } 358 359 362 public void sendUserListToEveryone() 363 { 364 ArrayList userList = new ArrayList(); 365 Iterator users = ConnectInfoManager.getInstance().getClientConnectInfos(); 366 while(users.hasNext()) 367 { 368 ConnectInfo user = (ConnectInfo)users.next(); 369 userList.add(user.getName()); 370 } 371 372 Map action = new HashMap(); 373 action.put("command", "USER_LIST"); 374 action.put("users", userList); 375 376 Iterator clients = ConnectInfoManager.getInstance().getClientConnectInfos(); 378 while(clients.hasNext()) 379 { 380 ConnectInfo client = (ConnectInfo)clients.next(); 381 try { 382 ObjectConnection oc = sendMessageTo(client, "Client", action); 383 oc.close(); 384 } catch (Exception e) { 385 Logging.getLogger().warning("unable to send user list to " + client); 386 387 ConnectInfoManager.getInstance().removeConnectInfo(client); 390 break; 391 } 392 } 393 } 394 395 396 403 public ObjectConnection sendMessageTo(ConnectInfo dest, String app, Object data) 404 throws Exception 405 { 406 Socket sock = ClientSocketFactory.getSocket(dest); 407 ObjectConnection oc = new ObjectConnection(sock); 408 409 Message msg = new Message(ConnectInfoManager.getInstance().getServerInfo(), dest, app, data); 410 oc.write(msg); 411 412 return oc; 413 } 414 415 420 public DatabaseAbstractionLayer getDBLayer() 421 { 422 return this.dbLayer; 423 } 424 425 430 public Store getStore() 431 { 432 return store; 433 } 434 435 440 public Authenticator getAuthenticator() 441 { 442 return this.authenticator; 443 } 444 445 450 public AccessController getAccessController() 451 { 452 return this.accessController; 453 } 454 455 460 public String getWorkingDirectory() 461 { 462 return workingDirectory; 463 } 464 465 466 468 471 public static void shutdownServer(String [] args) 472 { 473 Server.getInstance().shutdown(); 474 } 475 476 481 public static void main(String [] args) 482 { 483 if (args.length > 1) { 484 System.err.println("USAGE :\nserver.(bat|sh) [server path]"); 485 System.exit(1); 486 } 487 488 String workingDirectory; 490 if (args.length==1) { 491 workingDirectory=args[0]; 492 } else { 493 workingDirectory=System.getProperty("user.dir"); 494 } 495 workingDirectory=workingDirectory.replace('\\','/'); 496 if (workingDirectory.startsWith("\"")) 497 workingDirectory=workingDirectory.substring(1, workingDirectory.length()-2); 498 if (!workingDirectory.endsWith("/")) 499 workingDirectory+="/"; 500 501 try { 503 new File(workingDirectory + "/logs").mkdirs(); 504 Logging.init(workingDirectory+LOG_FILE, "ALL"); 505 } catch(IOException ioe) { 506 System.err.println("Unable to init logging, exiting."); 507 System.exit(1); 508 } 509 510 ServerConfig config = null; 511 512 try { 513 config = new ServerConfig(workingDirectory+CONFIG_FILE); 514 } catch (Exception e) { 515 Logging.getLogger().severe("Unable to read or parse the config file."); 516 e.printStackTrace(); 517 System.exit(1); 518 } 519 520 Server server = new Server(config, workingDirectory); 522 server.initConnectInfo(); 523 ServiceManager.getInstance().loadAllServices(); 524 ServiceManager.getInstance().startAllServices(); 525 server.acceptConnections(); 526 Logging.getLogger().info("Server is ready."); 527 } 528 } 529 | Popular Tags |