PropertiesPrincipalDatabase.java
001 /*
002  *  Licensed to the Apache Software Foundation (ASF) under one
003  *  or more contributor license agreements.  See the NOTICE file
004  *  distributed with this work for additional information
005  *  regarding copyright ownership.  The ASF licenses this file
006  *  to you under the Apache License, Version 2.0 (the
007  *  "License"); you may not use this file except in compliance
008  *  with the License.  You may obtain a copy of the License at
009  *
010  *    http://www.apache.org/licenses/LICENSE-2.0
011  *
012  *  Unless required by applicable law or agreed to in writing,
013  *  software distributed under the License is distributed on an
014  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015  *  KIND, either express or implied.  See the License for the
016  *  specific language governing permissions and limitations
017  *  under the License.    
018  *
019  
020  */
021 package org.apache.qpid.server.security.auth.database;
022 
023 import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
024 import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
025 import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
026 import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
027 
028 import javax.security.auth.callback.PasswordCallback;
029 import javax.security.auth.login.AccountNotFoundException;
030 import java.util.Properties;
031 import java.util.Map;
032 import java.util.HashMap;
033 import java.util.List;
034 import java.util.LinkedList;
035 import java.security.Principal;
036 import java.io.IOException;
037 import java.io.UnsupportedEncodingException;
038 
039 public class PropertiesPrincipalDatabase implements PrincipalDatabase
040 {
041     private Properties _users;
042 
043     private Map<String, AuthenticationProviderInitialiser> _saslServers;
044 
045     public PropertiesPrincipalDatabase(Properties users)
046     {
047         _users = users;
048 
049         _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
050 
051         /**
052          *  Create Authenticators for Properties Principal Database.
053          */
054 
055         //  Accept MD5 incomming and use plain comparison with the file
056         PlainInitialiser cram = new PlainInitialiser();
057         cram.initialise(this);
058         // Accept Plain incomming and hash it for comparison to the file.
059         CRAMMD5Initialiser plain = new CRAMMD5Initialiser();
060         plain.initialise(this, CRAMMD5Initialiser.HashDirection.INCOMMING);
061 
062         _saslServers.put(plain.getMechanismName(), cram);
063         _saslServers.put(cram.getMechanismName(), plain);
064     }
065 
066     public void setPassword(Principal principal, PasswordCallback callbackthrows IOException, AccountNotFoundException
067     {
068         if (principal == null)
069         {
070             throw new IllegalArgumentException("principal must not be null");
071         }
072 
073 
074 
075         final String pwd = _users.getProperty(principal.getName());
076 
077         if (pwd != null)
078         {
079             callback.setPassword(pwd.toCharArray());
080         }
081         else
082         {
083             throw new AccountNotFoundException("No account found for principal " + principal);
084         }
085     }
086 
087     public boolean verifyPassword(String principal, char[] passwordthrows AccountNotFoundException
088     {
089         //fixme this is not correct as toCharArray is not safe based on the type of string.
090         char[] pwd = _users.getProperty(principal).toCharArray();
091 
092         return compareCharArray(pwd, password);
093     }
094 
095     public boolean updatePassword(Principal principal, char[] passwordthrows AccountNotFoundException
096     {
097         return false// updates denied
098     }
099 
100     public boolean createPrincipal(Principal principal, char[] password)
101     {
102         return false// updates denied
103     }
104 
105     public boolean deletePrincipal(Principal principalthrows AccountNotFoundException
106     {
107         return false// updates denied
108     }
109 
110     private boolean compareCharArray(char[] a, char[] b)
111     {
112         boolean equal = false;
113         if (a.length == b.length)
114         {
115             equal = true;
116             int index = 0;
117             while (equal && index < a.length)
118             {
119                 equal = a[index== b[index];
120                 index++;
121             }
122         }
123         return equal;
124     }
125 
126     private char[] convertPassword(String passwordthrows UnsupportedEncodingException
127     {
128         byte[] passwdBytes = password.getBytes("utf-8");
129 
130         char[] passwd = new char[passwdBytes.length];
131 
132         int index = 0;
133 
134         for (byte b : passwdBytes)
135         {
136             passwd[index++(charb;
137         }
138 
139         return passwd;
140     }
141 
142 
143     public Map<String, AuthenticationProviderInitialiser> getMechanisms()
144     {
145         return _saslServers;
146     }
147 
148     public List<Principal> getUsers()
149     {
150         return new LinkedList<Principal>()//todo
151     }
152 
153     public Principal getUser(String username)
154     {
155         if (_users.getProperty(username!= null)
156         {
157             return new UsernamePrincipal(username);
158         }
159         else
160         {
161             return null;
162         }
163     }
164 
165     public void reload() throws IOException
166     {
167         //No file to update from, so do nothing.
168     }
169 }