1 8 9 package mx4j.remote; 10 11 import java.io.ByteArrayOutputStream ; 12 import java.io.IOException ; 13 import java.io.ObjectOutputStream ; 14 import java.io.Serializable ; 15 import java.lang.reflect.Constructor ; 16 import java.security.AccessControlContext ; 17 import java.security.AccessController ; 18 import java.security.CodeSource ; 19 import java.security.DomainCombiner ; 20 import java.security.Permission ; 21 import java.security.PermissionCollection ; 22 import java.security.Principal ; 23 import java.security.PrivilegedAction ; 24 import java.security.PrivilegedActionException ; 25 import java.security.PrivilegedExceptionAction ; 26 import java.security.ProtectionDomain ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 import java.util.Set ; 31 32 import javax.management.remote.SubjectDelegationPermission ; 33 import javax.security.auth.AuthPermission ; 34 import javax.security.auth.Policy ; 35 import javax.security.auth.Subject ; 36 37 42 public class MX4JRemoteUtils 43 { 44 private static int connectionNumber; 45 46 49 public static Map removeNonSerializableEntries(Map map) 50 { 51 Map newMap = new HashMap (map.size()); 52 for (Iterator i = map.entrySet().iterator(); i.hasNext();) 53 { 54 Map.Entry entry = (Map.Entry )i.next(); 55 if (isSerializable(entry)) newMap.put(entry.getKey(), entry.getValue()); 56 } 57 return newMap; 58 } 59 60 private static boolean isSerializable(Object object) 61 { 62 if (object instanceof Map.Entry ) return isSerializable(((Map.Entry )object).getKey()) && isSerializable(((Map.Entry )object).getValue()); 63 if (object == null) return true; 64 if (object instanceof String ) return true; 65 if (object instanceof Number ) return true; 66 if (!(object instanceof Serializable )) return false; 67 68 return isTrulySerializable(object); 69 } 70 71 public static boolean isTrulySerializable(Object object) 72 { 73 try 75 { 76 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 77 ObjectOutputStream oos = new ObjectOutputStream (baos); 78 oos.writeObject(object); 79 oos.close(); 80 return true; 81 } 82 catch (IOException ignored) 83 { 84 } 85 return false; 86 } 87 88 public static String createConnectionID(String protocol, String callerAddress, int callerPort, Subject subject) 89 { 90 92 StringBuffer buffer = new StringBuffer (protocol); 93 buffer.append(':'); 94 if (callerAddress != null) buffer.append("//").append(callerAddress); 95 if (callerPort >= 0) buffer.append(':').append(callerPort); 96 buffer.append(' '); 97 98 if (subject != null) 99 { 100 Set principals = subject.getPrincipals(); 101 for (Iterator i = principals.iterator(); i.hasNext();) 102 { 103 Principal principal = (Principal )i.next(); 104 String name = principal.getName(); 105 name = name.replace(' ', '_'); 106 buffer.append(name); 107 if (i.hasNext()) buffer.append(';'); 108 } 109 } 110 buffer.append(' '); 111 112 buffer.append("0x").append(Integer.toHexString(getNextConnectionNumber())); 113 114 return buffer.toString(); 115 } 116 117 private static synchronized int getNextConnectionNumber() 118 { 119 return ++connectionNumber; 120 } 121 122 public static Object subjectInvoke(Subject subject, Subject delegate, AccessControlContext context, PrivilegedExceptionAction action) throws Exception 123 { 124 if (delegate != null) 125 { 126 if (subject == null) throw new SecurityException ("There is no authenticated subject to delegate to"); 127 checkSubjectDelegationPermission(delegate, getSubjectContext(subject, context)); 128 } 129 130 if (subject == null) 131 { 132 if (context == null) return action.run(); 133 try 134 { 135 return AccessController.doPrivileged(action, context); 136 } 137 catch (PrivilegedActionException x) 138 { 139 throw x.getException(); 140 } 141 } 142 143 try 148 { 149 AccessControlContext subjectContext = getSubjectContext(subject, context); 150 if (delegate == null) 151 return Subject.doAsPrivileged(subject, action, subjectContext); 152 else 153 return Subject.doAsPrivileged(delegate, action, subjectContext); 154 } 155 catch (PrivilegedActionException x) 156 { 157 throw x.getException(); 158 } 159 } 160 161 private static void checkSubjectDelegationPermission(final Subject delegate, AccessControlContext context) throws SecurityException 162 { 163 final SecurityManager sm = System.getSecurityManager(); 164 if (sm != null) 165 { 166 AccessController.doPrivileged(new PrivilegedAction () 167 { 168 public Object run() 169 { 170 StringBuffer buffer = new StringBuffer (); 171 Set principals = delegate.getPrincipals(); 172 for (Iterator i = principals.iterator(); i.hasNext();) 173 { 174 Principal principal = (Principal )i.next(); 175 buffer.setLength(0); 176 String permission = buffer.append(principal.getClass().getName()).append(".").append(principal.getName()).toString(); 177 sm.checkPermission(new SubjectDelegationPermission (permission)); 178 } 179 return null; 180 } 181 }, context); 182 } 183 } 184 185 215 private static AccessControlContext getSubjectContext(final Subject subject, final AccessControlContext context) 216 { 217 final SecurityManager sm = System.getSecurityManager(); 218 if (sm == null) 219 { 220 return context; 221 } 222 else 223 { 224 return (AccessControlContext )AccessController.doPrivileged(new PrivilegedAction () 225 { 226 public Object run() 227 { 228 InjectingDomainCombiner combiner = new InjectingDomainCombiner(subject); 229 AccessControlContext acc = new AccessControlContext (context, combiner); 230 AccessController.doPrivileged(new PrivilegedAction () 231 { 232 public Object run() 233 { 234 sm.checkPermission(new AuthPermission ("doAsPrivileged")); 236 return null; 237 } 238 }, acc); 239 ProtectionDomain [] combined = combiner.getCombinedDomains(); 240 return new AccessControlContext (combined); 241 } 242 }); 243 } 244 } 245 246 private static class InjectingDomainCombiner implements DomainCombiner 247 { 248 private static Constructor domainConstructor; 249 250 static 251 { 252 try 253 { 254 domainConstructor = ProtectionDomain .class.getConstructor(new Class []{CodeSource .class, PermissionCollection .class, ClassLoader .class, Principal [].class}); 255 } 256 catch (Exception x) 257 { 258 } 259 } 260 261 private ProtectionDomain domain; 262 private ProtectionDomain [] combined; 263 264 public InjectingDomainCombiner(Subject subject) 265 { 266 if (domainConstructor != null) 267 { 268 Principal [] principals = (Principal [])subject.getPrincipals().toArray(new Principal [0]); 269 try 270 { 271 domain = (ProtectionDomain )domainConstructor.newInstance(new Object []{new CodeSource (null, null), null, null, principals}); 272 } 273 catch (Exception x) 274 { 275 } 276 } 277 278 if (domain == null) 279 { 280 domain = new SubjectProtectionDomain(new CodeSource (null, null), subject); 282 } 283 } 284 285 public ProtectionDomain [] combine(ProtectionDomain [] current, ProtectionDomain [] assigned) 286 { 287 int length = current.length; 288 ProtectionDomain [] result = null; 289 if (assigned == null || assigned.length == 0) 290 { 291 result = new ProtectionDomain [length + 1]; 292 System.arraycopy(current, 0, result, 0, length); 293 } 294 else 295 { 296 result = new ProtectionDomain [length + assigned.length + 1]; 297 System.arraycopy(current, 0, result, 0, length); 298 System.arraycopy(assigned, 0, result, length, assigned.length); 299 } 300 result[result.length - 1] = domain; 301 this.combined = result; 302 return result; 303 } 304 305 public ProtectionDomain [] getCombinedDomains() 306 { 307 return combined; 308 } 309 310 private static class SubjectProtectionDomain extends ProtectionDomain 311 { 312 private final Subject subject; 313 314 public SubjectProtectionDomain(CodeSource codesource, Subject subject) 315 { 316 super(codesource, null); 317 this.subject = subject; 318 } 319 320 public boolean implies(Permission permission) 321 { 322 Policy policy = (Policy )AccessController.doPrivileged(new PrivilegedAction () 323 { 324 public Object run() 325 { 326 return Policy.getPolicy(); 327 } 328 }); 329 PermissionCollection permissions = policy.getPermissions(subject, getCodeSource()); 330 return permissions.implies(permission); 331 } 332 } 333 } 334 } 335 | Popular Tags |