1 18 19 package org.osgi.framework; 20 21 import java.io.IOException ; 22 import java.security.*; 23 import java.util.*; 24 import org.eclipse.osgi.framework.internal.core.AbstractBundle; 25 import org.eclipse.osgi.framework.internal.core.FilterImpl; 26 27 79 80 public final class AdminPermission extends BasicPermission { 81 static final long serialVersionUID = 207051004521261705L; 82 83 87 public final static String CLASS = "class"; 88 92 public final static String EXECUTE = "execute"; 93 98 public final static String EXTENSIONLIFECYCLE = "extensionLifecycle"; 99 103 public final static String LIFECYCLE = "lifecycle"; 104 108 public final static String LISTENER = "listener"; 109 113 public final static String METADATA = "metadata"; 114 118 public final static String RESOLVE = "resolve"; 119 123 public final static String RESOURCE = "resource"; 124 128 public final static String STARTLEVEL = "startlevel"; 129 130 134 public final static String CONTEXT = "context"; 135 136 private final static int ACTION_CLASS = 0x00000001; 137 private final static int ACTION_EXECUTE = 0x00000002; 138 private final static int ACTION_LIFECYCLE = 0x00000004; 139 private final static int ACTION_LISTENER = 0x00000008; 140 private final static int ACTION_METADATA = 0x00000010; 141 private final static int ACTION_RESOLVE = 0x00000040; 142 private final static int ACTION_RESOURCE = 0x00000080; 143 private final static int ACTION_STARTLEVEL = 0x00000100; 144 private final static int ACTION_EXTENSIONLIFECYCLE = 0x00000200; 145 private final static int ACTION_CONTEXT = 0x00000400; 146 private final static int ACTION_ALL = 147 ACTION_CLASS | 148 ACTION_EXECUTE | 149 ACTION_LIFECYCLE | 150 ACTION_LISTENER | 151 ACTION_METADATA | 152 ACTION_RESOLVE | 153 ACTION_RESOURCE | 154 ACTION_STARTLEVEL | 155 ACTION_EXTENSIONLIFECYCLE | 156 ACTION_CONTEXT; 157 private final static int ACTION_NONE = 0; 158 159 163 private boolean wildcard; 164 165 170 private String filter; 171 172 177 private String actions = null; 178 179 182 private transient int action_mask = ACTION_NONE; 183 184 188 private transient Bundle bundle; 189 190 195 private transient Dictionary bundleProperties; 196 197 202 private transient Filter filterImpl; 203 204 208 public AdminPermission() { 209 this("*",AdminPermission.ACTION_ALL); } 211 212 242 public AdminPermission(String filter, String actions) { 243 this( 246 (filter == null ? "*" : filter), getMask((actions == null ? "*" : actions)) ); 249 } 250 251 263 public AdminPermission(Bundle bundle, String actions) { 264 super(createName(bundle)); 265 this.bundle = bundle; 266 this.wildcard = false; 267 this.filter = null; 268 this.action_mask = getMask(actions); 269 } 270 271 277 private static String createName(Bundle bundle) { 278 StringBuffer sb = new StringBuffer (); 279 sb.append("(id="); 280 sb.append(bundle.getBundleId()); 281 sb.append(")"); 282 return sb.toString(); 283 } 284 285 292 public boolean equals(Object obj) { 293 if (obj == this) { 294 return true; 295 } 296 297 if (!(obj instanceof AdminPermission)) { 298 return false; 299 } 300 301 AdminPermission a = (AdminPermission) obj; 302 303 return (action_mask == a.action_mask) && 304 (wildcard == a.wildcard) && 305 (bundle == null ? a.bundle == null : (a.bundle == null ? false : bundle.getBundleId() == a.bundle.getBundleId())) && 306 (filter == null ? a.filter == null : filter.equals(a.filter)); 307 } 308 309 314 public int hashCode() { 315 return getName().hashCode() ^ getActions().hashCode(); 316 } 317 318 332 public String getActions() { 333 if (actions == null) { 334 StringBuffer sb = new StringBuffer (); 335 336 if ((action_mask & ACTION_CLASS) == ACTION_CLASS) { 337 sb.append(CLASS); 338 sb.append(','); 339 } 340 341 if ((action_mask & ACTION_EXECUTE) == ACTION_EXECUTE) { 342 sb.append(EXECUTE); 343 sb.append(','); 344 } 345 346 if ((action_mask & ACTION_EXTENSIONLIFECYCLE) == ACTION_EXTENSIONLIFECYCLE) { 347 sb.append(EXTENSIONLIFECYCLE); 348 sb.append(','); 349 } 350 351 if ((action_mask & ACTION_LIFECYCLE) == ACTION_LIFECYCLE) { 352 sb.append(LIFECYCLE); 353 sb.append(','); 354 } 355 356 if ((action_mask & ACTION_LISTENER) == ACTION_LISTENER) { 357 sb.append(LISTENER); 358 sb.append(','); 359 } 360 361 if ((action_mask & ACTION_METADATA) == ACTION_METADATA) { 362 sb.append(METADATA); 363 sb.append(','); 364 } 365 366 if ((action_mask & ACTION_RESOLVE) == ACTION_RESOLVE) { 367 sb.append(RESOLVE); 368 sb.append(','); 369 } 370 371 if ((action_mask & ACTION_RESOURCE) == ACTION_RESOURCE) { 372 sb.append(RESOURCE); 373 sb.append(','); 374 } 375 376 if ((action_mask & ACTION_STARTLEVEL) == ACTION_STARTLEVEL) { 377 sb.append(STARTLEVEL); 378 sb.append(','); 379 } 380 381 if ((action_mask & ACTION_CONTEXT) == ACTION_CONTEXT) { 382 sb.append(CONTEXT); 383 sb.append(','); 384 } 385 386 if (sb.length() > 0) { 388 sb.setLength(sb.length()-1); 389 } 390 391 actions = sb.toString(); 392 } 393 return actions; 394 } 395 396 425 public boolean implies(Permission p) { 426 if (!(p instanceof AdminPermission)) 427 return false; 428 AdminPermission target = (AdminPermission)p; 429 if ((action_mask & target.action_mask)!=target.action_mask) 431 return false; 432 if (target.filter != null) 434 throw new RuntimeException ("Cannot imply a filter"); if (target.wildcard) 437 return wildcard; 438 439 if (filter != null) { 441 Filter filterImpl = getFilterImpl(); 443 return filterImpl != null && filterImpl.match(target.getProperties()); 444 } else if (wildcard) { 445 return true; 447 } else { 448 return bundle.equals(target.bundle); 450 } 451 } 452 453 459 public PermissionCollection newPermissionCollection() { 460 return(new AdminPermissionCollection()); 461 } 462 463 469 AdminPermission(String filter, int action_mask) { 470 super(filter); 471 472 if (filter.equals("*")) { this.wildcard = true; 475 this.filter = null; 476 } else { 477 this.wildcard = false; 478 this.filter = filter; 479 } 480 this.bundle = null; 481 this.action_mask = action_mask; 482 } 483 484 490 private static int getMask(String actions) { 491 492 boolean seencomma = false; 493 494 int mask = ACTION_NONE; 495 496 if (actions == null) { 497 return mask; 498 } 499 500 char[] a = actions.toCharArray(); 501 502 int i = a.length - 1; 503 if (i < 0) 504 return mask; 505 506 while (i != -1) { 507 char c; 508 509 while ((i!=-1) && ((c = a[i]) == ' ' || 511 c == '\r' || 512 c == '\n' || 513 c == '\f' || 514 c == '\t')) 515 i--; 516 517 int matchlen; 519 520 if (i >= 4 && 521 (a[i-4] == 'c' || a[i-4] == 'C') && 522 (a[i-3] == 'l' || a[i-3] == 'L') && 523 (a[i-2] == 'a' || a[i-2] == 'A') && 524 (a[i-1] == 's' || a[i-1] == 'S') && 525 (a[i] == 's' || a[i] == 'S')) 526 { 527 matchlen = 5; 528 mask |= ACTION_CLASS; 529 530 } else if (i >= 6 && 531 (a[i-6] == 'e' || a[i-6] == 'E') && 532 (a[i-5] == 'x' || a[i-5] == 'X') && 533 (a[i-4] == 'e' || a[i-4] == 'E') && 534 (a[i-3] == 'c' || a[i-3] == 'C') && 535 (a[i-2] == 'u' || a[i-2] == 'U') && 536 (a[i-1] == 't' || a[i-1] == 'T') && 537 (a[i] == 'e' || a[i] == 'E')) 538 { 539 matchlen = 7; 540 mask |= ACTION_EXECUTE; 541 542 } else if (i >= 17 && 543 (a[i-17] == 'e' || a[i-17] == 'E') && 544 (a[i-16] == 'x' || a[i-16] == 'X') && 545 (a[i-15] == 't' || a[i-15] == 'T') && 546 (a[i-14] == 'e' || a[i-14] == 'E') && 547 (a[i-13] == 'n' || a[i-13] == 'N') && 548 (a[i-12] == 's' || a[i-12] == 'S') && 549 (a[i-11] == 'i' || a[i-11] == 'I') && 550 (a[i-10] == 'o' || a[i-10] == 'O') && 551 (a[i-9] == 'n' || a[i-9] == 'N') && 552 (a[i-8] == 'l' || a[i-8] == 'L') && 553 (a[i-7] == 'i' || a[i-7] == 'I') && 554 (a[i-6] == 'f' || a[i-6] == 'F') && 555 (a[i-5] == 'e' || a[i-5] == 'E') && 556 (a[i-4] == 'c' || a[i-4] == 'C') && 557 (a[i-3] == 'y' || a[i-3] == 'Y') && 558 (a[i-2] == 'c' || a[i-2] == 'C') && 559 (a[i-1] == 'l' || a[i-1] == 'L') && 560 (a[i] == 'e' || a[i] == 'E')) 561 { 562 matchlen = 18; 563 mask |= ACTION_EXTENSIONLIFECYCLE; 564 565 } else if (i >= 8 && 566 (a[i-8] == 'l' || a[i-8] == 'L') && 567 (a[i-7] == 'i' || a[i-7] == 'I') && 568 (a[i-6] == 'f' || a[i-6] == 'F') && 569 (a[i-5] == 'e' || a[i-5] == 'E') && 570 (a[i-4] == 'c' || a[i-4] == 'C') && 571 (a[i-3] == 'y' || a[i-3] == 'Y') && 572 (a[i-2] == 'c' || a[i-2] == 'C') && 573 (a[i-1] == 'l' || a[i-1] == 'L') && 574 (a[i] == 'e' || a[i] == 'E')) 575 { 576 matchlen = 9; 577 mask |= ACTION_LIFECYCLE; 578 579 } else if (i >= 7 && 580 (a[i-7] == 'l' || a[i-7] == 'L') && 581 (a[i-6] == 'i' || a[i-6] == 'I') && 582 (a[i-5] == 's' || a[i-5] == 'S') && 583 (a[i-4] == 't' || a[i-4] == 'T') && 584 (a[i-3] == 'e' || a[i-3] == 'E') && 585 (a[i-2] == 'n' || a[i-2] == 'N') && 586 (a[i-1] == 'e' || a[i-1] == 'E') && 587 (a[i] == 'r' || a[i] == 'R')) 588 { 589 matchlen = 8; 590 mask |= ACTION_LISTENER; 591 592 } else if (i >= 7 && 593 (a[i-7] == 'm' || a[i-7] == 'M') && 594 (a[i-6] == 'e' || a[i-6] == 'E') && 595 (a[i-5] == 't' || a[i-5] == 'T') && 596 (a[i-4] == 'a' || a[i-4] == 'A') && 597 (a[i-3] == 'd' || a[i-3] == 'D') && 598 (a[i-2] == 'a' || a[i-2] == 'A') && 599 (a[i-1] == 't' || a[i-1] == 'T') && 600 (a[i] == 'a' || a[i] == 'A')) 601 { 602 matchlen = 8; 603 mask |= ACTION_METADATA; 604 605 } else if (i >= 6 && 606 (a[i-6] == 'r' || a[i-6] == 'R') && 607 (a[i-5] == 'e' || a[i-5] == 'E') && 608 (a[i-4] == 's' || a[i-4] == 'S') && 609 (a[i-3] == 'o' || a[i-3] == 'O') && 610 (a[i-2] == 'l' || a[i-2] == 'L') && 611 (a[i-1] == 'v' || a[i-1] == 'V') && 612 (a[i] == 'e' || a[i] == 'E')) 613 { 614 matchlen = 7; 615 mask |= ACTION_RESOLVE; 616 617 } else if (i >= 7 && 618 (a[i-7] == 'r' || a[i-7] == 'R') && 619 (a[i-6] == 'e' || a[i-6] == 'E') && 620 (a[i-5] == 's' || a[i-5] == 'S') && 621 (a[i-4] == 'o' || a[i-4] == 'O') && 622 (a[i-3] == 'u' || a[i-3] == 'U') && 623 (a[i-2] == 'r' || a[i-2] == 'R') && 624 (a[i-1] == 'c' || a[i-1] == 'C') && 625 (a[i] == 'e' || a[i] == 'E')) 626 { 627 matchlen = 8; 628 mask |= ACTION_RESOURCE; 629 630 } else if (i >= 9 && 631 (a[i-9] == 's' || a[i-9] == 'S') && 632 (a[i-8] == 't' || a[i-8] == 'T') && 633 (a[i-7] == 'a' || a[i-7] == 'A') && 634 (a[i-6] == 'r' || a[i-6] == 'R') && 635 (a[i-5] == 't' || a[i-5] == 'T') && 636 (a[i-4] == 'l' || a[i-4] == 'L') && 637 (a[i-3] == 'e' || a[i-3] == 'E') && 638 (a[i-2] == 'v' || a[i-2] == 'V') && 639 (a[i-1] == 'e' || a[i-1] == 'E') && 640 (a[i] == 'l' || a[i] == 'L')) 641 { 642 matchlen = 10; 643 mask |= ACTION_STARTLEVEL; 644 645 } else if (i >= 6 && 646 (a[i-6] == 'c' || a[i-6] == 'C') && 647 (a[i-5] == 'o' || a[i-5] == 'O') && 648 (a[i-4] == 'n' || a[i-4] == 'N') && 649 (a[i-3] == 't' || a[i-3] == 'T') && 650 (a[i-2] == 'e' || a[i-2] == 'E') && 651 (a[i-1] == 'x' || a[i-1] == 'X') && 652 (a[i] == 't' || a[i] == 'T')) 653 { 654 matchlen = 7; 655 mask |= ACTION_CONTEXT; 656 657 } else if (i >= 0 && 658 659 (a[i] == '*')) 660 { 661 matchlen = 1; 662 mask |= ACTION_ALL; 663 664 } else { 665 throw new IllegalArgumentException ( 667 "invalid permission: " + actions); } 669 670 seencomma = false; 673 while (i >= matchlen && !seencomma) { 674 switch(a[i-matchlen]) { 675 case ',': 676 seencomma = true; 677 678 case ' ': case '\r': case '\n': 679 case '\f': case '\t': 680 break; 681 default: 682 throw new IllegalArgumentException ( 683 "invalid permission: " + actions); } 685 i--; 686 } 687 688 i -= matchlen; 690 } 691 692 if (seencomma) { 693 throw new IllegalArgumentException ("invalid permission: " + actions); 695 } 696 697 return mask; 698 } 699 700 711 private Dictionary getProperties() { 712 if (bundleProperties == null) { 713 bundleProperties = new Hashtable(); 714 715 AccessController.doPrivileged(new PrivilegedAction() { 716 public Object run() { 717 bundleProperties.put("id",new Long (bundle.getBundleId())); 720 bundleProperties.put("location",bundle.getLocation()); 723 if (bundle.getSymbolicName() != null) 725 bundleProperties.put("name",bundle.getSymbolicName()); 727 bundleProperties.put("signer",new SignerWrapper(bundle)); 730 return null; 731 } 732 }); 733 } 734 return bundleProperties; 735 } 736 737 private static class SignerWrapper extends Object { 738 private Bundle bundle; 739 private String pattern; 740 public SignerWrapper(String pattern) { 741 this.pattern = pattern; 742 } 743 SignerWrapper(Bundle bundle) { 744 this.bundle = bundle; 745 } 746 747 public boolean equals(Object o) { 748 if (!(o instanceof SignerWrapper)) 749 return false; 750 SignerWrapper other = (SignerWrapper) o; 751 AbstractBundle matchBundle = (AbstractBundle) (bundle != null ? bundle : other.bundle); 752 String matchPattern = bundle != null ? other.pattern : pattern; 753 return matchBundle.getBundleData().matchDNChain(matchPattern); 754 } 755 } 756 757 768 private Filter getFilterImpl() { 769 if (filterImpl == null) { 770 try { 771 int pos = filter.indexOf("signer"); if (pos != -1){ 773 774 StringBuffer filterBuf = new StringBuffer (filter); 776 int numAsteriskFound = 0; 778 int walkbackPos; 780 while (pos != -1) { 782 783 walkbackPos = pos-1; 785 786 while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) { 788 walkbackPos--; 789 } 790 if (walkbackPos <0) { 791 break; 793 } 794 795 if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) { 797 pos = filter.indexOf("signer",pos+6); continue; 800 } 801 pos+=6; 803 while (Character.isWhitespace(filter.charAt(pos))) { 805 pos++; 806 } 807 808 if (filter.charAt(pos) != '=') { 810 pos = filter.indexOf("signer",pos); continue; 813 } 814 pos++; 816 while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) { 818 if (filter.charAt(pos) == '*') { 819 filterBuf.insert(pos+numAsteriskFound,'\\'); 820 numAsteriskFound++; 821 } 822 pos++; 823 } 824 825 pos = filter.indexOf("signer",pos); } filter = filterBuf.toString(); 829 } 831 filterImpl = new FilterImpl(filter); 832 } catch (InvalidSyntaxException e) { 833 } 835 } 836 return filterImpl; 837 } 838 839 846 int getMask() { 847 return action_mask; 848 } 849 850 private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException { 851 if (actions == null) 854 getActions(); 855 if (filter == null && !wildcard) 856 throw new UnsupportedOperationException ("cannot serialize"); s.defaultWriteObject(); 858 } 859 860 864 private synchronized void readObject(java.io.ObjectInputStream s) throws IOException , ClassNotFoundException { 865 s.defaultReadObject(); 867 action_mask = getMask(actions); 868 } 869 } 870 871 874 final class AdminPermissionCollection extends PermissionCollection 875 { 876 private static final long serialVersionUID = 3906372644575328048L; 877 882 private Hashtable permissions; 883 884 888 889 public AdminPermissionCollection() 890 { 891 permissions = new Hashtable(); 892 } 893 894 906 public void add(Permission permission) 907 { 908 if (! (permission instanceof AdminPermission)) 909 throw new IllegalArgumentException ("invalid permission: "+ permission); 911 if (isReadOnly()) 912 throw new SecurityException ("attempt to add a Permission to a " + "readonly AdminCollection"); AdminPermission ap = (AdminPermission) permission; 915 AdminPermission existing = (AdminPermission) permissions.get(ap.getName()); 916 if (existing != null){ 917 int oldMask = existing.getMask(); 918 int newMask = ap.getMask(); 919 920 if (oldMask != newMask) { 921 permissions.put(existing.getName(), 922 new AdminPermission(existing.getName(), oldMask | newMask)); 923 } 924 } else { 925 permissions.put(ap.getName(), ap); 926 } 927 } 928 929 930 940 public boolean implies(Permission permission) 941 { 942 if (!(permission instanceof AdminPermission)) 943 return(false); 944 945 AdminPermission target = (AdminPermission) permission; 946 947 Iterator permItr = permissions.values().iterator(); 949 950 while(permItr.hasNext()) 951 if (((AdminPermission)permItr.next()).implies(target)) 952 return true; 953 return false; 954 } 955 956 957 963 964 public Enumeration elements() 965 { 966 return(Collections.enumeration(permissions.values())); 967 } 968 } 969 | Popular Tags |