001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins;
023:
024: import java.security.Principal;
025: import javax.net.ssl.SSLSession;
026: import javax.net.ssl.SSLPeerUnverifiedException;
027: import java.security.cert.X509Certificate;
028: import org.jboss.invocation.Invocation;
029:
030: import org.jboss.security.ssl.DomainServerSocketFactory;
031: import org.jboss.security.CertificatePrincipal;
032: import org.jboss.security.auth.certs.SubjectDNMapping;
033:
034: /**
035: * An interceptor that looks for the peer certificates from the SSLSession
036: * associated with the sessionIDKey(defaults to SESSION_ID) of the invocation.
037: *
038: * @see org.jboss.security.ssl.DomainServerSocketFactory
039: *
040: * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
041: * @version $Revision: 57209 $
042: */
043: public class SSLSessionInterceptor extends AbstractInterceptor {
044: /** The certificate to principal mapping interface */
045: private CertificatePrincipal cpMapping = new SubjectDNMapping();
046: /** The name of the invocation key with the session id */
047: private String sessionIDKey = "SESSION_ID";
048:
049: public Object invokeHome(Invocation mi) throws Exception {
050: extractSessionPrincipal(mi);
051: Object returnValue = getNext().invoke(mi);
052: return returnValue;
053: }
054:
055: public CertificatePrincipal getPrincialMapping() {
056: return cpMapping;
057: }
058:
059: public void setPrincialMapping(CertificatePrincipal cpMapping) {
060: this .cpMapping = cpMapping;
061: }
062:
063: public String getSessionIDKey() {
064: return sessionIDKey;
065: }
066:
067: public void setSessionIDKey(String sessionIDKey) {
068: this .sessionIDKey = sessionIDKey;
069: }
070:
071: public Object invoke(Invocation mi) throws Exception {
072: extractSessionPrincipal(mi);
073: Object returnValue = getNext().invoke(mi);
074: return returnValue;
075: }
076:
077: /**
078: * Look for the session id in the invocation and if there is an associated
079: * session in DomainServerSocketFactory, use the client cert as the
080: * credential, and the cert principal mapping as the principal.
081: *
082: * @param mi - the method invocation
083: * @throws SSLPeerUnverifiedException
084: */
085: private void extractSessionPrincipal(Invocation mi)
086: throws SSLPeerUnverifiedException {
087: String sessionID = (String) mi.getValue(sessionIDKey);
088: if (sessionID != null) {
089: SSLSession session = DomainServerSocketFactory
090: .getSSLSession(sessionID);
091: if (session != null) {
092: X509Certificate[] certs = (X509Certificate[]) session
093: .getPeerCertificates();
094: Principal caller = cpMapping.toPrinicipal(certs);
095: mi.setPrincipal(caller);
096: mi.setCredential(certs);
097: }
098: }
099: }
100: }
|