UsernamePasswordInitialiser.java
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[] callbacksthrows IOException, UnsupportedCallbackException
059         {
060             Principal username = null;
061             for (Callback callback : callbacks)
062             {
063                 if (callback instanceof NameCallback)
064                 {
065                     username = new UsernamePrincipal(((NameCallbackcallback).getDefaultName());
066                 }
067                 else if (callback instanceof PasswordCallback)
068                 {
069                     try
070                     {
071                         _principalDatabase.setPassword(username, (PasswordCallbackcallback);
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                     ((AuthorizeCallbackcallback).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> principalDatabasesthrows 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 }