1 18 package net.sf.drftpd.master.config; 19 20 import java.io.FileInputStream ; 21 import java.io.FileNotFoundException ; 22 import java.io.FileReader ; 23 import java.io.IOException ; 24 import java.io.LineNumberReader ; 25 import java.net.InetAddress ; 26 import java.net.UnknownHostException ; 27 import java.util.ArrayList ; 28 import java.util.Collection ; 29 import java.util.Enumeration ; 30 import java.util.Hashtable ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Properties ; 34 import java.util.StringTokenizer ; 35 36 import net.sf.drftpd.master.ConnectionManager; 37 import net.sf.drftpd.master.FtpReply; 38 import net.sf.drftpd.master.SlaveManagerImpl; 39 import net.sf.drftpd.master.usermanager.User; 40 import net.sf.drftpd.remotefile.LinkedRemoteFileInterface; 41 import net.sf.drftpd.slave.SlaveImpl; 42 43 import org.apache.log4j.Logger; 44 import org.apache.oro.text.GlobCompiler; 45 import org.apache.oro.text.regex.MalformedPatternException; 46 47 51 public class FtpConfig { 52 private static final Logger logger = Logger.getLogger(FtpConfig.class); 53 54 public static String getProperty(Properties p, String name) 55 throws NullPointerException { 56 String result = p.getProperty(name); 57 if (result == null) 58 throw new NullPointerException ("Error getting setting " + name); 59 return result; 60 } 61 private static ArrayList makeRatioPermission( 62 ArrayList arr, 63 StringTokenizer st) 64 throws MalformedPatternException { 65 arr.add( 66 new RatioPathPermission( 67 new GlobCompiler().compile(st.nextToken()), 68 Float.parseFloat(st.nextToken()), 69 makeUsers(st))); 70 return arr; 71 } 72 73 public static ArrayList makeUsers(Enumeration st) { 74 ArrayList users = new ArrayList (); 75 while (st.hasMoreElements()) { 76 users.add(st.nextElement()); 77 } 78 return users; 79 } 80 private ArrayList _bouncerIps; 81 private boolean _capFirstDir; 82 private boolean _capFirstFile; 83 84 String _cfgFileName; 85 private ConnectionManager _connManager; 86 private ArrayList _creditcheck; 87 private ArrayList _creditloss; 88 private boolean _isLowerDir; 89 private boolean _isLowerFile; 90 private String _loginPrompt = SlaveImpl.VERSION + " http://drftpd.org"; 91 private int _maxUsersExempt; 92 private int _maxUsersTotal = Integer.MAX_VALUE; 93 private ArrayList _msgpath; 94 private Hashtable _patternPaths; 95 private Hashtable _permissions; 96 private StringTokenizer _replaceDir; 97 private StringTokenizer _replaceFile; 98 private long _slaveStatusUpdateTime; 99 private boolean _useDirNames; 100 private boolean _useFileNames; 101 102 private String newConf = "conf/perms.conf"; 103 104 private String _serverName; 105 private int _socketPort; 106 107 110 public FtpConfig( 111 Properties cfg, 112 String cfgFileName, 113 ConnectionManager connManager) 114 throws IOException { 115 _cfgFileName = cfgFileName; 116 loadConfig(cfg, connManager); 117 } 118 119 protected FtpConfig() { 120 } 121 122 public boolean checkDelete(User fromUser, LinkedRemoteFileInterface path) { 123 return checkPathPermission("delete", fromUser, path); 124 } 125 126 public boolean checkDeleteOwn( 127 User fromUser, 128 LinkedRemoteFileInterface path) { 129 return checkPathPermission("deleteown", fromUser, path); 130 } 131 132 public boolean checkGive(User user) { 133 return checkPermission("give", user); 134 } 135 136 public boolean checkTake(User user) { 137 return checkPermission("take", user); 138 } 139 140 public boolean checkDenyDataUnencrypted(User user) { 141 return checkPermission("denydatauncrypted", user); 142 } 143 144 public boolean checkDenyDirUnencrypted(User user) { 145 return checkPermission("denydiruncrypted", user); 146 } 147 148 154 public boolean checkDirLog(User fromUser, LinkedRemoteFileInterface path) { 155 return checkPathPermission("dirlog", fromUser, path); 156 } 157 158 162 public boolean checkDownload( 163 User fromUser, 164 LinkedRemoteFileInterface path) { 165 return checkPathPermission("download", fromUser, path); 166 } 167 168 171 public boolean checkHideInWho( 172 User fromUser, 173 LinkedRemoteFileInterface path) { 174 return checkPathPermission("hideinwho", fromUser, path); 175 } 176 177 180 public boolean checkMakeDir( 181 User fromUser, 182 LinkedRemoteFileInterface path) { 183 return checkPathPermission("makedir", fromUser, path); 184 } 185 186 public boolean checkPathPermission( 187 String key, 188 User fromUser, 189 LinkedRemoteFileInterface path) { 190 return checkPathPermission(key, fromUser, path, false); 191 } 192 193 private boolean checkPathPermission( 194 String key, 195 User fromUser, 196 LinkedRemoteFileInterface path, 197 boolean defaults) { 198 Collection coll = ((Collection ) _patternPaths.get(key)); 199 if (coll == null) 200 return defaults; 201 Iterator iter = coll.iterator(); 202 while (iter.hasNext()) { 203 PathPermission perm = (PathPermission) iter.next(); 204 if (perm.checkPath(path)) { 205 return perm.check(fromUser); 206 } 207 } 208 return defaults; 209 } 210 211 private boolean checkPermission(String key, User user) { 212 Permission perm = (Permission) _permissions.get(key); 213 if (perm == null) 214 return false; 215 return perm.check(user); 216 } 217 218 221 public boolean checkPrivPath( 222 User fromUser, 223 LinkedRemoteFileInterface path) { 224 return checkPathPermission("privpath", fromUser, path, true); 225 } 226 227 public boolean checkRename(User fromUser, LinkedRemoteFileInterface path) { 228 return checkPathPermission("rename", fromUser, path); 229 } 230 231 public boolean checkRenameOwn( 232 User fromUser, 233 LinkedRemoteFileInterface path) { 234 return checkPathPermission("renameown", fromUser, path); 235 } 236 237 240 public boolean checkUpload(User fromUser, LinkedRemoteFileInterface path) { 241 return checkPathPermission("upload", fromUser, path); 242 } 243 244 public boolean checkUserRejectInsecure(User user) { 245 return checkPermission("userrejectinsecure", user); 246 } 247 248 public boolean checkUserRejectSecure(User user) { 249 return checkPermission("userrejectsecure", user); 250 } 251 252 public void directoryMessage( 253 FtpReply response, 254 User user, 255 LinkedRemoteFileInterface dir) { 256 257 for (Iterator iter = _msgpath.iterator(); iter.hasNext();) { 258 MessagePathPermission perm = (MessagePathPermission) iter.next(); 259 if (perm.checkPath(dir)) { 260 if (perm.check(user)) { 261 perm.printMessage(response); 262 } 263 } 264 } 265 } 266 269 public List getBouncerIps() { 270 return _bouncerIps; 271 } 272 273 public float getCreditCheckRatio( 274 LinkedRemoteFileInterface path, 275 User fromUser) { 276 for (Iterator iter = _creditcheck.iterator(); iter.hasNext();) { 277 RatioPathPermission perm = (RatioPathPermission) iter.next(); 278 if (perm.checkPath(path)) { 279 if (perm.check(fromUser)) { 280 return perm.getRatio(); 281 } else { 282 return fromUser.getRatio(); 283 } 284 } 285 } 286 return fromUser.getRatio(); 287 } 288 289 public float getCreditLossRatio( 290 LinkedRemoteFileInterface path, 291 User fromUser) { 292 for (Iterator iter = _creditloss.iterator(); iter.hasNext();) { 293 RatioPathPermission perm = (RatioPathPermission) iter.next(); 294 295 if (perm.checkPath(path)) { 296 if (perm.check(fromUser)) { 297 return perm.getRatio(); 298 } 299 } 300 } 301 return fromUser.getRatio() == 0 ? 0 : 1; 303 } 304 305 public String getDirName(String name) { 306 if (!_useDirNames) 307 return name; 308 String temp = new String (name); 309 if (_isLowerDir) 310 temp = temp.toLowerCase(); 311 else 312 temp = temp.toUpperCase(); 313 if (_capFirstDir) 314 temp = 315 temp.substring(0, 1).toUpperCase() 316 + temp.substring(1, temp.length()); 317 return replaceName(temp, _replaceDir); 318 } 319 320 public String getFileName(String name) { 321 if (!_useFileNames) 322 return name; 323 String temp = new String (name); 324 if (_isLowerFile) 325 temp = temp.toLowerCase(); 326 else 327 temp = temp.toUpperCase(); 328 if (_capFirstFile) 329 temp = 330 temp.substring(0, 1).toUpperCase() 331 + temp.substring(1, temp.length()); 332 return replaceName(temp, _replaceFile); 333 } 334 335 public String getLoginPrompt() { 336 return _loginPrompt; 337 } 338 public int getMaxUsersExempt() { 339 return _maxUsersExempt; 340 } 341 342 public int getMaxUsersTotal() { 343 return _maxUsersTotal; 344 } 345 346 public SlaveManagerImpl getSlaveManager() { 347 return _connManager.getSlaveManager(); 348 } 349 350 public long getSlaveStatusUpdateTime() { 351 return _slaveStatusUpdateTime; 352 } 353 354 public void loadConfig(Properties cfg, ConnectionManager connManager) 355 throws IOException { 356 loadConfig2(); 357 _connManager = connManager; 358 loadConfig1(cfg); 359 } 360 361 protected void loadConfig1(Properties cfg) throws UnknownHostException { 362 _slaveStatusUpdateTime = 363 Long.parseLong(cfg.getProperty("slaveStatusUpdateTime", "3000")); 364 _serverName = cfg.getProperty("master.bindname", "slavemaster"); 365 _socketPort = 366 Integer.parseInt(cfg.getProperty("master.socketport", "1100")); 367 368 StringTokenizer st = 369 new StringTokenizer (cfg.getProperty("bouncer_ip",""), " "); 370 371 ArrayList bouncerIps = new ArrayList (); 372 while (st.hasMoreTokens()) { 373 bouncerIps.add(InetAddress.getByName(st.nextToken())); 374 } 376 _bouncerIps = bouncerIps; 377 } 378 379 private void loadConfig2() throws IOException { 380 Hashtable patternPathPermissions = new Hashtable (); 381 Hashtable permissions = new Hashtable (); 382 ArrayList creditcheck = new ArrayList (); 383 ArrayList creditloss = new ArrayList (); 384 ArrayList msgpath = new ArrayList (); 385 _useFileNames = false; 386 _replaceFile = null; 387 _useDirNames = false; 388 _replaceDir = null; 389 390 LineNumberReader in = new LineNumberReader (new FileReader (newConf)); 391 try { 392 String line; 393 while ((line = in.readLine()) != null) { 394 StringTokenizer st = new StringTokenizer (line); 395 if (!st.hasMoreTokens()) 396 continue; 397 String cmd = st.nextToken(); 398 399 try { 400 if (cmd.equals("login_prompt")) { 402 _loginPrompt = line.substring(13); 403 } 404 else if (cmd.equals("max_users")) { 406 _maxUsersTotal = Integer.parseInt(st.nextToken()); 407 _maxUsersExempt = Integer.parseInt(st.nextToken()); 408 } else if (cmd.equals("dir_names")) { 409 _useDirNames = true; 410 _capFirstDir = st.nextToken().equals("true"); 411 _isLowerDir = st.nextToken().equals("lower"); 412 _replaceDir = st; 413 } else if (cmd.equals("file_names")) { 414 _useFileNames = true; 415 _capFirstFile = st.nextToken().equals("true"); 416 _isLowerFile = st.nextToken().equals("lower"); 417 _replaceFile = st; 418 } 419 420 else if (cmd.equals("msgpath")) { 422 String path = st.nextToken(); 423 String messageFile = st.nextToken(); 424 msgpath.add( 425 new MessagePathPermission( 426 path, 427 messageFile, 428 makeUsers(st))); 429 } 430 else if (cmd.equals("creditloss")) { 432 makeRatioPermission(creditloss, st); 433 } 434 else if (cmd.equals("creditcheck")) { 436 makeRatioPermission(creditcheck, st); 437 } else if (cmd.equals("pathperm")) { 438 makePatternPathPermission( 439 patternPathPermissions, 440 st.nextToken(), 441 st); 442 } else if ( 446 cmd.equals("privpath") 447 || cmd.equals("dirlog") 448 || cmd.equals("hideinwho") 449 || cmd.equals("makedir") 450 || cmd.equals("pre") 451 || cmd.equals("upload") 452 || cmd.equals("download") 453 || cmd.equals("delete") 454 || cmd.equals("deleteown") 455 || cmd.equals("rename") 456 || cmd.equals("renameown") 457 || cmd.equals("request")) { 458 makePatternPathPermission( 459 patternPathPermissions, 460 cmd, 461 st); 462 } else if ( 466 "userrejectsecure".equals(cmd) 467 || "userrejectinsecure".equals(cmd) 468 || "denydiruncrypted".equals(cmd) 469 || "denydatauncrypted".equals(cmd) 470 || "give".equals(cmd) 471 || "take".equals(cmd)) { 472 if (permissions.containsKey(cmd)) 473 throw new RuntimeException ( 474 "Duplicate key in perms.conf: " 475 + cmd 476 + " line: " 477 + in.getLineNumber()); 478 permissions.put(cmd, new Permission(makeUsers(st))); 479 } 480 } catch (Exception e) { 481 logger.warn( 482 "Exception when reading " 483 + newConf 484 + " line " 485 + in.getLineNumber(), 486 e); 487 } 488 } 489 490 creditcheck.trimToSize(); 491 _creditcheck = creditcheck; 492 493 creditloss.trimToSize(); 494 _creditloss = creditloss; 495 496 msgpath.trimToSize(); 497 _msgpath = msgpath; 498 499 _patternPaths = patternPathPermissions; 500 _permissions = permissions; 501 } finally { 502 in.close(); 503 } 504 } 505 506 private void makePatternPathPermission( 507 Hashtable patternPathPermission, 508 String key, 509 StringTokenizer st) 510 throws MalformedPatternException { 511 ArrayList perms = (ArrayList ) patternPathPermission.get(key); 512 if (perms == null) { 513 perms = new ArrayList (); 514 patternPathPermission.put(key, perms); 515 } 516 perms.add( 517 new PatternPathPermission( 518 new GlobCompiler().compile(st.nextToken()), 519 makeUsers(st))); 520 } 521 522 527 public void reloadConfig() throws FileNotFoundException , IOException { 528 Properties cfg = new Properties (); 529 cfg.load(new FileInputStream (_cfgFileName)); 530 loadConfig(cfg, _connManager); 531 } 532 533 private void replaceChars( 534 StringBuffer source, 535 Character oldChar, 536 Character newChar) { 537 if (newChar == null) { 538 int x = 0; 539 while (x < source.length()) { 540 if (source.charAt(x) == oldChar.charValue()) { 541 source.deleteCharAt(x); 542 } else 543 x++; 544 } 545 } else { 546 int x = 0; 547 while (x < source.length()) { 548 if (source.charAt(x) == oldChar.charValue()) 549 source.setCharAt(x, newChar.charValue()); 550 x++; 551 } 552 } 553 } 554 555 private String replaceName(String source, StringTokenizer st) { 556 StringBuffer sb = new StringBuffer (source); 557 Character oldChar = null; 558 Character newChar = null; 559 while (true) { 560 if (!st.hasMoreTokens()) 561 return sb.toString(); 562 String nextToken = st.nextToken(); 563 if (nextToken.length() == 1) { 564 oldChar = new Character (nextToken.charAt(0)); 565 newChar = null; 566 } else { 567 oldChar = new Character (nextToken.charAt(0)); 568 newChar = new Character (nextToken.charAt(1)); 569 } 570 replaceChars(sb, oldChar, newChar); 571 } 572 } 573 } 574 | Popular Tags |