/** Remove the objects under administration from the JNDI Context, and then destroy the objects */ public void tearDown() { try { InitialContext ic = new InitialContext(); for (Iterator i = this.objectsToCreate.keySet().iterator(); i.hasNext(); ) { String name = (String) i.next(); try { ic.unbind(name); } catch (NamingException err) { Logger.log( Logger.ERROR, JNDI_RESOURCES, "ContainerJNDIManager.ErrorUnbindingResource", name, err); } Object unboundObject = this.objectsToCreate.get(name); if (unboundObject instanceof WinstoneDataSource) ((WinstoneDataSource) unboundObject).destroy(); Logger.log(Logger.FULL_DEBUG, JNDI_RESOURCES, "ContainerJNDIManager.UnboundResource", name); } Logger.log( Logger.DEBUG, JNDI_RESOURCES, "ContainerJNDIManager.TeardownComplete", "" + this.objectsToCreate.size()); } catch (NamingException err) { Logger.log( Logger.ERROR, JNDI_RESOURCES, "ContainerJNDIManager.ErrorGettingInitialContext", err); } }
/** Add the objects passed to the constructor to the JNDI Context addresses specified */ public void setup() { try { InitialContext ic = new InitialContext(); for (Iterator i = this.objectsToCreate.keySet().iterator(); i.hasNext(); ) { String name = (String) i.next(); try { Name fullName = new CompositeName(name); Context currentContext = ic; while (fullName.size() > 1) { // Make contexts that are not already present try { currentContext = currentContext.createSubcontext(fullName.get(0)); } catch (NamingException err) { currentContext = (Context) currentContext.lookup(fullName.get(0)); } fullName = fullName.getSuffix(1); } ic.bind(name, this.objectsToCreate.get(name)); Logger.log(Logger.FULL_DEBUG, JNDI_RESOURCES, "ContainerJNDIManager.BoundResource", name); } catch (NamingException err) { Logger.log( Logger.ERROR, JNDI_RESOURCES, "ContainerJNDIManager.ErrorBindingResource", name, err); } } Logger.log( Logger.DEBUG, JNDI_RESOURCES, "ContainerJNDIManager.SetupComplete", "" + this.objectsToCreate.size()); } catch (NamingException err) { Logger.log( Logger.ERROR, JNDI_RESOURCES, "ContainerJNDIManager.ErrorGettingInitialContext", err); } }
/** * Used to get the base ssl context in which to create the server socket. This is basically just * so we can have a custom location for key stores. */ public SSLContext getSSLContext(String keyStoreName, String password) throws IOException { try { // Check the key manager factory KeyManagerFactory kmf = KeyManagerFactory.getInstance(this.keyManagerType); File ksFile = new File(keyStoreName); if (!ksFile.exists() || !ksFile.isFile()) throw new WinstoneException( SSL_RESOURCES.getString("HttpsListener.KeyStoreNotFound", ksFile.getPath())); InputStream in = new FileInputStream(ksFile); char[] passwordChars = password == null ? null : password.toCharArray(); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(in, passwordChars); kmf.init(ks, passwordChars); Logger.log(Logger.FULL_DEBUG, SSL_RESOURCES, "HttpsListener.KeyCount", ks.size() + ""); for (Enumeration e = ks.aliases(); e.hasMoreElements(); ) { String alias = (String) e.nextElement(); Logger.log( Logger.FULL_DEBUG, SSL_RESOURCES, "HttpsListener.KeyFound", new String[] {alias, ks.getCertificate(alias) + ""}); } SSLContext context = SSLContext.getInstance("SSL"); context.init(kmf.getKeyManagers(), null, null); Arrays.fill(passwordChars, 'x'); return context; } catch (IOException err) { throw err; } catch (Throwable err) { throw new WinstoneException( SSL_RESOURCES.getString("HttpsListener.ErrorGettingContext"), err); } }
protected boolean doRoleCheck( HttpServletRequest request, HttpServletResponse response, String pathRequested) throws IOException, ServletException { // Loop through constraints boolean foundApplicable = false; for (int n = 0; (n < this.constraints.length) && !foundApplicable; n++) { Logger.log( Logger.FULL_DEBUG, AUTH_RESOURCES, "BaseAuthenticationHandler.EvalConstraint", this.constraints[n].getName()); // Find one that applies, then if (this.constraints[n].isApplicable(pathRequested, request.getMethod())) { Logger.log( Logger.FULL_DEBUG, AUTH_RESOURCES, "BaseAuthenticationHandler.ApplicableConstraint", this.constraints[n].getName()); foundApplicable = true; if (this.constraints[n].needsSSL() && !request.isSecure()) { Logger.log( Logger.DEBUG, AUTH_RESOURCES, "BaseAuthenticationHandler.ConstraintNeedsSSL", this.constraints[n].getName()); response.sendError( HttpServletResponse.SC_FORBIDDEN, AUTH_RESOURCES.getString( "BaseAuthenticationHandler.ConstraintNeedsSSL", this.constraints[n].getName())); return false; } else if (!this.constraints[n].isAllowed(request)) { // Logger.log(Logger.FULL_DEBUG, "Not allowed - requesting auth"); requestAuthentication(request, response, pathRequested); return false; } else { // Logger.log(Logger.FULL_DEBUG, "Allowed - authorization accepted"); // Ensure that secured resources are not cached setNoCache(response); } } } // If we made it this far without a check being run, there must be none applicable Logger.log(Logger.FULL_DEBUG, AUTH_RESOURCES, "BaseAuthenticationHandler.PassedAuthCheck"); return true; }
private void log(int level, String msgKey, String arg[], Throwable err) { if (getLogWriter() != null) { getLogWriter().println(DS_RESOURCES.getString(msgKey, arg)); if (err != null) { err.printStackTrace(getLogWriter()); } } else { Logger.log(level, DS_RESOURCES, msgKey, arg, err); } }
/** * Evaluates any authentication constraints, intercepting if auth is required. The relevant * authentication handler subclass's logic is used to actually authenticate. * * @return A boolean indicating whether to continue after this request */ public boolean processAuthentication( ServletRequest inRequest, ServletResponse inResponse, String pathRequested) throws IOException, ServletException { Logger.log(Logger.FULL_DEBUG, AUTH_RESOURCES, "BaseAuthenticationHandler.StartAuthCheck"); HttpServletRequest request = (HttpServletRequest) inRequest; HttpServletResponse response = (HttpServletResponse) inResponse; // Give previous attempts a chance to be validated if (!validatePossibleAuthenticationResponse(request, response, pathRequested)) { return false; } else { return doRoleCheck(request, response, pathRequested); } }
/** * Gets the relevant list of objects from the args, validating against the web.xml nodes supplied. * All node addresses are assumed to be relative to the java:/comp/env context */ public ContainerJNDIManager(Map args, List webXmlNodes, ClassLoader loader) { // Build all the objects we wanted this.objectsToCreate = new HashMap(); Collection keys = new ArrayList(args != null ? args.keySet() : (Collection) new ArrayList()); for (Iterator i = keys.iterator(); i.hasNext(); ) { String key = (String) i.next(); if (key.startsWith("jndi.resource.")) { String resName = key.substring(14); String className = (String) args.get(key); String value = (String) args.get("jndi.param." + resName + ".value"); Logger.log( Logger.FULL_DEBUG, JNDI_RESOURCES, "ContainerJNDIManager.CreatingResourceArgs", resName); Object obj = createObject(resName.trim(), className.trim(), value, args, loader); if (obj != null) this.objectsToCreate.put(resName, obj); } } }
/** Build an object to insert into the jndi space */ protected Object createObject( String name, String className, String value, Map args, ClassLoader loader) { if ((className == null) || (name == null)) return null; // Set context class loader ClassLoader cl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(loader); try { // If we are working with a datasource if (className.equals("javax.sql.DataSource")) { try { return new WinstoneDataSource(name, extractRelevantArgs(args, name), loader); } catch (Throwable err) { Logger.log( Logger.ERROR, JNDI_RESOURCES, "ContainerJNDIManager.ErrorBuildingDatasource", name, err); } } // If we are working with a mail session else if (className.equals("javax.mail.Session")) { try { Class smtpClass = Class.forName(className, true, loader); Method smtpMethod = smtpClass.getMethod( "getInstance", new Class[] {Properties.class, Class.forName("javax.mail.Authenticator")}); return smtpMethod.invoke(null, new Object[] {extractRelevantArgs(args, name), null}); // return Session.getInstance(extractRelevantArgs(args, name), null); } catch (Throwable err) { Logger.log( Logger.ERROR, JNDI_RESOURCES, "ContainerJNDIManager.ErrorBuildingMailSession", name, err); } } // If unknown type, try to instantiate with the string constructor else if (value != null) { try { Class objClass = Class.forName(className.trim(), true, loader); Constructor objConstr = objClass.getConstructor(new Class[] {String.class}); return objConstr.newInstance(new Object[] {value}); } catch (Throwable err) { Logger.log( Logger.ERROR, JNDI_RESOURCES, "ContainerJNDIManager.ErrorBuildingObject", new String[] {name, className}, err); } } return null; } finally { Thread.currentThread().setContextClassLoader(cl); } }
/** * The maintenance thread. This makes sure that any changes in the files in the classpath trigger * a classLoader self destruct and recreate. */ public void run() { Logger.log(Logger.FULL_DEBUG, CL_RESOURCES, "ReloadingClassLoader.MaintenanceThreadStarted"); Map classDateTable = new HashMap(); Map classLocationTable = new HashMap(); Set lostClasses = new HashSet(); while (!interrupted) { try { String loadedClassesCopy[] = null; synchronized (this) { loadedClassesCopy = (String[]) this.loadedClasses.toArray(new String[0]); } for (int n = 0; (n < loadedClassesCopy.length) && !interrupted; n++) { Thread.sleep(RELOAD_SEARCH_SLEEP); String className = transformToFileFormat(loadedClassesCopy[n]); File location = (File) classLocationTable.get(className); Long classDate = null; if ((location == null) || !location.exists()) { for (int j = 0; (j < this.classPaths.length) && (classDate == null); j++) { File path = this.classPaths[j]; if (!path.exists()) { continue; } else if (path.isDirectory()) { File classLocation = new File(path, className); if (classLocation.exists()) { classDate = new Long(classLocation.lastModified()); classLocationTable.put(className, classLocation); } } else if (path.isFile()) { classDate = searchJarPath(className, path); if (classDate != null) classLocationTable.put(className, path); } } } else if (location.exists()) classDate = new Long(location.lastModified()); // Has class vanished ? Leave a note and skip over it if (classDate == null) { if (!lostClasses.contains(className)) { lostClasses.add(className); Logger.log(Logger.DEBUG, CL_RESOURCES, "ReloadingClassLoader.ClassLost", className); } continue; } if ((classDate != null) && lostClasses.contains(className)) { lostClasses.remove(className); } // Stash date of loaded files, and compare with last // iteration Long oldClassDate = (Long) classDateTable.get(className); if (oldClassDate == null) { classDateTable.put(className, classDate); } else if (oldClassDate.compareTo(classDate) != 0) { // Trigger reset of webAppConfig Logger.log( Logger.INFO, CL_RESOURCES, "ReloadingClassLoader.ReloadRequired", new String[] { className, "" + new Date(classDate.longValue()), "" + new Date(oldClassDate.longValue()) }); this.webAppConfig.resetClassLoader(); } } } catch (Throwable err) { Logger.log(Logger.ERROR, CL_RESOURCES, "ReloadingClassLoader.MaintenanceThreadError", err); } } Logger.log(Logger.FULL_DEBUG, CL_RESOURCES, "ReloadingClassLoader.MaintenanceThreadFinished"); }