1 22 package org.jboss.security.srp; 23 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.InvocationTargetException ; 26 import java.lang.reflect.Proxy ; 27 import java.lang.reflect.UndeclaredThrowableException ; 28 import java.rmi.server.RMIClientSocketFactory ; 29 import java.rmi.server.RMIServerSocketFactory ; 30 import java.util.Collections ; 31 import java.util.HashMap ; 32 import java.util.Map ; 33 import javax.naming.InitialContext ; 34 import javax.naming.Name ; 35 import javax.naming.NamingException ; 36 37 import org.jboss.invocation.Invocation; 38 import org.jboss.invocation.MarshalledInvocation; 39 import org.jboss.naming.NonSerializableFactory; 40 import org.jboss.security.srp.SRPRemoteServer; 41 import org.jboss.security.srp.SRPServerListener; 42 import org.jboss.security.srp.SRPServerInterface; 43 import org.jboss.security.srp.SRPServerSession; 44 import org.jboss.security.srp.SRPVerifierStore; 45 import org.jboss.system.ServiceMBeanSupport; 46 import org.jboss.util.CachePolicy; 47 import org.jboss.util.TimedCachePolicy; 48 49 56 public class SRPService extends ServiceMBeanSupport 57 implements SRPServiceMBean, SRPServerListener 58 { 59 65 private SRPRemoteServer server; 66 private int serverPort = 10099; 67 68 73 private SRPVerifierStore verifierStore; 74 private String verifierSourceJndiName = "srp/DefaultVerifierSource"; 75 private String serverJndiName = "srp/SRPServerInterface"; 76 private String cacheJndiName = "srp/AuthenticationCache"; 77 private CachePolicy cachePolicy; 78 private int cacheTimeout = 1800; 79 private int cacheResolution = 60; 80 83 private boolean overwriteSessions; 84 85 private boolean requireAuxChallenge; 86 87 private RMIClientSocketFactory clientSocketFactory; 88 89 private RMIServerSocketFactory serverSocketFactory; 90 91 private String clientSocketFactoryName; 92 93 private String serverSocketFactoryName; 94 95 private Map marshalledInvocationMapping = new HashMap (); 96 97 100 public String getVerifierSourceJndiName() 101 { 102 return verifierSourceJndiName; 103 } 104 106 public void setVerifierSourceJndiName(String jndiName) 107 { 108 this.verifierSourceJndiName = jndiName; 109 } 110 112 public String getJndiName() 113 { 114 return serverJndiName; 115 } 116 118 public void setJndiName(String jndiName) 119 { 120 this.serverJndiName = jndiName; 121 } 122 124 public String getAuthenticationCacheJndiName() 125 { 126 return cacheJndiName; 127 } 128 130 public void setAuthenticationCacheJndiName(String jndiName) 131 { 132 this.cacheJndiName = jndiName; 133 } 134 135 137 public int getAuthenticationCacheTimeout() 138 { 139 return cacheTimeout; 140 } 141 143 public void setAuthenticationCacheTimeout(int timeoutInSecs) 144 { 145 this.cacheTimeout = timeoutInSecs; 146 } 147 149 public int getAuthenticationCacheResolution() 150 { 151 return cacheResolution; 152 } 153 155 public void setAuthenticationCacheResolution(int resInSecs) 156 { 157 this.cacheResolution = resInSecs; 158 } 159 160 public boolean getRequireAuxChallenge() 161 { 162 return this.requireAuxChallenge; 163 } 164 public void setRequireAuxChallenge(boolean flag) 165 { 166 this.requireAuxChallenge = flag; 167 } 168 169 public boolean getOverwriteSessions() 170 { 171 return this.overwriteSessions; 172 } 173 public void setOverwriteSessions(boolean flag) 174 { 175 this.overwriteSessions = flag; 176 } 177 178 181 public String getClientSocketFactory() 182 { 183 return serverSocketFactoryName; 184 } 185 188 public void setClientSocketFactory(String factoryClassName) 189 throws ClassNotFoundException , InstantiationException , IllegalAccessException 190 { 191 this.clientSocketFactoryName = factoryClassName; 192 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 193 Class clazz = loader.loadClass(clientSocketFactoryName); 194 clientSocketFactory = (RMIClientSocketFactory ) clazz.newInstance(); 195 } 196 197 200 public String getServerSocketFactory() 201 { 202 return serverSocketFactoryName; 203 } 204 207 public void setServerSocketFactory(String factoryClassName) 208 throws ClassNotFoundException , InstantiationException , IllegalAccessException 209 { 210 this.serverSocketFactoryName = factoryClassName; 211 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 212 Class clazz = loader.loadClass(serverSocketFactoryName); 213 serverSocketFactory = (RMIServerSocketFactory ) clazz.newInstance(); 214 } 215 217 public int getServerPort() 218 { 219 return serverPort; 220 } 221 223 public void setServerPort(int serverPort) 224 { 225 this.serverPort = serverPort; 226 } 227 229 233 public void verifiedUser(SRPSessionKey key, SRPServerSession session) 234 { 235 try 236 { 237 synchronized( cachePolicy ) 238 { 239 if( cachePolicy.peek(key) == null ) 241 { 242 cachePolicy.insert(key, session); 243 log.trace("Cached SRP session for user="+key); 244 } 245 else if( overwriteSessions ) 246 { 247 cachePolicy.remove(key); 248 cachePolicy.insert(key, session); 249 log.trace("Replaced SRP session for user="+key); 250 } 251 else 252 { 253 log.debug("Ignoring SRP session due to existing session for user="+key); 254 } 255 } 256 } 257 catch(Exception e) 258 { 259 log.error("Failed to update SRP cache for user="+key, e); 260 } 261 } 262 public void closedUserSession(SRPSessionKey key) 263 { 264 try 265 { 266 synchronized( cachePolicy ) 267 { 268 if( cachePolicy.peek(key) == null ) 270 { 271 log.warn("No SRP session found for user="+key); 272 } 273 cachePolicy.remove(key); 274 } 275 } 276 catch(Exception e) 277 { 278 log.error("Failed to update SRP cache for user="+key, e); 279 } 280 } 281 282 public String getName() 283 { 284 return "SRPService"; 285 } 286 287 public Object invoke(Invocation invocation) throws Exception 288 { 289 if (invocation instanceof MarshalledInvocation) 291 { 292 MarshalledInvocation mi = (MarshalledInvocation) invocation; 293 mi.setMethodMap(marshalledInvocationMapping); 294 } 295 Method method = invocation.getMethod(); 297 Object [] args = invocation.getArguments(); 298 Object value = null; 299 try 300 { 301 value = method.invoke(server, args); 302 } 303 catch(InvocationTargetException e) 304 { 305 Throwable t = e.getTargetException(); 306 if( t instanceof Exception ) 307 throw (Exception ) t; 308 else 309 throw new UndeclaredThrowableException (t, method.toString()); 310 } 311 312 return value; 313 } 314 315 protected void startService() throws Exception 316 { 317 loadStore(); 318 server = new SRPRemoteServer(verifierStore, serverPort, 319 clientSocketFactory, serverSocketFactory); 320 server.addSRPServerListener(this); 321 server.setRequireAuxChallenge(this.requireAuxChallenge); 322 323 InitialContext ctx = new InitialContext (); 325 if( serverJndiName != null && serverJndiName.length() > 0 ) 326 { 327 SRPServerProxy proxyHandler = new SRPServerProxy(server); 328 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 329 Class [] interfaces = {SRPServerInterface.class}; 330 Object proxy = Proxy.newProxyInstance(loader, interfaces, proxyHandler); 331 org.jboss.naming.Util.rebind(ctx, serverJndiName, proxy); 332 log.debug("Bound SRPServerProxy at "+serverJndiName); 333 } 334 335 try 337 { 338 cachePolicy = (CachePolicy) ctx.lookup(cacheJndiName); 339 log.debug("Found AuthenticationCache at: "+cacheJndiName); 340 } 341 catch(Exception e) 342 { 343 log.trace("Failed to find existing cache at: "+cacheJndiName, e); 344 cachePolicy = new TimedCachePolicy(cacheTimeout, true, cacheResolution); 346 cachePolicy.create(); 347 cachePolicy.start(); 348 Name name = ctx.getNameParser("").parse(cacheJndiName); 350 NonSerializableFactory.rebind(name, cachePolicy, true); 351 log.debug("Bound AuthenticationCache at "+cacheJndiName); 352 } 353 354 HashMap tmpMap = new HashMap (13); 356 Method [] methods = SRPRemoteServerInterface.class.getMethods(); 357 for(int m = 0; m < methods.length; m ++) 358 { 359 Method method = methods[m]; 360 Long hash = new Long (MarshalledInvocation.calculateHash(method)); 361 tmpMap.put(hash, method); 362 } 363 marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap); 364 } 365 366 protected void stopService() throws Exception 367 { 368 InitialContext ctx = new InitialContext (); 370 ctx.unbind(serverJndiName); 371 log.debug("Unbound SRPServerProxy at "+serverJndiName); 372 NonSerializableFactory.unbind(cacheJndiName); 373 ctx.unbind(cacheJndiName); 374 log.debug("Unbound AuthenticationCache at "+cacheJndiName); 375 } 376 377 private void loadStore() throws NamingException 378 { 379 InitialContext ctx = new InitialContext (); 380 verifierStore = (SRPVerifierStore) ctx.lookup(verifierSourceJndiName); 382 if( server != null ) 383 { 384 server.setVerifierStore(verifierStore); 385 } 386 } 387 388 } 389 | Popular Tags |