From scm-return-6717-apmail-geronimo-scm-archive=geronimo.apache.org@geronimo.apache.org Tue May 17 10:56:59 2005 Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 66475 invoked from network); 17 May 2005 10:56:59 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 17 May 2005 10:56:59 -0000 Received: (qmail 65115 invoked by uid 500); 17 May 2005 00:36:31 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 65088 invoked by uid 500); 17 May 2005 00:36:31 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 65006 invoked by uid 99); 17 May 2005 00:36:26 -0000 X-ASF-Spam-Status: No, hits=-9.3 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME,WEIRD_PORT X-Spam-Check-By: apache.org Received: from minotaur.apache.org (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Mon, 16 May 2005 17:36:21 -0700 Received: (qmail 53153 invoked by uid 65534); 17 May 2005 00:28:30 -0000 Message-ID: <20050517002830.53152.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: svn commit: r170494 - in /geronimo/trunk/modules: axis-builder/src/java/org/apache/geronimo/axis/builder/ jetty/src/java/org/apache/geronimo/jetty/ jetty/src/test/org/apache/geronimo/jetty/ security/src/java/org/apache/geronimo/security/realm/providers/ webservices/src/java/org/apache/geronimo/webservices/ Date: Tue, 17 May 2005 00:28:29 -0000 To: scm@geronimo.apache.org From: djencks@apache.org X-Mailer: svnmailer-1.0.0-dev X-Virus-Checked: Checked X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: djencks Date: Mon May 16 17:28:28 2005 New Revision: 170494 URL: http://svn.apache.org/viewcvs?rev=3D170494&view=3Drev Log: GERONIMO-648 add security for ejb web services Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificateCallback.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificateCallbackHandler.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificatePropertiesFileLoginModule.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/ClearableCallbackHandler.java geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/PasswordCallbackHandler.java - copied, changed from r169699, geronimo/trunk/modules/jetty/src/java= /org/apache/geronimo/jetty/PasswordCallbackHandler.java Removed: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/Passwor= dCallbackHandler.java Modified: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/b= uilder/AxisBuilder.java geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJet= tyRealm.java geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyCo= ntainerImpl.java geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJ= BWebServiceContext.java geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/Contain= erTest.java geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webserv= ices/SoapHandler.java Modified: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/= axis/builder/AxisBuilder.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/= java/org/apache/geronimo/axis/builder/AxisBuilder.java?rev=3D170494&r1=3D17= 0493&r2=3D170494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/b= uilder/AxisBuilder.java (original) +++ geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/b= uilder/AxisBuilder.java Mon May 16 17:28:28 2005 @@ -112,7 +112,7 @@ try { classLoader.loadClass(seiClassName); } catch (ClassNotFoundException e) { - throw new DeploymentException("Unable to load servlet class fo= r pojo webservice: "+seiClassName, e); + throw new DeploymentException("Unable to load servlet class fo= r pojo webservice: " + seiClassName, e); } =20 targetGBean.setAttribute("pojoClassName", seiClassName); @@ -165,7 +165,7 @@ SchemaInfoBuilder schemaInfoBuilder =3D null; JavaWsdlMappingType mapping =3D null; if (wsdlURI !=3D null) { - schemaInfoBuilder =3D new SchemaInfoBuilder(moduleFile, wsdlU= RI); + schemaInfoBuilder =3D new SchemaInfoBuilder(moduleFile, wsdlUR= I); =20 mapping =3D WSDescriptorParser.readJaxrpcMapping(moduleFile, j= axrpcMappingURI); } @@ -237,9 +237,6 @@ } =20 Map exceptionMap =3D WSDescriptorParser.getExceptionMap(mapping); -// Map schemaTypeKeyToSchemaTypeMap =3D schemaInfoBuilder.getSchema= TypeKeyToSchemaTypeMap(); -// Map complexTypeMap =3D schemaInfoBuilder.getComplexTypesInWsdl(); -// Map elementMap =3D schemaInfoBuilder.getElementToTypeMap(); =20 Map wsdlPortMap =3D service.getPorts(); for (Iterator iterator =3D wsdlPortMap.entrySet().iterator(); iter= ator.hasNext();) { @@ -257,7 +254,7 @@ =20 ServiceEndpointInterfaceMappingType[] endpointMappings =3D map= ping.getServiceEndpointInterfaceMappingArray(); =20 - String credentialsName =3D credentialsNameMap =3D=3D null? nul= l: (String) credentialsNameMap.get(port.getName()); + String credentialsName =3D credentialsNameMap =3D=3D null ? nu= ll : (String) credentialsNameMap.get(port.getName()); =20 //port type corresponds to SEI List operations =3D portType.getOperations(); @@ -274,15 +271,20 @@ javax.wsdl.Service service; if (serviceQName !=3D null) { service =3D definition.getService(serviceQName); + if (service =3D=3D null) { + throw new DeploymentException("No service wsdl for supplie= d service qname " + serviceQName); + } } else { Map services =3D definition.getServices(); - if (services.size() !=3D 1) { + if (services.size() > 1) { throw new DeploymentException("no serviceQName supplied, a= nd there are " + services.size() + " services"); } - service =3D (javax.wsdl.Service) services.values().iterator().= next(); - } - if (service =3D=3D null) { - throw new DeploymentException("No service wsdl for supplied se= rvice qname " + serviceQName); + if (services.size() =3D=3D 0) { + //partial wsdl + service =3D null; + } else { + service =3D (javax.wsdl.Service) services.values().iterato= r().next(); + } } return service; } Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/J= AASJettyRealm.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/or= g/apache/geronimo/jetty/JAASJettyRealm.java?rev=3D170494&r1=3D170493&r2=3D1= 70494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJet= tyRealm.java (original) +++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJet= tyRealm.java Mon May 16 17:28:28 2005 @@ -19,6 +19,7 @@ import java.security.AccessControlContext; import java.security.AccessControlException; import java.security.Principal; +import java.security.cert.X509Certificate; import java.util.HashMap; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; @@ -27,8 +28,11 @@ =20 import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.geronimo.security.ContextManager; import org.apache.geronimo.jetty.interceptor.SecurityContextBeforeAfter; +import org.apache.geronimo.security.ContextManager; +import org.apache.geronimo.security.realm.providers.CertificateCallbackHan= dler; +import org.apache.geronimo.security.realm.providers.ClearableCallbackHandl= er; +import org.apache.geronimo.security.realm.providers.PasswordCallbackHandle= r; import org.mortbay.http.HttpRequest; import org.mortbay.http.UserRealm; =20 @@ -66,16 +70,22 @@ userMap.remove(username); } =20 - - char[] password; + ClearableCallbackHandler callbackHandler; if (credentials instanceof char[]) { - password =3D (char[]) credentials; + char[] password =3D (char[]) credentials; + callbackHandler =3D new PasswordCallbackHandler(username, = password); } else if (credentials instanceof String) { - password =3D ((String) credentials).toCharArray(); + char[] password =3D ((String) credentials).toCharArray(); + callbackHandler =3D new PasswordCallbackHandler(username, = password); + } else if (credentials instanceof X509Certificate[]) { + X509Certificate[] certs =3D (X509Certificate[]) credential= s; + if (certs.length < 1) { + throw new LoginException("no certificates supplied"); + } + callbackHandler =3D new CertificateCallbackHandler(certs[0= ]); } else { throw new LoginException("Cannot extract credentials from = class: " + credentials.getClass().getName()); } - PasswordCallbackHandler callbackHandler =3D new PasswordCallba= ckHandler(username, password); =20 //set up the login context LoginContext loginContext =3D new LoginContext(loginDomainName= , callbackHandler); @@ -93,7 +103,7 @@ =20 return userPrincipal; } catch (LoginException e) { - log.warn(e); + log.info("problem", e); return null; } } Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/J= ettyContainerImpl.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/or= g/apache/geronimo/jetty/JettyContainerImpl.java?rev=3D170494&r1=3D170493&r2= =3D170494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyCo= ntainerImpl.java (original) +++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyCo= ntainerImpl.java Mon May 16 17:28:28 2005 @@ -132,8 +132,8 @@ server.removeRealm(realm.getName()); } =20 - public void addWebService(String contextPath, WebServiceContainer webS= erviceContainer) throws Exception { - JettyEJBWebServiceContext webServiceContext =3D new JettyEJBWebSer= viceContext(contextPath, webServiceContainer); + public void addWebService(String contextPath, WebServiceContainer webS= erviceContainer, String securityRealmName, String realmName, String transpo= rtGuarantee, String authMethod, ClassLoader classLoader) throws Exception { + JettyEJBWebServiceContext webServiceContext =3D new JettyEJBWebSer= viceContext(contextPath, webServiceContainer, securityRealmName, realmName,= transportGuarantee, authMethod, classLoader); addContext(webServiceContext); webServiceContext.start(); webServices.put(contextPath, webServiceContext); Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/J= ettyEJBWebServiceContext.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/or= g/apache/geronimo/jetty/JettyEJBWebServiceContext.java?rev=3D170494&r1=3D17= 0493&r2=3D170494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJ= BWebServiceContext.java (original) +++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyEJ= BWebServiceContext.java Mon May 16 17:28:28 2005 @@ -25,31 +25,36 @@ import java.util.Map; =20 import org.apache.geronimo.webservices.WebServiceContainer; +import org.mortbay.http.Authenticator; +import org.mortbay.http.BasicAuthenticator; +import org.mortbay.http.ClientCertAuthenticator; +import org.mortbay.http.DigestAuthenticator; import org.mortbay.http.HttpContext; import org.mortbay.http.HttpException; import org.mortbay.http.HttpHandler; import org.mortbay.http.HttpRequest; import org.mortbay.http.HttpResponse; +import org.mortbay.http.UserRealm; =20 /** * Delegates requests to a WebServiceContainer which is presumably for an = EJB WebService. - * + *

* WebServiceContainer delegates to an EJBContainer that will ultimately p= rovide the JNDI, * TX, and Security services for this web service. - * + *

* Nothing stopping us from using this for POJOs or other types of webserv= ices if shared * Context (JNDI, tx, security) wasn't required to be supplied by the web = context. - * + *

* From a 10,000 foot view the Jetty architecture has: * Container -> Context -> Holder -> Servlet - * + *

* A Container has multiple Contexts, typically webapps * A Context provides the JNDI, TX, and Security for the webapp and has ma= ny Holders * A Holder simply wraps each Servlet - * + *

* The POJO Web Service architecture on Jetty looks like this: * Container -> WebApp Context -> JettyPOJOWebServiceHolder -> POJOWebServ= iceServlet - * + *

* The EJB Web Service architecure, on the other hand, creates one Context= for each EJB: * Container -> JettyEJBWebServiceContext * @@ -59,12 +64,51 @@ =20 private final String contextPath; private final WebServiceContainer webServiceContainer; + private final Authenticator authenticator; + private final UserRealm realm; + private final boolean isConfidentialTransportGuarantee; + private final boolean isIntegralTransportGuarantee; + private final ClassLoader classLoader; =20 private HttpContext httpContext; =20 - public JettyEJBWebServiceContext(String contextPath, WebServiceContain= er webServiceContainer) { + public JettyEJBWebServiceContext(String contextPath, WebServiceContain= er webServiceContainer, String securityRealmName, String realmName, String = transportGuarantee, String authMethod, ClassLoader classLoader) { this.contextPath =3D contextPath; this.webServiceContainer =3D webServiceContainer; + if (securityRealmName !=3D null) { + JAASJettyRealm realm =3D new JAASJettyRealm(realmName, securit= yRealmName); + setRealm(realm); + this.realm =3D realm; + if ("NONE".equals(transportGuarantee)) { + isConfidentialTransportGuarantee =3D false; + isIntegralTransportGuarantee =3D false; + } else if ("INTEGRAL".equals(transportGuarantee)) { + isConfidentialTransportGuarantee =3D false; + isIntegralTransportGuarantee =3D true; + } else if ("CONFIDENTIAL".equals(transportGuarantee)) { + isConfidentialTransportGuarantee =3D true; + isIntegralTransportGuarantee =3D false; + } else { + throw new IllegalArgumentException("Invalid transport-guar= antee: " + transportGuarantee); + } + if ("BASIC".equals(authMethod)) { + authenticator =3D new BasicAuthenticator(); + } else if ("DIGEST".equals(authMethod)) { + authenticator =3D new DigestAuthenticator(); + } else if ("CLIENT-CERT".equals(authMethod)) { + authenticator =3D new ClientCertAuthenticator(); + } else if ("NONE".equals(authMethod)) { + authenticator =3D null; + } else { + throw new IllegalArgumentException("Invalid authMethod: " = + authMethod); + } + } else { + realm =3D null; + authenticator =3D null; + isConfidentialTransportGuarantee =3D false; + isIntegralTransportGuarantee =3D false; + } + this.classLoader =3D classLoader; } =20 public String getName() { @@ -84,26 +128,49 @@ req.setContentType("text/xml"); RequestAdapter request =3D new RequestAdapter(req); ResponseAdapter response =3D new ResponseAdapter(res); - =20 + if (req.getParameter("wsdl") !=3D null) { try { - webServiceContainer.getWsdl(request,response); + webServiceContainer.getWsdl(request, response); + //WHO IS RESPONSIBLE FOR CLOSING OUT? } catch (IOException e) { throw e; } catch (Exception e) { throw (HttpException) new HttpException(500, "Could not fe= tch wsdl!").initCause(e); } } else { + if (isConfidentialTransportGuarantee) { + if (!req.isConfidential()) { + throw new HttpException(403); + } + } else if (isIntegralTransportGuarantee) { + if (!req.isIntegral()) { + throw new HttpException(403); + } + } + Thread currentThread =3D Thread.currentThread(); + ClassLoader oldClassLoader =3D currentThread.getContextClassLo= ader(); + currentThread.setContextClassLoader(classLoader); try { - webServiceContainer.invoke(request,response); - req.setHandled(true); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw (HttpException) new HttpException(500, "Could not pr= ocess message!").initCause(e); + if (authenticator !=3D null) { + String pathInContext =3D org.mortbay.util.URI.canonica= lPath(req.getPath()); + if (authenticator.authenticate(realm, pathInContext, r= eq, res) =3D=3D null) { + throw new HttpException(403); + } + } + try { + webServiceContainer.invoke(request, response); + req.setHandled(true); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw (HttpException) new HttpException(500, "Could no= t process message!").initCause(e); + } + } finally { + currentThread.setContextClassLoader(oldClassLoader); } } - =20 + } =20 public String getContextPath() { @@ -123,9 +190,9 @@ } =20 public java.net.URI getURI() { - if( uri=3D=3Dnull ) { + if (uri =3D=3D null) { try { - String uriString =3D request.getScheme()+"://"+reques= t=2EgetHost()+":"+request.getPort()+request.getURI(); + String uriString =3D request.getScheme() + "://" + req= uest.getHost() + ":" + request.getPort() + request.getURI(); //return new java.net.URI(uri.getScheme(),uri.getHost(= ),uri.getPath(),uri.); uri =3D new java.net.URI(uriString); } catch (URISyntaxException e) { @@ -149,7 +216,7 @@ =20 public int getMethod() { Integer method =3D (Integer) methods.get(request.getMethod()); - return method =3D=3D null ? UNSUPPORTED: method.intValue(); + return method =3D=3D null ? UNSUPPORTED : method.intValue(); } =20 public String getParameter(String name) { @@ -164,7 +231,7 @@ return request.getAttribute(name); } =20 - public void setAttribute(String name, Object value){ + public void setAttribute(String name, Object value) { request.setAttribute(name, value); } =20 Modified: geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/C= ontainerTest.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/test/or= g/apache/geronimo/jetty/ContainerTest.java?rev=3D170494&r1=3D170493&r2=3D17= 0494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/Contain= erTest.java (original) +++ geronimo/trunk/modules/jetty/src/test/org/apache/geronimo/jetty/Contain= erTest.java Mon May 16 17:28:28 2005 @@ -79,7 +79,7 @@ =20 String contextPath =3D "/foo/webservice.ws"; MockWebServiceContainer webServiceInvoker =3D new MockWebServiceCo= ntainer(); - kernel.invoke(containerName, "addWebService", new Object[] {contex= tPath, webServiceInvoker}, new String[] {String.class.getName(), WebService= Container.class.getName()}); + kernel.invoke(containerName, "addWebService", new Object[] {contex= tPath, webServiceInvoker, null, null, null, null,cl}, new String[] {String.= class.getName(), WebServiceContainer.class.getName(), String.class.getName(= ), String.class.getName(), String.class.getName(), String.class.getName(), = ClassLoader.class.getName()}); =20 HttpURLConnection connection =3D (HttpURLConnection) new URL("http= ://localhost:5678" + contextPath).openConnection(); try { Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/securit= y/realm/providers/CertificateCallback.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java= /org/apache/geronimo/security/realm/providers/CertificateCallback.java?rev= =3D170494&view=3Dauto =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificateCallback.java (added) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificateCallback.java Mon May 16 17:28:28 2005 @@ -0,0 +1,35 @@ +/** + * + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implie= d=2E + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.security.realm.providers; + +import java.security.cert.X509Certificate; +import javax.security.auth.callback.Callback; + +/** + * @version $Rev: $ $Date: $ + */ +public class CertificateCallback implements Callback { + X509Certificate certificate; + + public X509Certificate getCertificate() { + return certificate; + } + + public void setCertificate(X509Certificate certificate) { + this.certificate =3D certificate; + } +} Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/securit= y/realm/providers/CertificateCallbackHandler.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java= /org/apache/geronimo/security/realm/providers/CertificateCallbackHandler.ja= va?rev=3D170494&view=3Dauto =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificateCallbackHandler.java (added) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificateCallbackHandler.java Mon May 16 17:28:28 2005 @@ -0,0 +1,48 @@ +/** + * + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implie= d=2E + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.security.realm.providers; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.UnsupportedCallbackException; + +/** + * @version $Rev: $ $Date: $ + */ +public class CertificateCallbackHandler implements ClearableCallbackHandle= r { + X509Certificate certificate; + public CertificateCallbackHandler(X509Certificate certificate) { + this.certificate =3D certificate; + } + + public void handle(Callback[] callbacks) throws IOException, Unsupport= edCallbackException { + for (int i =3D 0; i < callbacks.length; i++) { + Callback callback =3D callbacks[i]; + if (callback instanceof CertificateCallback) { + CertificateCallback cc =3D (CertificateCallback) callback; + cc.setCertificate(certificate); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + + public void clear() { + certificate =3D null; + } +} Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/securit= y/realm/providers/CertificatePropertiesFileLoginModule.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java= /org/apache/geronimo/security/realm/providers/CertificatePropertiesFileLogi= nModule.java?rev=3D170494&view=3Dauto =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificatePropertiesFileLoginModule.java (added) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/CertificatePropertiesFileLoginModule.java Mon May 16 17:28:2= 8 2005 @@ -0,0 +1,216 @@ +/** + * + * Copyright 2003-2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implie= d=2E + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.geronimo.security.realm.providers; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.security.cert.X509Certificate; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.Collection; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; +import javax.security.auth.x500.X500Principal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.common.GeronimoSecurityException; +import org.apache.geronimo.kernel.Kernel; +import org.apache.geronimo.kernel.KernelRegistry; +import org.apache.geronimo.security.jaas.JaasLoginModuleUse; +import org.apache.geronimo.system.serverinfo.ServerInfo; + + +/** + * An example LoginModule that reads a list of users and group from a file= on disk. + * Authentication is provided by the SSL layer supplying the client certif= icate. + * All we check is that it is present. The + * file should be formatted using standard Java properties syntax. Expects + * to be run by a GenericSecurityRealm (doesn't work on its own). + * + * The usersURI property file should have lines of the form token=3Dcertif= icatename + * where certificate name is X509Certificate.getSubjectX500Principal().get= Name() + * + * The groupsURI property file should have lines of the form group=3Dtoken= 1,token2,... + * where the tokens were associated to the certificate names in the usersU= RI properties file. + * + * @version $Rev: 169154 $ $Date: 2005-05-08 12:35:23 -0700 (Sun, 08 May 2= 005) $ + */ +public class CertificatePropertiesFileLoginModule implements LoginModule { + public final static String USERS_URI =3D "usersURI"; + public final static String GROUPS_URI =3D "groupsURI"; + private static Log log =3D LogFactory.getLog(CertificatePropertiesFile= LoginModule.class); + private final Map users =3D new HashMap(); + final Map groups =3D new HashMap(); + + Subject subject; + CallbackHandler handler; + X500Principal principal; + + public void initialize(Subject subject, CallbackHandler callbackHandle= r, Map sharedState, Map options) { + this.subject =3D subject; + this.handler =3D callbackHandler; + try { + Kernel kernel =3D KernelRegistry.getKernel((String)options.get= (JaasLoginModuleUse.KERNEL_LM_OPTION)); + ServerInfo serverInfo =3D (ServerInfo) options.get(JaasLoginMo= duleUse.SERVERINFO_LM_OPTION); + URI usersURI =3D new URI((String)options.get(USERS_URI)); + URI groupsURI =3D new URI((String)options.get(GROUPS_URI)); + loadProperties(kernel, serverInfo, usersURI, groupsURI); + } catch (Exception e) { + log.error(e); + throw new IllegalArgumentException("Unable to configure proper= ties file login module: "+e); + } + } + + public void loadProperties(Kernel kernel, ServerInfo serverInfo, URI u= sersURI, URI groupURI) throws GeronimoSecurityException { + try { + URI userFile =3D serverInfo.resolve(usersURI); + URI groupFile =3D serverInfo.resolve(groupURI); + InputStream stream =3D userFile.toURL().openStream(); + Properties tmpUsers =3D new Properties(); + tmpUsers.load(stream); + stream.close(); + + for (Iterator iterator =3D tmpUsers.entrySet().iterator(); ite= rator.hasNext();) { + Map.Entry entry =3D (Map.Entry) iterator.next(); + users.put(entry.getValue(), entry.getKey()); + } + + Properties temp =3D new Properties(); + stream =3D groupFile.toURL().openStream(); + temp.load(stream); + stream.close(); + + Enumeration e =3D temp.keys(); + while (e.hasMoreElements()) { + String groupName =3D (String) e.nextElement(); + String[] userList =3D ((String) temp.get(groupName)).split= (","); + + Set userset =3D (Set) groups.get(groupName); + if (userset =3D=3D null) { + userset =3D new HashSet(); + groups.put(groupName, userset); + } + + for (int i =3D 0; i < userList.length; i++) { + String userName =3D userList[i]; + userset.add(userName); + } + } + + } catch (Exception e) { + log.error("Properties File Login Module - data load failed", e= ); + throw new GeronimoSecurityException(e); + } + } + + + public boolean login() throws LoginException { + Callback[] callbacks =3D new Callback[1]; + + callbacks[0] =3D new CertificateCallback(); + try { + handler.handle(callbacks); + } catch (IOException ioe) { + throw (LoginException) new LoginException().initCause(ioe); + } catch (UnsupportedCallbackException uce) { + throw (LoginException) new LoginException().initCause(uce); + } + assert callbacks.length =3D=3D 1; + X509Certificate certificate =3D ((CertificateCallback)callbacks[0]= )=2EgetCertificate(); + if (certificate =3D=3D null) { + return false; + } + principal =3D certificate.getSubjectX500Principal(); + + return users.containsKey(principal.getName()); + } + + public boolean commit() throws LoginException { + Set principals =3D subject.getPrincipals(); + + principals.add(principal); + String userName =3D (String) users.get(principal.getName()); + principals.add(new GeronimoUserPrincipal(userName)); + + Iterator e =3D groups.keySet().iterator(); + while (e.hasNext()) { + String groupName =3D (String) e.next(); + Set users =3D (Set) groups.get(groupName); + Iterator iter =3D users.iterator(); + while (iter.hasNext()) { + String user =3D (String) iter.next(); + if (userName.equals(user)) { + principals.add(new GeronimoGroupPrincipal(groupName)); + break; + } + } + } + + return true; + } + + public boolean abort() throws LoginException { + principal =3D null; + + return true; + } + + public boolean logout() throws LoginException { + principal =3D null; + + return true; + } + + /** + * Gets the names of all principal classes that may be populated into + * a Subject. + */ + public String[] getPrincipalClassNames() { + return new String[]{GeronimoUserPrincipal.class.getName(), Geronim= oGroupPrincipal.class.getName()}; + } + + /** + * Gets a list of all the principals of a particular type (identified = by + * the principal class). These are available for manual role mapping. + */ + public String[] getPrincipalsOfClass(String className) { + Collection s; + if(className.equals(GeronimoGroupPrincipal.class.getName())) { + s =3D groups.keySet(); + } else if(className.equals(GeronimoUserPrincipal.class.getName()))= { + s =3D users.values(); + } else if(className.equals(X500Principal.class.getName())) { + s =3D users.keySet(); + } else { + throw new IllegalArgumentException("No such principal class "+= className); + } + return (String[]) s.toArray(new String[s.size()]); + } +} Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/securit= y/realm/providers/ClearableCallbackHandler.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java= /org/apache/geronimo/security/realm/providers/ClearableCallbackHandler.java= ?rev=3D170494&view=3Dauto =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/ClearableCallbackHandler.java (added) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/ClearableCallbackHandler.java Mon May 16 17:28:28 2005 @@ -0,0 +1,26 @@ +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implie= d=2E + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.security.realm.providers; + +import javax.security.auth.callback.CallbackHandler; + +/** + * @version $Rev: $ $Date: $ + */ +public interface ClearableCallbackHandler extends CallbackHandler { + void clear(); +} Copied: geronimo/trunk/modules/security/src/java/org/apache/geronimo/securi= ty/realm/providers/PasswordCallbackHandler.java (from r169699, geronimo/tru= nk/modules/jetty/src/java/org/apache/geronimo/jetty/PasswordCallbackHandler= .java) URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java= /org/apache/geronimo/security/realm/providers/PasswordCallbackHandler.java?= p2=3Dgeronimo/trunk/modules/security/src/java/org/apache/geronimo/security/= realm/providers/PasswordCallbackHandler.java&p1=3Dgeronimo/trunk/modules/je= tty/src/java/org/apache/geronimo/jetty/PasswordCallbackHandler.java&r1=3D16= 9699&r2=3D170494&rev=3D170494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/Passwor= dCallbackHandler.java (original) +++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/r= ealm/providers/PasswordCallbackHandler.java Mon May 16 17:28:28 2005 @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.geronimo.jetty; +package org.apache.geronimo.security.realm.providers; =20 import java.util.Arrays; import javax.security.auth.callback.Callback; @@ -26,7 +26,7 @@ /** * @version $Revision$ $Date$ */ -public class PasswordCallbackHandler implements CallbackHandler { +public class PasswordCallbackHandler implements ClearableCallbackHandler { private final String username; private final char[] password; =20 Modified: geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/w= ebservices/SoapHandler.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/webservices/src/j= ava/org/apache/geronimo/webservices/SoapHandler.java?rev=3D170494&r1=3D1704= 93&r2=3D170494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webserv= ices/SoapHandler.java (original) +++ geronimo/trunk/modules/webservices/src/java/org/apache/geronimo/webserv= ices/SoapHandler.java Mon May 16 17:28:28 2005 @@ -21,7 +21,7 @@ */ public interface SoapHandler { =20 - void addWebService(String contextPath, WebServiceContainer webServiceC= ontainer) throws Exception; + void addWebService(String contextPath, WebServiceContainer webServiceC= ontainer, String securityRealmName, String realmName, String transportGuara= ntee, String authMethod, ClassLoader classLoader) throws Exception; =20 void removeWebService(String contextPath); =20