001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.soap.handlers.security;
018    
019    import java.io.IOException;
020    
021    import javax.security.auth.callback.Callback;
022    import javax.security.auth.callback.CallbackHandler;
023    import javax.security.auth.callback.UnsupportedCallbackException;
024    
025    import org.apache.ws.security.WSPasswordCallback;
026    
027    /**
028     * Base implementation for security callback handler.
029     * 
030     * @author gnodet
031     */
032    public class BaseSecurityCallbackHandler implements CallbackHandler {
033        
034        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
035            if (callbacks == null || callbacks.length == 0) {
036                throw new IllegalStateException("callbacks is null or empty");
037            }
038            for (int i = 0; i < callbacks.length; i++) {
039                if (callbacks[i] instanceof WSPasswordCallback == false) {
040                    throw new UnsupportedCallbackException(callbacks[i]);
041                }
042                processCallback((WSPasswordCallback) callbacks[i]);
043            }
044        } 
045        
046        protected void processCallback(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
047            switch (callback.getUsage()) {
048            case WSPasswordCallback.DECRYPT:
049                processDecrypt(callback);
050                break;
051            case WSPasswordCallback.USERNAME_TOKEN:
052                processUsernameToken(callback);
053                break;
054            case WSPasswordCallback.SIGNATURE:
055                processSignature(callback);
056                break;
057            case WSPasswordCallback.KEY_NAME:
058                processKeyName(callback);
059                break;
060            case WSPasswordCallback.USERNAME_TOKEN_UNKNOWN:
061                processUsernameTokenUnkown(callback);
062                break;
063            default:
064                throw new UnsupportedCallbackException(callback);
065            }
066        }
067    
068        /**
069         * Need a password to get the private key of
070         * this identifier (username) from    the keystore. WSS4J uses this private
071         * key to decrypt the session (symmetric) key. Because the encryption
072         * method uses the public key to encrypt the session key it needs no
073         * password (a public key is usually not protected by a password)
074         */
075        protected void processDecrypt(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
076            throw new UnsupportedCallbackException(callback);
077        }
078        
079        /** 
080         * Need the password to fill in or to
081         * verify a <code>UsernameToken</code>
082         */
083        protected void processUsernameToken(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
084            throw new UnsupportedCallbackException(callback);
085        }
086        
087        /**
088         * Need the password to get the private key of
089         * this identifier (username) from    the keystore. WSS4J uses this private
090         * key to produce a signature. The signature verfication uses the public
091         * key to verfiy the signature
092         */
093        protected void processSignature(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
094            throw new UnsupportedCallbackException(callback);
095        }
096        
097        /**
098         * Need the <i>key</i>, not the password,
099         * associated with the identifier. WSS4J uses this key to encrypt or
100         * decrypt parts of the SOAP request. Note, the key must match the
101         * symmetric encryption/decryption algorithm specified (refer to
102         * {@link org.apache.ws.security.handler.WSHandlerConstants#ENC_SYM_ALGO})
103         */
104        protected void processKeyName(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
105            throw new UnsupportedCallbackException(callback);
106        }
107        
108        /**
109         * Either a not specified 
110         * password type or a password type passwordText. In these both cases <b>only</b>
111         * the password variable is <b>set</>. The callback class now may check if
112         * the username and password match. If they don't match the callback class must
113         * throw an exception. The exception can be a UnsupportedCallbackException or
114         * an IOException.</li>
115         */
116        protected void processUsernameTokenUnkown(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
117            throw new UnsupportedCallbackException(callback);
118        }
119        
120    }