1 17 18 package org.apache.geronimo.console.core.security; 19 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.net.URI ; 23 import java.security.MessageDigest ; 24 import java.security.NoSuchAlgorithmException ; 25 import java.util.Enumeration ; 26 import java.util.HashMap ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 import java.util.Properties ; 31 import java.util.Set ; 32 33 import javax.security.auth.Subject ; 34 import javax.security.auth.callback.Callback ; 35 import javax.security.auth.callback.CallbackHandler ; 36 import javax.security.auth.callback.NameCallback ; 37 import javax.security.auth.callback.PasswordCallback ; 38 import javax.security.auth.callback.UnsupportedCallbackException ; 39 import javax.security.auth.login.LoginException ; 40 import javax.security.auth.spi.LoginModule ; 41 42 import org.apache.commons.logging.Log; 43 import org.apache.commons.logging.LogFactory; 44 import org.apache.geronimo.common.GeronimoSecurityException; 45 import org.apache.geronimo.kernel.Kernel; 46 import org.apache.geronimo.kernel.KernelRegistry; 47 import org.apache.geronimo.security.jaas.JaasLoginModuleUse; 48 import org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal; 49 import org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal; 50 import org.apache.geronimo.system.serverinfo.ServerInfo; 51 import org.apache.geronimo.util.encoders.HexTranslator; 52 53 56 public class PropertiesFileLoginModuleNoCache implements LoginModule { 57 58 Kernel kernel; 59 60 ServerInfo serverInfo; 61 62 URI usersURI; 63 64 URI groupsURI; 65 66 public final static String USERS_URI = "usersURI"; 67 68 public final static String GROUPS_URI = "groupsURI"; 69 70 public final static String DIGEST = "digest"; 71 72 private static Log log = LogFactory 73 .getLog(PropertiesFileLoginModuleNoCache.class); 74 75 final Properties users = new Properties (); 76 77 final Map groups = new HashMap (); 78 79 private String digest; 80 81 Subject subject; 82 83 CallbackHandler handler; 84 85 String username; 86 87 String password; 88 89 public void initialize(Subject subject, CallbackHandler callbackHandler, 90 Map sharedState, Map options) { 91 this.subject = subject; 92 this.handler = callbackHandler; 93 try { 94 kernel = KernelRegistry.getKernel((String ) options 95 .get(JaasLoginModuleUse.KERNEL_NAME_LM_OPTION)); 96 serverInfo = (ServerInfo) options 97 .get(JaasLoginModuleUse.SERVERINFO_LM_OPTION); 98 usersURI = new URI ((String ) options.get(USERS_URI)); 99 groupsURI = new URI ((String ) options.get(GROUPS_URI)); 100 digest = (String ) options.get(DIGEST); 101 if(digest != null && !digest.equals("")) { 102 try { 104 MessageDigest.getInstance(digest); 105 } catch(NoSuchAlgorithmException e) { 106 log.error("Initialization failed. Digest algorithm "+digest+" is not available.", e); 107 throw new IllegalArgumentException ("Unable to configure properties file login module: "+e.getMessage()); 108 } 109 } 110 } catch (Exception e) { 111 log.error(e); 112 throw new IllegalArgumentException ( 113 "Unable to configure properties file login module: " + e); 114 } 115 } 116 117 public void loadProperties(Kernel kernel, ServerInfo serverInfo, 118 URI userURI, URI groupURI) throws GeronimoSecurityException { 119 try { 120 URI userFile = serverInfo.resolve(userURI); 121 URI groupFile = serverInfo.resolve(groupURI); 122 InputStream stream = userFile.toURL().openStream(); 123 users.clear(); 125 users.load(stream); 126 stream.close(); 127 128 Properties temp = new Properties (); 129 stream = groupFile.toURL().openStream(); 130 temp.load(stream); 131 stream.close(); 132 groups.clear(); 134 Enumeration e = temp.keys(); 135 while (e.hasMoreElements()) { 136 String groupName = (String ) e.nextElement(); 137 String [] userList = ((String ) temp.get(groupName)).split(","); 138 139 Set userset = (Set ) groups.get(groupName); 140 if (userset == null) { 141 userset = new HashSet (); 142 groups.put(groupName, userset); 143 } 144 145 for (int i = 0; i < userList.length; i++) { 146 userset.add(userList[i]); 147 } 148 } 149 150 } catch (Exception e) { 151 log.error("Properties File Login Module - data load failed", e); 152 throw new GeronimoSecurityException(e); 153 } 154 } 155 156 public boolean login() throws LoginException { 157 loadProperties(kernel, serverInfo, usersURI, groupsURI); 160 161 Callback [] callbacks = new Callback [2]; 162 163 callbacks[0] = new NameCallback ("User name"); 164 callbacks[1] = new PasswordCallback ("Password", false); 165 try { 166 handler.handle(callbacks); 167 } catch (IOException ioe) { 168 throw (LoginException ) new LoginException ().initCause(ioe); 169 } catch (UnsupportedCallbackException uce) { 170 throw (LoginException ) new LoginException ().initCause(uce); 171 } 172 assert callbacks.length == 2; 173 username = ((NameCallback ) callbacks[0]).getName(); 174 if (username == null || username.equals("")) { 175 return false; 176 } 177 password = users.getProperty(username); 178 179 return checkPassword(password, new String ((((PasswordCallback ) callbacks[1]).getPassword()))); 180 } 181 182 public boolean commit() throws LoginException { 183 Set principals = subject.getPrincipals(); 184 185 principals.add(new GeronimoUserPrincipal(username)); 186 187 Iterator e = groups.keySet().iterator(); 188 while (e.hasNext()) { 189 String groupName = (String ) e.next(); 190 Set users = (Set ) groups.get(groupName); 191 Iterator iter = users.iterator(); 192 while (iter.hasNext()) { 193 String user = (String ) iter.next(); 194 if (username.equals(user)) { 195 principals.add(new GeronimoGroupPrincipal(groupName)); 196 break; 197 } 198 } 199 } 200 201 return true; 202 } 203 204 public boolean abort() throws LoginException { 205 username = null; 206 password = null; 207 208 return true; 209 } 210 211 public boolean logout() throws LoginException { 212 username = null; 213 password = null; 214 215 return true; 216 } 217 218 222 public String [] getPrincipalClassNames() { 223 return new String [] { GeronimoUserPrincipal.class.getName(), 224 GeronimoGroupPrincipal.class.getName() }; 225 } 226 227 231 public String [] getPrincipalsOfClass(String className) { 232 Set s; 233 if (className.equals(GeronimoGroupPrincipal.class.getName())) { 234 s = groups.keySet(); 235 } else if (className.equals(GeronimoUserPrincipal.class.getName())) { 236 s = users.keySet(); 237 } else { 238 throw new IllegalArgumentException ("No such principal class " 239 + className); 240 } 241 return (String []) s.toArray(new String [s.size()]); 242 } 243 244 250 private boolean checkPassword(String real, String provided){ 251 if(digest == null || digest.equals("")) { 252 return real.equals(provided); 254 } 255 try { 256 MessageDigest md = MessageDigest.getInstance(digest); 258 byte[] data = md.digest(provided.getBytes()); 259 byte[] hexData = new byte[data.length * 2]; 261 HexTranslator ht = new HexTranslator(); 262 ht.encode(data, 0, data.length, hexData, 0); 263 return real.equalsIgnoreCase(new String (hexData)); 265 } catch (NoSuchAlgorithmException e) { 266 log.error("Should not occur. Availability of algorithm has been checked at initialization.", e); 268 } 269 return false; 270 } 271 } 272 | Popular Tags |