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 callback) throws 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[] password) throws 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[] password) throws 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 principal) throws 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 password) throws 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++] = (char) b;
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 }
|