1 21 package freecs; 22 23 import freecs.content.*; 24 import freecs.content.Connection; 25 import freecs.layout.*; 26 import freecs.auth.*; 27 import freecs.core.*; 28 import freecs.external.XmlRpcManager; 29 import freecs.interfaces.*; 30 import freecs.util.*; 31 import freecs.util.logger.LogWriter; 32 33 import java.util.Calendar ; 34 import java.util.Iterator ; 35 import java.util.Set ; 36 import java.util.TimeZone ; 37 import java.util.Vector ; 38 import java.util.Hashtable ; 39 import java.util.Enumeration ; 40 import java.util.Properties ; 41 import java.text.SimpleDateFormat ; 42 43 import java.net.InetAddress ; 44 import java.nio.charset.Charset ; 45 import java.nio.charset.CharsetEncoder ; 46 47 import java.io.IOException ; 48 import java.io.File ; 49 import java.io.FileInputStream ; 50 import java.io.FileNotFoundException ; 51 import java.net.UnknownHostException ; 52 57 public class Server implements IReloadable { 58 private static final String VERSION = "1.2.20060102"; 60 61 public static final int REQUEST_TYPE_HTTP = 1; 63 64 public static String BASE_PATH; 66 67 public static final long startupTime=System.currentTimeMillis(); 68 69 public String DEFAULT_CHARSET="iso-8859-1", COOKIE_DOMAIN, 72 SERVER_NAME, TIMEZONE, ADMIN_HTTP_ALLOWED, 73 ADMIN_HTTP_USERNAME, ADMIN_HTTP_PASSWORD, ADMIN_XMLRPC_ALLOWED; 74 public long TOUCH_USER_DELAY, READER_MAX_IDLETIME, FILE_CHECK_INTERVAL, 75 FLOOD_PROTECT_MILLIS, USER_TIMEOUT, USER_AWAY_TIMEOUT, 76 USER_REMOVE_SCHEDULE_TIME, HOST_BAN_DURATION, VIP_TIMEOUT, 77 READER_TIMEOUT, LOGIN_TIMEOUT; 78 public boolean ALLOW_EXTERNAL, DEBUG_TEMPLATESET, USE_HTTP11, 79 USE_IP_BAN, THREAD_PER_READ, USE_TOKENSTORE, MD5_PASSWORDS, 80 USE_MESSAGE_RENDER_CACHE, USE_TRAFFIC_MONITOR, USE_CENTRAL_REQUESTQUEUE, 81 STRICT_HOST_BINDING; 82 public int READER_MAX_QUEUE, READER_MAX_QUEUE_USAGE, MAX_READERS, MAX_BAN_DURATION, 83 DEFAULT_BAN_DURATION, FLOOD_PROTECT_TOLERANC, FLOOD_BAN_DURATION, 84 READBUFFER_SIZE, MAX_USERS, COLOR_CHANGE_INTERVAL, MAX_USERNAME_LENGTH, 85 MAX_DIE_NUMBER, MAX_DIE_EYES, TCP_RECEIVE_BUFFER_WINDOW, 86 LOG_QUEUE_SIZE, MAX_REQUESTS_PER_PROXY_IP, MAX_REQUESTS_PER_IP, 87 MAX_SUUSERS_PER_STARTGROUP, INITIAL_RESPONSE_QUEUE, MAX_RESPONSE_QUEUE, 88 MAX_GROUPNAME_LENGTH, MAX_GROUPTHEME_LENGTH, ADMIN_XMLRPC_PORT, TOOL_PROTECT_COUNTER, 89 TOOL_PROTECT_TOLERANC, TOOL_BAN_DURATION, TOOL_PROTECT_MINMILLS, TOOL_PROTECT_MINCOUNTER, 90 JOIN_PUNISHED_COUNTER; 91 92 private Vector adminHosts; 93 public Vector allowedLoginHosts; 94 public TemplateManager templatemanager = null; 95 public AuthManager auth; 96 public static Server srv = null; 97 private Hashtable banList; 98 public InetAddress lh = null; 99 public Properties props; 100 public static Calendar cal = Calendar.getInstance(); 101 private volatile boolean isRunning = true; 102 public Charset defaultCs=Charset.forName(DEFAULT_CHARSET); 103 public CharsetEncoder defaultCsEnc=defaultCs.newEncoder(); 104 105 public static boolean TRACE_CREATE_AND_FINALIZE = false; 106 107 private Hashtable tokenStore = new Hashtable (); 108 109 public long KEEP_ALIVE_TIMEOUT; 110 111 public String UNAME_PREFIX_GOD, 112 UNAME_PREFIX_GUEST, 113 UNAME_PREFIX_MODERATOR, 114 UNAME_PREFIX_PUNISHED, 115 UNAME_PREFIX_SU, 116 UNAME_PREFIX_VIP, 117 UNAME_SUFFIX_GOD, 118 UNAME_SUFFIX_GUEST, 119 UNAME_SUFFIX_MODERATOR, 120 UNAME_SUFFIX_PUNISHED, 121 UNAME_SUFFIX_SU, 122 UNAME_SUFFIX_VIP; 123 124 public short FN_DEFAULT_MODE_FALSE = 0; 125 public short FN_DEFAULT_MODE_TRUE = 2; 126 127 public Server () { 128 LOG_MASK[0]=new Short (LVL_MINOR); 130 LOG_MASK[1]=new Short (LVL_MINOR); 131 LOG_MASK[2]=new Short (LVL_MINOR); 132 LOG_MASK[3]=new Short (LVL_MINOR); 133 LOG_MASK[4]=new Short (LVL_MINOR); 134 135 try { 136 lh = InetAddress.getLocalHost (); 137 } catch (UnknownHostException uhe) { 138 System.out.println ("Server: No networkinterface found: " + uhe.getCause()); 139 uhe.printStackTrace(); 140 System.exit (1); 141 } 142 banList = new Hashtable (); 143 props = new Properties (); 144 adminHosts = new Vector (); 145 allowedLoginHosts = new Vector (); 146 } 147 148 158 public static void main (String args[]) { 159 for (int i = 0; i < args.length; i++) { 160 if (args[i].startsWith ("-b=")) { 161 BASE_PATH=args[0].substring(3); 162 } else if (args[i].equals("printcharsets")) { 163 System.out.println("Available Charsets:"); 164 Set ks = Charset.availableCharsets().keySet(); 165 for (Iterator it = ks.iterator(); it.hasNext(); ) { 166 System.out.print(":> "); 167 System.out.println((String ) it.next()); 168 } 169 System.exit(0); 170 } 171 } 172 if (BASE_PATH==null) 173 BASE_PATH="./"; 174 srv=new Server (); 175 srv.readConfig (); 176 srv.initServer (); 177 srv.startThreads (); 178 if (srv.USE_CENTRAL_REQUESTQUEUE) 179 Server.log ("Server", "starting up with CENTRAL-requestqueue", Server.MSG_STATE, Server.LVL_MAJOR); 180 else 181 Server.log ("Server", "starting up with per RequestReader-requestqueue", Server.MSG_STATE, Server.LVL_MAJOR); 182 long lastMessage=0; 183 while (srv.isRunning ()) { 184 188 try { 189 long now = System.currentTimeMillis (); 190 long rws[][] = RequestReader.getWorkingSince(); 191 boolean b[] = RequestReader.getAliveState(); 192 StringBuffer sb = new StringBuffer ("ThreadsWorkingTime:"); 193 for (int i = 0; i < rws.length; i++) { 194 if (rws[i][0] == 0) { 195 sb.append (" 0, "); 196 } else { 197 sb.append (" "); 198 sb.append (now - rws[i][0]); 199 sb.append (", "); 200 } 201 if (b[i]) sb.append ("alive@"); 202 else sb.append ("dead@"); 203 switch ((short) rws[i][1]) { 204 case RequestReader.WAITING: 205 sb.append("waiting"); 206 continue; 207 case RequestReader.EVAL_GET_MESSAGES_APND2WRITE: 208 sb.append("appending message to writequeue"); 209 continue; 210 case RequestReader.EVAL_GET_MESSAGES_SND_MSGS: 211 sb.append("sending scheduled message"); 212 continue; 213 case RequestReader.EVAL_GET_MESSAGES: 214 sb.append("sending messages-frame"); 215 continue; 216 case RequestReader.EVAL_GET_STATE: 217 sb.append("retrieving /state"); 218 continue; 219 case RequestReader.EVAL_GET: 220 sb.append("evaluating getrequest"); 221 continue; 222 case RequestReader.EVAL_POST: 223 sb.append("evaluating postrequest"); 224 continue; 225 case RequestReader.EVAL_POST_LOGIN: 226 sb.append("loging in"); 227 continue; 228 case RequestReader.EVAL_PREP4SEND: 229 sb.append("perparing for sending"); 230 continue; 231 case RequestReader.EVAL_SEND: 232 sb.append("evaluating a /SEND request"); 233 continue; 234 case RequestReader.EVAL_SENDFINAL: 235 sb.append("sending content"); 236 continue; 237 case RequestReader.EVALUATE_COMMAND: 238 sb.append("evaluating a command"); 239 String cmd = RequestReader.getCurrCommant(i); 240 if (cmd != null) 241 sb.append (" (").append (cmd).append (")"); 242 continue; 243 case RequestReader.EVALUATING: 244 sb.append("evaluating"); 245 continue; 246 case RequestReader.PARSE_MSG: 247 sb.append("parsing message"); 248 continue; 249 case RequestReader.READING: 250 sb.append("reading"); 251 continue; 252 case RequestReader.EVAL_POST_LOGIN_RESULT: 253 sb.append("evaluating login-result"); 254 continue; 255 case RequestReader.TRYLOGIN: 256 sb.append("trylogin"); 257 continue; 258 case RequestReader.TRYLOGIN_AUTHENTICATE: 259 sb.append("trylogin authenticate"); 260 continue; 261 case RequestReader.TRYLOGIN_CHECK_FRIENDS: 262 sb.append("trylogin check friends"); 263 continue; 264 case RequestReader.TRYLOGIN_CHECK4PRESENCE: 265 sb.append("trylogin check for presence"); 266 continue; 267 case RequestReader.TRYLOGIN_CORRECT_PERMISSION: 268 sb.append("trylogin correct permission"); 269 continue; 270 case RequestReader.TRYLOGIN_SCHEDULE_FRIENDMSGS: 271 sb.append("trylogin schedule online-friends-messages"); 272 continue; 273 case RequestReader.TRYLOGIN_SCHEDULE_VIPMSG: 274 sb.append("trylogin schedule vip-message"); 275 continue; 276 case RequestReader.TRYLOGIN_SEND_LOGINMSG: 277 sb.append("trylogin send loginmessages"); 278 continue; 279 case RequestReader.TRYLOGIN_SET_GROUP: 280 sb.append("trylogin set group"); 281 continue; 282 case RequestReader.TRYLOGIN_SET_PERMISSION: 283 sb.append("trylogin set permission"); 284 continue; 285 } 286 } 287 Server.log ("static Server", sb.toString(), MSG_STATE, LVL_VERBOSE); 288 Runtime r = Runtime.getRuntime (); 289 long free = r.freeMemory (); 290 long total = r.totalMemory (); 291 long max = r.maxMemory (); 292 long used = r.totalMemory () - r.freeMemory (); 293 sb = new StringBuffer (); 294 sb.append ("Memory-Report (VM-MaxSize/VM-CurrSize/free/used): "); 295 sb.append (max).append ("/"); 296 sb.append (total).append ("/"); 297 sb.append (free).append ("/"); 298 sb.append (used); 299 Server.log (null, sb.toString(), MSG_STATE, LVL_MINOR); 300 301 long lVal = now + 30001; 303 for (Enumeration e = srv.banList.keys (); e.hasMoreElements () ; ) { 304 Object key = e.nextElement (); 305 BanObject bObj = (BanObject) srv.banList.get(key); 306 if (bObj == null) 307 continue; 308 if (bObj.time < now) { 309 if (checkLogLvl (Server.MSG_STATE, Server.LVL_MINOR)) { 310 sb = new StringBuffer ("Server: removing ban for ").append (key); 311 Server.log ("static Server", sb.toString (), MSG_STATE, LVL_MINOR); 312 } 313 srv.banList.remove (key); 314 } else if (bObj.time < lVal) 315 lVal = bObj.time; 316 } 317 long slpTime = lVal - now; 318 if (slpTime < 30) 319 slpTime = 30; 320 Thread.sleep(slpTime); 321 } catch (Exception ie) { } 322 } 323 } 324 325 private void startThreads() { 326 try { 327 UserManager.startUserManager(); 328 RequestReader.startRequestReader(true); 329 RequestReader.startRequestReader(true); 330 CentralSelector.startCentralSelector(); 331 Responder.startResponder(); 332 Listener.startListener(); 333 } catch (Exception e) { 334 Server.debug(this, "Exception during starting threads:", e, MSG_ERROR, LVL_HALT); 335 } 336 try { 337 XmlRpcManager.startManager(); 338 } catch (Exception e) { 339 Server.debug(this, "Exception during starting XmlRpcManager (Server will not be reachable via XML-RPC):", e, MSG_ERROR, LVL_MAJOR); 340 } 341 } 342 343 public void readConfig() { 344 Server.log(this, "FreeCS Startup", MSG_CONFIG, LVL_MINOR); 345 StringBuffer sb = new StringBuffer (BASE_PATH).append("/config"); 346 File cFile = new File (sb.toString()); 347 if (!cFile.exists()) { 348 Server.log(this, "config directory missing\r\n" + BASE_PATH + "/config", MSG_ERROR, LVL_HALT); 349 } 350 sb = new StringBuffer (BASE_PATH).append("/config/config.cfg"); 351 cFile = new File (sb.toString()); 352 if (!cFile.exists()) { 353 Server.log(this, "config file missing\r\n" + sb.toString(), MSG_ERROR, LVL_HALT); 354 } 355 356 try { 357 FileInputStream in = new FileInputStream (cFile); 358 props.load(in); 359 in.close(); 360 } catch (FileNotFoundException fnfe) { 361 } catch (IOException ioe) { 363 Server.log(this, "unable to read config-files", MSG_ERROR, LVL_HALT); 364 } 365 366 if (props.getProperty("port") == null) 368 Server.log(this, "No port specified in config: port=[portnumber]", MSG_ERROR, LVL_HALT); 369 370 checkForConfigValues(); 371 configFile = cFile; 372 lastModified = cFile.lastModified(); 373 FileMonitor.getFileMonitor().addReloadable(srv); 374 } 375 376 382 private synchronized void checkForConfigValues() { 383 String sgroups = props.getProperty("startgroups"); 384 if (sgroups == null) 385 Server.log(this, "No starting-rooms are deffined: startrooms=[room1/TITLE1 [, room2/TITLE2, ...", MSG_ERROR, LVL_HALT); 386 387 GroupManager.mgr.updateStartingGroups(sgroups.split(",")); 388 389 Server.log (this, "updating log-destinations", MSG_CONFIG, LVL_MINOR); 390 LOGFILE[MSG_CONFIG] = checkProperty("logfileCfg", "console"); 391 LOGFILE[MSG_AUTH] = checkProperty("logfileAuth", "console"); 392 LOGFILE[MSG_STATE] = checkProperty("logfileState", "console"); 393 LOGFILE[MSG_TRAFFIC] = checkProperty("logfileTraffic", "console"); 394 LOGFILE[MSG_ERROR] = checkProperty("logfileError", "console"); 395 LOG_QUEUE_SIZE = checkProperty("logQueueSize", 500); 396 try { 397 LogWriter l = LogWriter.instance; 399 } catch (Exception e) { 401 e.printStackTrace(); 402 } 403 Server.log(this, "Reading config...", MSG_CONFIG, LVL_MINOR); 404 READBUFFER_SIZE = checkProperty("readbuffer", 640); 405 READER_MAX_IDLETIME = checkProperty("threadMaxIdletime", 30000); 406 READER_MAX_QUEUE = checkProperty("ioQueueSize", 5); 407 FLOOD_PROTECT_TOLERANC = checkProperty("floodProtectTolerance",3); 408 FLOOD_PROTECT_MILLIS = checkProperty("floodProtectMillis", 500); 409 FLOOD_BAN_DURATION = checkProperty("floodBanDuration", 30000); 410 TOOL_PROTECT_TOLERANC = checkProperty("toolProtectTolerance", 250); 411 TOOL_PROTECT_COUNTER = checkProperty("toolProtectCounter", 10); 412 TOOL_BAN_DURATION = checkProperty("toolBanDuration", 600) * 60000; 413 TOOL_PROTECT_MINMILLS = checkProperty("toolProtectMinmills", 12000); 414 TOOL_PROTECT_MINCOUNTER = checkProperty("toolProtectMincounter",10); 415 JOIN_PUNISHED_COUNTER = checkProperty("joinpunishedcounter",2); 416 COLOR_CHANGE_INTERVAL = checkProperty("colorChangeInterval", 15000); 417 USER_TIMEOUT = checkProperty("userTimeout", 15) * 60000; 418 USER_AWAY_TIMEOUT = checkProperty("userAwayTimeout", 30) * 60000; 419 USER_REMOVE_SCHEDULE_TIME = checkProperty("userRemoveDelay", 2000); 420 TCP_RECEIVE_BUFFER_WINDOW = checkProperty("tcpReceiveBuffer", 4096); 421 FILE_CHECK_INTERVAL = checkProperty("fileCheckInterval", 10000); 422 if (FILE_CHECK_INTERVAL < 1000) 423 FILE_CHECK_INTERVAL = 1000; 424 425 String ndcs = checkProperty("charset", "iso-8859-1"); 426 if (!ndcs.equals(DEFAULT_CHARSET)) { 427 defaultCs = Charset.forName(ndcs); 428 defaultCsEnc = defaultCs.newEncoder(); 429 DEFAULT_CHARSET=ndcs; 430 } 431 432 COOKIE_DOMAIN = checkProperty("cookieDomain", null); 433 SERVER_NAME = checkProperty("server", null); 434 ALLOW_EXTERNAL = checkProperty("allowExternalLogin", true); 435 USE_CENTRAL_REQUESTQUEUE = checkProperty("useCentralRequestqueue",false); 436 DEBUG_TEMPLATESET = checkProperty("debugTemplateset", false); 437 STRICT_HOST_BINDING = checkProperty("useStrictHostBinding", true); 438 MAX_READERS = checkProperty("maxThreads", 100); 439 USE_HTTP11 = checkProperty("useHTTP1.1", true); 440 MAX_USERS = checkProperty("maxUsers", 2000); 441 TOUCH_USER_DELAY = checkProperty("touchUserDelay", 20000); 442 MAX_BAN_DURATION = checkProperty("maxBanDuration", 120); 443 USE_IP_BAN = checkProperty("useIpBan", true); 444 DEFAULT_BAN_DURATION = checkProperty("defaultBanDuration", 10); 445 INITIAL_RESPONSE_QUEUE = checkProperty("responseQueueSize", 100); 446 MAX_RESPONSE_QUEUE = checkProperty("maxResponseQueueSize", 1000); 447 MAX_REQUESTS_PER_PROXY_IP = checkProperty("maxRequestsPerProxy", 20000); 448 MAX_REQUESTS_PER_IP = checkProperty("maxRequestsPerIp", 90); 449 HOST_BAN_DURATION = checkProperty("floodHostBanDuration", 3600000); 450 USE_TRAFFIC_MONITOR = checkProperty("useTrafficMonitor", false); 451 MAX_DIE_NUMBER = checkProperty("maximumDieNumber", 10); 452 MAX_DIE_EYES = checkProperty("maximumDieEyes", 20); 453 MAX_SUUSERS_PER_STARTGROUP = checkProperty("maxSuPerStartgroup", 5); 454 USE_TOKENSTORE = checkProperty("useTokenedLogin", false); 455 MD5_PASSWORDS = checkProperty("MD5EncodePasswords", false); 456 MAX_USERNAME_LENGTH = checkProperty("maxUserNameLength", 30); 457 MAX_GROUPNAME_LENGTH = checkProperty("maxGroupNameLength", -1); 458 MAX_GROUPTHEME_LENGTH = checkProperty("maxGroupThemeLength", -1); 459 USE_MESSAGE_RENDER_CACHE = checkProperty("useMessageRenderCache",false); 460 VIP_TIMEOUT = checkProperty("vipTimeout", 0) * 60000; 461 462 ADMIN_HTTP_USERNAME = checkProperty("admin.http.username", null); 463 ADMIN_HTTP_PASSWORD = checkProperty("admin.http.password", null); 464 ADMIN_HTTP_ALLOWED = checkProperty("admin.http.allowedClients", ""); 465 ADMIN_XMLRPC_PORT = checkProperty("admin.xmlrpc.port", 0); 466 ADMIN_XMLRPC_ALLOWED = checkProperty("admin.xmlrpc.allowedClients", ""); 467 468 UNAME_PREFIX_GOD = checkProperty("prefix.admin", "<b>"); 469 UNAME_SUFFIX_GOD = checkProperty("suffix.admin", "(A)</b>"); 470 UNAME_PREFIX_GUEST = checkProperty("prefix.guest", ""); 471 UNAME_SUFFIX_GUEST = checkProperty("suffix.guest", "(G)"); 472 UNAME_PREFIX_MODERATOR = checkProperty("prefix.moderator", ""); 473 UNAME_SUFFIX_MODERATOR = checkProperty("suffix.moderator", "(M)"); 474 UNAME_PREFIX_PUNISHED = checkProperty("prefix.punished", "<s>"); 475 UNAME_SUFFIX_PUNISHED = checkProperty("suffix.punished", "</s>"); 476 UNAME_PREFIX_SU = checkProperty("prefix.su", "<i>"); 477 UNAME_SUFFIX_SU = checkProperty("suffix.su", "</i>"); 478 UNAME_PREFIX_VIP = checkProperty("prefix.vip", "<b>"); 479 UNAME_SUFFIX_VIP = checkProperty("suffix.vip", "</b>"); 480 481 READER_TIMEOUT = checkProperty("readerTimeout", 5000); 482 LOGIN_TIMEOUT = checkProperty("loginTimeout", 20000); 483 484 FN_DEFAULT_MODE_FALSE = (short) 485 checkProperty("friendNotificationMode.false", 0); 486 FN_DEFAULT_MODE_TRUE = (short) 487 checkProperty("friendNotificationMode.true", 2); 488 489 KEEP_ALIVE_TIMEOUT = checkProperty("keepAliveTimeout", 30) * 1000; 490 491 TRACE_CREATE_AND_FINALIZE = checkProperty("traceCreateAndFinalize",false); 492 493 String val = props.getProperty("moderatedgroups"); 494 if (val != null) { 495 String values[] = val.split(","); 496 Vector names = new Vector (); 497 for (int i = 0; i < values.length; i++) 498 names.add(values[i].trim().toLowerCase()); 499 GroupManager.mgr.updateModeratedGroups(names); 500 } else { 501 GroupManager.mgr.updateModeratedGroups(new Vector ()); 502 } 503 504 val = props.getProperty("vips"); 505 if (val != null) { 506 Vector tvl = new Vector (); 507 String values[] = val.split(","); 508 for (int i = 0; i < values.length; i++) { 509 tvl.addElement(values[i].trim().toLowerCase()); 510 } 511 UserManager.mgr.updateVips(tvl); 512 } else 513 UserManager.mgr.updateVips(new Vector ()); 514 515 val = props.getProperty("admins"); 516 if (val != null) { 517 Vector tvl = new Vector (); 518 String values[] = val.split(","); 519 for (int i = 0; i < values.length; i++) { 520 tvl.addElement(values[i].trim().toLowerCase()); 521 } 522 UserManager.mgr.updateAdmins(tvl); 523 } else 524 UserManager.mgr.updateAdmins(new Vector ()); 525 526 val = props.getProperty("moderators"); 527 if (val != null) { 528 Vector tvl = new Vector (); 529 String values[] = val.split(","); 530 for (int i = 0; i < values.length; i++) { 531 tvl.addElement(values[i].trim().toLowerCase()); 532 } 533 UserManager.mgr.updateModerators(tvl); 534 } else 535 UserManager.mgr.updateModerators(new Vector ()); 536 537 val = props.getProperty("guests"); 538 if (val != null) { 539 Vector tvl = new Vector (); 540 String values[] = val.split(","); 541 for (int i = 0; i < values.length; i++) { 542 tvl.addElement(values[i].trim().toLowerCase()); 543 } 544 UserManager.mgr.updateGuests(tvl); 545 } else 546 UserManager.mgr.updateGuests(new Vector ()); 547 548 val = props.getProperty("admin.http.allowedClients"); 549 if (val != null) { 550 String hsts[] = val.split(","); 551 Vector newHsts = new Vector (); 552 for (int i = 0; i < hsts.length; i++) { 553 try { 554 InetAddress ia = InetAddress.getByName(hsts[i].trim()); 555 if (!newHsts.contains(ia)) 556 newHsts.addElement(ia); 557 } catch (Exception e) { 558 StringBuffer tsb = new StringBuffer ("Server.checkForConfigValues: unable to add adminHost "); 559 tsb.append(hsts[i]); 560 Server.debug(this, tsb.toString(), e, Server.MSG_ERROR, Server.LVL_MAJOR); 561 } 562 } 563 Vector remove = (Vector ) adminHosts.clone(); 564 remove.removeAll(newHsts); 565 newHsts.removeAll(adminHosts); 566 adminHosts.removeAll(remove); 567 adminHosts.addAll(newHsts); 568 } 569 570 String oldTimeZone = TIMEZONE; 571 TIMEZONE = checkProperty("timezone", null); 572 TimeZone tz = null; 573 if (TIMEZONE == null || TIMEZONE.length() < 1) { 574 StringBuffer sb = new StringBuffer ("checkForConfigValues: setting TimeZone to default-TimeZone ("); 575 tz = TimeZone.getDefault(); 576 sb.append(tz.getID()); 577 sb.append(")"); 578 Server.log(this, sb.toString(), Server.MSG_STATE, Server.LVL_MINOR); 579 if (tz.equals(cal.getTimeZone())) 580 tz = null; 581 } else if (oldTimeZone == null || !oldTimeZone.equals(TIMEZONE)) { 582 try { 583 tz = TimeZone.getTimeZone(TIMEZONE); 584 if (tz.equals(cal.getTimeZone())) { 585 Server.log(this, "checkForConfigVals: TimeZone has not changed", Server.MSG_ERROR, Server.LVL_MINOR); 586 tz = null; 587 } else if (!tz.getID().equals(TIMEZONE)) { 588 StringBuffer sb = new StringBuffer ("checkForConfigVals: TimeZone is set to "); 589 sb.append(tz.getID()); 590 sb.append(" now. The following TimeZones are available:\r\n"); 591 String [] ids = TimeZone.getAvailableIDs(); 592 for (int i = 0; i < ids.length; i++) { 593 sb.append(ids[i]); 594 if (i < ids.length) 595 sb.append(", "); 596 } 597 Server.log(this, sb.toString(), Server.MSG_STATE, Server.LVL_MINOR); 598 } 599 StringBuffer sb = new StringBuffer ("checkForConfigValues: setting TimeZone to "); 600 sb.append(tz.getID()); 601 Server.log(this, sb.toString(), Server.MSG_STATE, Server.LVL_MINOR); 602 } catch (Exception e) { 603 Server.debug(this, "checkForConfigValues: unable to set TimeZone!", e, Server.MSG_ERROR, Server.LVL_MAJOR); 604 } 605 } 606 if (tz != null) { 607 cal.setTimeZone(tz); 608 } 609 610 Listener.updateSscRecieveBuffer(this.TCP_RECEIVE_BUFFER_WINDOW); 611 612 val = checkProperty("allowedLoginHosts", null); 613 if (val != null) { 614 String hsts[] = val.split(","); 615 Vector newHsts = new Vector (); 616 for (int i = 0; i < hsts.length; i++) { 617 try { 618 InetAddress ia = InetAddress.getByName(hsts[i].trim()); 619 if (!newHsts.contains(ia)) 620 newHsts.addElement(ia); 621 } catch (Exception e) { 622 StringBuffer tsb = new StringBuffer ("Server.checkForConfigValues: unable to add adminHost "); 623 tsb.append(hsts[i]); 624 Server.debug(this, tsb.toString(), e, Server.MSG_ERROR, Server.LVL_MAJOR); 625 } 626 } 627 Vector remove = (Vector ) allowedLoginHosts.clone(); 628 remove.removeAll(newHsts); 629 newHsts.removeAll(allowedLoginHosts); 630 allowedLoginHosts.removeAll(remove); 631 allowedLoginHosts.addAll(newHsts); 632 } 633 634 String logVal = props.getProperty("debug"); 636 if (logVal != null && logVal.equalsIgnoreCase("false")) 637 DEBUG = false; 638 else if (logVal != null && logVal.equalsIgnoreCase("true")) 639 DEBUG = true; 640 641 logVal = props.getProperty("log_config"); 642 if (logVal != null) 643 LOG_MASK[MSG_CONFIG] = new Short (Short.parseShort(logVal, 10)); 644 logVal = props.getProperty("log_auth"); 645 if (logVal != null) 646 LOG_MASK[MSG_AUTH] = new Short (Short.parseShort(logVal, 10)); 647 logVal = props.getProperty("log_state"); 648 if (logVal != null) 649 LOG_MASK[MSG_STATE] = new Short (Short.parseShort(logVal, 10)); 650 logVal = props.getProperty("log_traffic"); 651 if (logVal != null) 652 LOG_MASK[MSG_TRAFFIC] = new Short (Short.parseShort(logVal, 10)); 653 logVal = props.getProperty("log_error"); 654 if (logVal != null) 655 LOG_MASK[MSG_ERROR] = new Short (Short.parseShort(logVal, 10)); 656 } 657 658 664 private boolean checkProperty (String p, boolean def) { 665 String pval = props.getProperty (p); 666 if (pval == null) return def; 667 return pval.equalsIgnoreCase("true"); 668 } 669 670 676 private long checkProperty (String p, long def) { 677 String pval = props.getProperty (p); 678 if (pval == null) return def; 679 try { 680 return Long.parseLong (pval, 10); 681 } catch (Exception e) { 682 Server.debug("Server", "invalid value specified for configuration-parameter " + pval, e , Server.MSG_ERROR, Server.LVL_MAJOR); 683 return def; 684 } 685 } 686 687 693 private int checkProperty (String p, int def) { 694 String pval = props.getProperty (p); 695 if (pval == null) return def; 696 try { 697 return Integer.parseInt (pval, 10); 698 } catch (Exception e) { 699 Server.debug("Server", "invalid value specified for configuration-parameter " + pval, e , Server.MSG_ERROR, Server.LVL_MAJOR); 700 return def; 701 } 702 } 703 704 710 private String checkProperty (String p, String def) { 711 String pval = props.getProperty (p); 712 if (pval == null) return def; 713 return pval; 714 } 715 716 public void initServer() { 717 try { 718 if (templatemanager == null) 719 templatemanager = new TemplateManager(); 720 } catch (IOException ioe) { 721 Server.debug(this, "unable to load TemplateSet: ", ioe, MSG_ERROR, LVL_HALT); 722 } 723 auth = AuthManager.instance; 724 auth.init(); 725 726 Runtime rt = Runtime.getRuntime(); 727 rt.addShutdownHook(new CleanupClass()); 729 } 730 731 public void removeToken (String cookie) { 732 if (cookie == null) 733 return; 734 tokenStore.remove(cookie); 735 } 736 737 public boolean isTokenValid (String token, String cookie) { 738 if (!USE_TOKENSTORE) 739 return true; 740 if (token == null || cookie == null) 741 return false; 742 String t = (String ) tokenStore.get(cookie); 743 if (t==null || !t.equals(token)) 744 return false; 745 return true; 746 } 747 748 public void addToken (String token, String cookie) { 749 if (!USE_TOKENSTORE || token==null || cookie==null) 750 return; 751 tokenStore.put(cookie, token); 752 } 753 754 755 758 public void startShutdown() { 759 isRunning = false; 760 } 761 public boolean isRunning() { 762 return isRunning; 763 } 764 765 public boolean isAdminHost(InetAddress ia) { 766 return adminHosts.contains(ia); 767 } 768 769 public InetAddress getLocalHost() { 770 return lh; 771 } 772 773 public String getProperty(String key) { 774 return props.getProperty(key); 775 } 776 777 781 public String getUrl() { 782 StringBuffer sb = new StringBuffer (SERVER_NAME == null ? lh.getCanonicalHostName() : SERVER_NAME); 783 String port = props.getProperty("mappedPort"); 784 if (port==null) 785 port = props.getProperty("port"); 786 if (!"80".equals(port)) { 787 sb.append(":"); 788 sb.append(port); 789 } 790 return (sb.toString()); 791 } 792 793 797 public static String getVersion() { 798 return VERSION; 799 } 800 803 810 public void banUser (User u, String msgTemplate, String message, long millis, String bannedBy) { 811 if (u==null) 812 return; 813 MessageParser mp = new MessageParser (); 814 mp.setSender (u); 815 mp.setUsercontext(u); 816 Group g = u.getGroup (); 817 if (g != null) { 818 mp.setMessageTemplate (msgTemplate); 819 g.removeUser (u); 820 g.sendMessage(mp); 821 } 822 banUser (u, message, millis, bannedBy); 823 } 824 825 832 public void banUser (Vector v, String message, long millis, String bannedBy) { 833 for (Enumeration e = v.elements(); e.hasMoreElements(); ) { 834 User u = (User) e.nextElement(); 835 this.banUser (u, message, millis, bannedBy); 836 } 837 } 838 839 public void banUser (User u, String message, long millis, String bannedBy) { 840 if (u==null) 841 return; 842 StringBuffer sb = new StringBuffer ("banUser: User="); 843 sb.append (u.getName ()); 844 sb.append (" BannedBy="); 845 sb.append (bannedBy); 846 sb.append (" Cookie="); 847 sb.append (u.getCookie()); 848 if (u.conn == null) { 849 sb.append (" Connection-Object was null"); 850 } else if (u.conn.clientIp != null) { 851 sb.append(" +IP="); 852 sb.append(u.conn.clientIp); 853 } else { 854 sb.append(" Came over Proxy (Proxy: "); 855 sb.append(u.conn.peerIp); 856 sb.append(", ForwardChain: "); 857 sb.append(u.conn.fwChain); 858 } 859 sb.append (" Duration="); 860 sb.append (millis/1000); 861 sb.append ("secs Message="); 862 sb.append (message); 863 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR); 864 BanObject bo = new BanObject (message, bannedBy, System.currentTimeMillis () + millis); 865 bo.cookie = u.getCookie(); 866 bo.usr = u.getName().toLowerCase().trim(); 867 bo.email = (String ) u.getProperty("email"); 868 if (bo.email != null) { 869 bo.email = bo.email.trim().toLowerCase(); 870 banList.put (bo.email, bo); 871 } 872 banList.put (bo.usr, bo); 873 banList.put (bo.cookie, bo); 874 if (USE_IP_BAN && u.conn != null && u.conn.isBanable()) { 875 bo.con=u.conn; 876 banList.put (bo.con.getBanKey(), bo); 877 } 878 u.sendQuitMessage(true); 879 } 880 881 public boolean removeBan (String key) { 882 BanObject bo = (BanObject) banList.get(key); 883 if (bo == null) 884 return false; 885 if (bo.hostban!=null) { 886 banList.remove(bo.hostban); 887 } else { 888 if (bo.usr!=null) 889 banList.remove(bo.usr); 890 if (bo.cookie!=null) 891 banList.remove(bo.cookie); 892 if (bo.con!=null) 893 banList.remove(bo.con.getBanKey()); 894 if (bo.email!=null) 895 banList.remove(bo.email); 896 } 897 return true; 898 } 899 900 public BanObject[] getBanList() { 901 if (banList.size() < 0) { 902 return new BanObject[0]; 903 } 904 Vector v = new Vector (); 905 for (Enumeration e = banList.elements(); e.hasMoreElements(); ) { 906 Object o = e.nextElement(); 907 if (v.contains(o)) 908 continue; 909 v.add(o); 910 } 911 return (BanObject[]) v.toArray(new BanObject[0]); 912 } 913 914 public void banHost (InetAddress ia, long millis, String msg) { 915 BanObject bo = new BanObject (msg, "Server", millis); 916 bo.hostban = ia.getHostAddress(); 917 banList.put (bo.hostban, bo); 918 } 919 920 925 public boolean isBanned (Object o) { 926 if (o == null) 928 return false; 929 930 BanObject b; 932 if (o instanceof String ) { 933 String s = ((String ) o).toLowerCase(); 934 b = (BanObject) banList.get (s); 935 } else if (o instanceof Connection) { 936 Connection conn = (Connection) o; 937 if (!conn.isBanable()) 938 return false; 939 b = (BanObject) banList.get(conn.getBanKey()); 940 } else if (o instanceof InetAddress ) { 941 InetAddress ia = (InetAddress ) o; 942 b = (BanObject) banList.get(ia.getHostAddress()); 943 } else { 944 b = (BanObject) banList.get (o); 945 } 946 947 if (b == null) 949 return false; 950 951 if (b.time < System.currentTimeMillis ()) { 953 banList.remove (o); 954 return false; 955 } 956 return true; 957 } 958 959 962 public static String [] LOGFILE = {"console", "console", "console", 963 "console", "console" }; 964 965 public static final short MSG_CONFIG = 0; 966 public static final short MSG_AUTH = 1; 967 public static final short MSG_STATE = 2; 968 public static final short MSG_TRAFFIC = 3; 969 public static final short MSG_ERROR = 4; 970 971 public static final short LVL_HALT = 0; 972 public static final short LVL_MAJOR = 1; 973 public static final short LVL_MINOR = 2; 974 public static final short LVL_VERBOSE = 3; 975 public static final short LVL_VERY_VERBOSE = 4; 976 977 public static boolean DEBUG = false; 978 public static Short LOG_MASK[] = new Short [5]; 979 980 984 public static boolean checkLogLvl (short type, short lvl) { 985 return (LOG_MASK[type].intValue () >= lvl || DEBUG); 986 } 987 988 994 public static void log (Object o, String msg, short type, short lvl) { 995 StringBuffer sb = new StringBuffer (); 996 try { 997 if (LOG_MASK[type].intValue () < lvl && !DEBUG) return; 998 sb.append ("["); 999 sb.append (Server.formatDefaultTimeStamp (System.currentTimeMillis ())); 1000 switch (lvl) { 1001 case LVL_MAJOR: 1002 sb.append ("] MAJOR-| "); 1003 break; 1004 case LVL_HALT: 1005 sb.append ("] HALT -| "); 1006 break; 1007 default: 1008 sb.append ("] -| "); 1009 } 1010 if (o != null) { 1011 sb.append (o.toString()); 1012 sb.append (": "); 1013 } 1014 sb.append (msg); 1015 sb.append ("\r\n"); 1016 if ((type == MSG_CONFIG && LOGFILE[MSG_CONFIG].equals("console")) 1017 || (type == MSG_AUTH && LOGFILE[MSG_AUTH].equals("console")) 1018 || (type == MSG_STATE && LOGFILE[MSG_STATE].equals("console")) 1019 || (type == MSG_TRAFFIC && LOGFILE[MSG_TRAFFIC].equals("console")) 1020 || (type == MSG_ERROR && LOGFILE[MSG_ERROR].equals("console"))) { 1021 System.out.print (sb.toString ()); 1022 } else { 1023 LogWriter.instance.addLogMessage (type, sb.toString()); 1024 } 1025 if (lvl == LVL_HALT) 1026 System.exit (1); 1027 } catch (Exception e) { 1028 System.err.println("Server.log caused Exception for Message:"); 1029 System.err.print(sb.toString()); 1030 e.printStackTrace(); 1031 } 1032 } 1033 1034 1041 public static void debug (Object o, String prefix, Throwable t, short type, short lvl) { 1042 if (LOG_MASK[type].intValue () < lvl && !DEBUG) return; 1043 StringBuffer sb = new StringBuffer (); 1044 sb.append (prefix); 1045 sb.append ("\r\n"); 1046 sb.append (t.toString ()); 1047 StackTraceElement ste[] = t.getStackTrace (); 1048 for (int i = 0; i < ste.length; i++) { 1049 sb.append ("\r\n at "); 1050 sb.append (ste[i].getClassName ()); 1051 sb.append ("("); 1052 sb.append (ste[i].getFileName ()); 1053 sb.append (":"); 1054 sb.append (ste[i].getLineNumber ()); 1055 sb.append (")"); 1056 } 1057 log (o, sb.toString (), type, lvl); 1058 } 1059 1060 1061 1064 private long lastModified; 1065 private File configFile; 1066 1067 public long lastModified () { 1068 return lastModified; 1069 } 1070 1071 public void changed () { 1072 try { 1073 FileInputStream fis = new FileInputStream (configFile); 1074 Properties tprop = new Properties (); 1075 tprop.load (fis); 1076 fis.close (); 1077 props = tprop; 1078 checkForConfigValues (); 1079 lastModified = configFile.lastModified (); 1080 Server.log (this, "reload: reloaded configfile", Server.MSG_STATE, Server.LVL_MINOR); 1081 } catch (Exception e) { 1082 Server.debug (this, "reload: ", e, Server.MSG_ERROR, Server.LVL_MAJOR); 1083 } 1084 } 1085 1086 public void removed () { 1087 Server.log (this, "CRITICAL-WARNING: Config file has been removed!\r\nThe Serverconfiguration of the last configuration-file present will stay in charge, but the server won't start if no config is present!", Server.MSG_ERROR, Server.LVL_MAJOR); 1088 } 1089 public File getFile () { 1090 return configFile; 1091 } 1092 public boolean filePresent() { 1093 return true; } 1095 public void created() { 1096 changed(); 1097 } 1098 public String getFormatedTime (String pattern) { 1099 return formatTimeStamp (System.currentTimeMillis(), pattern); 1100 } 1101 1102 public static SimpleDateFormat defaultDateFormat = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss"); 1103 public static SimpleDateFormat hourSDF = new SimpleDateFormat ("HH"); 1104 public static SimpleDateFormat minuteSDF = new SimpleDateFormat ("mm"); 1105 1106 public static String formatDefaultTimeStamp (long ts) { 1107 cal.setTimeInMillis(ts); 1108 return defaultDateFormat.format (cal.getTime()); 1109 } 1110 public String formatTimeStamp (long ts, String pattern) { 1111 SimpleDateFormat sdf = new SimpleDateFormat (pattern); 1112 cal.setTimeInMillis (ts); 1113 return sdf.format (cal.getTime ()); 1114 } 1115 1116 public static String formatTimeStamp (long ts, SimpleDateFormat sdf) { 1117 cal.setTimeInMillis (ts); 1118 return sdf.format (cal.getTime ()); 1119 } 1120 1121 1125 public File getConfigDir() { 1126 return (configFile != null) ? configFile.getParentFile() : null; 1127 } 1128 1129 public String toString () { 1130 return ("[Server]"); 1131 } 1132} 1133 1134 | Popular Tags |