001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.server.security.auth.sasl;
022
023 import java.io.IOException;
024 import java.security.Principal;
025 import java.util.Map;
026
027 import javax.security.auth.callback.Callback;
028 import javax.security.auth.callback.CallbackHandler;
029 import javax.security.auth.callback.NameCallback;
030 import javax.security.auth.callback.PasswordCallback;
031 import javax.security.auth.callback.UnsupportedCallbackException;
032 import javax.security.auth.login.AccountNotFoundException;
033 import javax.security.sasl.AuthorizeCallback;
034
035 import org.apache.commons.configuration.Configuration;
036
037 import org.apache.log4j.Logger;
038
039 import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
040 import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
041 import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
042
043 public abstract class UsernamePasswordInitialiser implements AuthenticationProviderInitialiser
044 {
045 protected static final Logger _logger = Logger.getLogger(UsernamePasswordInitialiser.class);
046
047 private ServerCallbackHandler _callbackHandler;
048
049 private class ServerCallbackHandler implements CallbackHandler
050 {
051 private final PrincipalDatabase _principalDatabase;
052
053 protected ServerCallbackHandler(PrincipalDatabase database)
054 {
055 _principalDatabase = database;
056 }
057
058 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
059 {
060 Principal username = null;
061 for (Callback callback : callbacks)
062 {
063 if (callback instanceof NameCallback)
064 {
065 username = new UsernamePrincipal(((NameCallback) callback).getDefaultName());
066 }
067 else if (callback instanceof PasswordCallback)
068 {
069 try
070 {
071 _principalDatabase.setPassword(username, (PasswordCallback) callback);
072 }
073 catch (AccountNotFoundException e)
074 {
075 // very annoyingly the callback handler does not throw anything more appropriate than
076 // IOException
077 IOException ioe = new IOException("Error looking up user " + e);
078 ioe.initCause(e);
079 throw ioe;
080 }
081 }
082 else if (callback instanceof AuthorizeCallback)
083 {
084 ((AuthorizeCallback) callback).setAuthorized(true);
085 }
086 else
087 {
088 throw new UnsupportedCallbackException(callback);
089 }
090 }
091 }
092 }
093
094 public void initialise(String baseConfigPath, Configuration configuration,
095 Map<String, PrincipalDatabase> principalDatabases) throws Exception
096 {
097 String principalDatabaseName = configuration.getString(baseConfigPath + ".principal-database");
098 PrincipalDatabase db = principalDatabases.get(principalDatabaseName);
099
100 initialise(db);
101 }
102
103 public void initialise(PrincipalDatabase db)
104 {
105 if (db == null)
106 {
107 throw new NullPointerException("Cannot initialise with a null Principal database.");
108 }
109
110 _callbackHandler = new ServerCallbackHandler(db);
111 }
112
113 public CallbackHandler getCallbackHandler()
114 {
115 return _callbackHandler;
116 }
117
118 public Map<String, ?> getProperties()
119 {
120 // there are no properties required for the CRAM-MD5 implementation
121 return null;
122 }
123 }
|