1 17 18 package org.apache.geronimo.console.core.security; 19 20 import java.io.File ; 21 import java.io.FileOutputStream ; 22 import java.io.InputStream ; 23 import java.io.IOException ; 24 import java.io.OutputStream ; 25 import java.net.URL ; 26 import java.net.URLConnection ; 27 import java.net.UnknownServiceException ; 28 import java.security.MessageDigest ; 29 import java.security.NoSuchAlgorithmException ; 30 import java.util.Arrays ; 31 import java.util.HashSet ; 32 import java.util.Hashtable ; 33 import java.util.Properties ; 34 import java.util.Set ; 35 36 import org.apache.geronimo.common.GeronimoSecurityException; 37 import org.apache.geronimo.gbean.GBeanInfo; 38 import org.apache.geronimo.gbean.GBeanInfoBuilder; 39 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 40 import org.apache.geronimo.security.jaas.LoginModuleSettings; 41 import org.apache.geronimo.system.serverinfo.ServerInfo; 42 import org.apache.geronimo.util.encoders.HexTranslator; 43 44 47 public class PropertiesLoginModuleManager { 48 49 private ServerInfo serverInfo; 50 51 private LoginModuleSettings loginModule; 52 53 private Properties users = new Properties (); 54 55 private Properties groups = new Properties (); 56 57 private static final String usersKey = "usersURI"; 58 59 private static final String groupsKey = "groupsURI"; 60 61 private static final String digestKey = "digest"; 62 63 public PropertiesLoginModuleManager(ServerInfo serverInfo, LoginModuleSettings loginModule) { 64 this.serverInfo = serverInfo; 65 this.loginModule = loginModule; 66 } 67 68 private void refreshUsers() { 69 users.clear(); 70 InputStream in = null; 71 try { 72 in = serverInfo.resolve(getUsersURI()).toURL().openStream(); 73 users.load(in); 74 } catch (Exception e) { 75 throw new GeronimoSecurityException(e); 76 } finally { 77 if (in != null) { 78 try { 79 in.close(); 80 } catch (IOException ignored) { 81 } 83 } 84 } 85 } 86 87 private void refreshGroups() throws GeronimoSecurityException { 88 groups.clear(); 89 InputStream in = null; 90 try { 91 in = serverInfo.resolve(getGroupsURI()).toURL().openStream(); 92 groups.load(in); 93 } catch (Exception e) { 94 throw new GeronimoSecurityException(e); 95 } finally { 96 if (in != null) { 97 try { 98 in.close(); 99 } catch (IOException ignored) { 100 } 102 } 103 } 104 } 105 106 public String [] getUsers() throws GeronimoSecurityException { 107 users.clear(); 108 InputStream in = null; 109 try { 110 in = serverInfo.resolve(getUsersURI()).toURL().openStream(); 111 users.load(in); 112 } catch (Exception e) { 113 throw new GeronimoSecurityException(e); 114 } finally { 115 if (in != null) { 116 try { 117 in.close(); 118 } catch (IOException ignored) { 119 } 121 } 122 } 123 return (String []) users.keySet().toArray(new String [0]); 124 } 125 126 public String [] getGroups() throws GeronimoSecurityException { 127 groups.clear(); 128 InputStream in = null; 129 try { 130 in = serverInfo.resolve(getGroupsURI()).toURL().openStream(); 131 groups.load(in); 132 } catch (Exception e) { 133 throw new GeronimoSecurityException(e); 134 } finally { 135 if (in != null) { 136 try { 137 in.close(); 138 } catch (IOException ignored) { 139 } 141 } 142 } 143 return (String []) groups.keySet().toArray(new String [0]); 144 } 145 146 public void addUserPrincipal(Hashtable properties) 147 throws GeronimoSecurityException { 148 if (users.getProperty((String ) properties.get("UserName")) != null) { 149 throw new GeronimoSecurityException("User principal " 150 + properties.get("UserName") + " already exists."); 151 } 152 try { 153 refreshUsers(); 154 String digest = getDigest(); 155 String user = (String ) properties.get("UserName"); 156 String password = (String ) properties.get("Password"); 157 if(digest != null && !digest.equals("")) { 158 password = digestPassword(password, digest); 159 } 160 users.setProperty(user, password); 161 store(users, serverInfo.resolve(getUsersURI()).toURL()); 162 } catch (Exception e) { 163 throw new GeronimoSecurityException("Cannot add user principal: " 164 + e.getMessage()); 165 } 166 } 167 168 public void removeUserPrincipal(String userPrincipal) 169 throws GeronimoSecurityException { 170 try { 171 refreshUsers(); 172 users.remove(userPrincipal); 173 store(users, serverInfo.resolve(getUsersURI()).toURL()); 174 } catch (Exception e) { 175 throw new GeronimoSecurityException("Cannot remove user principal " 176 + userPrincipal + ": " + e.getMessage()); 177 } 178 } 179 180 public void updateUserPrincipal(Hashtable properties) 181 throws GeronimoSecurityException { 182 try { 184 refreshUsers(); 185 String digest = getDigest(); 186 String user = (String ) properties.get("UserName"); 187 String password = (String ) properties.get("Password"); 188 if(digest != null && !digest.equals("")) { 189 password = digestPassword(password, digest); 190 } 191 users.setProperty(user, password); 192 store(users, serverInfo.resolve(getUsersURI()).toURL()); 193 } catch (Exception e) { 194 throw new GeronimoSecurityException("Cannot add user principal: " 195 + e.getMessage()); 196 } 197 } 198 199 public void addGroupPrincipal(Hashtable properties) 200 throws GeronimoSecurityException { 201 refreshGroups(); 202 if (groups.getProperty((String ) properties.get("GroupName")) != null) { 203 throw new GeronimoSecurityException("Group " 204 + properties.get("GroupName") + " already exists."); 205 } 206 try { 207 groups.setProperty((String ) properties.get("GroupName"), 208 (String ) properties.get("Members")); 209 store(groups, serverInfo.resolve(getGroupsURI()).toURL()); 210 } catch (Exception e) { 211 throw new GeronimoSecurityException("Cannot add group principal: " 212 + e.getMessage()); 213 } 214 } 215 216 public void removeGroupPrincipal(String groupPrincipal) 217 throws GeronimoSecurityException { 218 refreshGroups(); 219 try { 220 groups.remove(groupPrincipal); 221 store(groups, serverInfo.resolve(getGroupsURI()).toURL()); 222 } catch (Exception e) { 223 throw new GeronimoSecurityException( 224 "Cannot remove group principal: " + e.getMessage()); 225 } 226 } 227 228 public void updateGroupPrincipal(Hashtable properties) 229 throws GeronimoSecurityException { 230 refreshGroups(); 232 try { 233 groups.setProperty((String ) properties.get("GroupName"), 234 (String ) properties.get("Members")); 235 store(groups, serverInfo.resolve(getGroupsURI()).toURL()); 236 } catch (Exception e) { 237 throw new GeronimoSecurityException("Cannot add group principal: " 238 + e.getMessage()); 239 } 240 } 241 242 public void addToGroup(String userPrincipal, String groupPrincipal) 243 throws GeronimoSecurityException { 244 throw new GeronimoSecurityException( 245 "Not implemented for properties file security realm..."); 246 } 247 248 public void removeFromGroup(String userPrincipal, String groupPrincipal) 249 throws GeronimoSecurityException { 250 throw new GeronimoSecurityException( 251 "Not implemented for properties file security realm..."); 252 } 253 254 public String getPassword(String userPrincipal) 255 throws GeronimoSecurityException { 256 refreshUsers(); 257 return users.getProperty(userPrincipal); 258 } 259 260 public Set getGroupMembers(String groupPrincipal) 261 throws GeronimoSecurityException { 262 Set memberSet = new HashSet (); 263 groups.clear(); 264 refreshGroups(); 265 if (groups.getProperty(groupPrincipal) == null) { 266 return memberSet; 267 } 268 String [] members = groups.getProperty(groupPrincipal) 269 .split(","); 270 271 memberSet.addAll(Arrays.asList(members)); 272 return memberSet; 273 } 274 275 private String getUsersURI() { 276 return loginModule.getOptions().getProperty(usersKey); 277 } 278 279 private String getGroupsURI() { 280 return loginModule.getOptions().getProperty(groupsKey); 281 } 282 283 private String getDigest() { 284 return loginModule.getOptions().getProperty(digestKey); 285 } 286 287 private void store(Properties props, URL url) throws Exception { 288 OutputStream out = null; 289 try { 290 try { 291 URLConnection con = url.openConnection(); 292 con.setDoOutput(true); 293 out = con.getOutputStream(); 294 } catch (Exception e) { 295 if ("file".equalsIgnoreCase(url.getProtocol()) && e instanceof UnknownServiceException ) { 296 out = new FileOutputStream (new File (url.getFile())); 297 } else { 298 throw e; 299 } 300 } 301 props.store(out, null); 302 } finally { 303 if (out != null) { 304 try { 305 out.close(); 306 } catch (IOException ignored) { 307 } 309 } 310 } 311 } 312 313 320 private String digestPassword(String password, String algorithm) throws NoSuchAlgorithmException { 321 MessageDigest md = MessageDigest.getInstance(algorithm); 322 byte[] data = md.digest(password.getBytes()); 323 byte[] hexData = new byte[data.length * 2]; 325 HexTranslator ht = new HexTranslator(); 326 ht.encode(data, 0, data.length, hexData, 0); 327 return new String (hexData); 328 } 329 330 public static final GBeanInfo GBEAN_INFO; 331 332 static { 333 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("PropertiesLoginModuleManager", PropertiesLoginModuleManager.class); 334 335 infoFactory.addOperation("addUserPrincipal", new Class []{Hashtable .class}); 336 infoFactory.addOperation("removeUserPrincipal", new Class []{String .class}); 337 infoFactory.addOperation("updateUserPrincipal", new Class []{Hashtable .class}); 338 infoFactory.addOperation("getGroups"); 339 infoFactory.addOperation("getUsers"); 340 341 infoFactory.addOperation("updateUserPrincipal", new Class []{Hashtable .class}); 342 343 infoFactory.addOperation("getPassword", new Class []{String .class}); 344 infoFactory.addOperation("getGroupMembers", new Class []{String .class}); 345 infoFactory.addOperation("addGroupPrincipal", new Class []{Hashtable .class}); 346 infoFactory.addOperation("removeGroupPrincipal", new Class []{String .class}); 347 infoFactory.addOperation("updateGroupPrincipal", new Class []{Hashtable .class}); 348 infoFactory.addOperation("addToGroup", new Class []{String .class, String .class}); 349 infoFactory.addOperation("removeFromGroup", new Class []{String .class, String .class}); 350 351 infoFactory.addReference("ServerInfo", ServerInfo.class, NameFactory.GERONIMO_SERVICE); 352 infoFactory.addReference("LoginModule", LoginModuleSettings.class, NameFactory.LOGIN_MODULE); 353 354 infoFactory.setConstructor(new String []{"ServerInfo", "LoginModule"}); 355 356 GBEAN_INFO = infoFactory.getBeanInfo(); 357 } 358 359 public static GBeanInfo getGBeanInfo() { 360 return GBEAN_INFO; 361 } 362 363 } 364 | Popular Tags |