001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or 1any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * Initial developer: Florent BENOIT
022: * --------------------------------------------------------------------------
023: * $Id: JResourceMemory.java 5459 2004-09-17 22:33:33Z ehardesty $
024: * --------------------------------------------------------------------------
025: */package org.objectweb.jonas.security.realm.factory;
026:
027: import java.security.NoSuchAlgorithmException;
028: import java.util.Enumeration;
029: import java.util.Hashtable;
030: import java.util.ArrayList;
031:
032: import javax.naming.BinaryRefAddr;
033: import javax.naming.NamingException;
034: import javax.naming.Reference;
035: import javax.naming.StringRefAddr;
036:
037: import org.objectweb.util.monolog.api.BasicLevel;
038: import org.objectweb.jonas.common.JNDIUtils;
039: import org.objectweb.jonas.jmx.JonasObjectName;
040: import org.objectweb.jonas.security.realm.lib.XML;
041: import org.objectweb.jonas.security.realm.principals.User;
042: import org.objectweb.jonas.security.realm.principals.Group;
043: import org.objectweb.jonas.security.realm.principals.Role;
044: import org.objectweb.jonas.security.realm.lib.HashHelper;
045:
046: /**
047: * This class extends the JResource class for the Memory implementation.
048: * @author Florent Benoit
049: */
050: public class JResourceMemory extends JResource implements
051: JResourceMemoryMBean {
052:
053: /**
054: * Groups
055: */
056: private Hashtable groups = new Hashtable();
057:
058: /**
059: * Roles
060: */
061: private Hashtable roles = new Hashtable();
062:
063: /**
064: * Type of the factory
065: */
066: private static final String FACTORY_TYPE = "org.objectweb.jonas.security.realm.factory.JResourceMemory";
067:
068: /**
069: * Name of the factory
070: */
071: private static final String FACTORY_NAME = "org.objectweb.jonas.security.realm.factory.JResourceMemoryFactory";
072:
073: /**
074: * Constructor . Use the super constructor
075: * @throws Exception if super constructor fail
076: */
077: public JResourceMemory() throws Exception {
078: super ();
079: }
080:
081: /**
082: * Add a user to this resource.
083: * @param user the user which need to be added.
084: * @throws Exception if the user already exists
085: */
086: public void addUser(User user) throws Exception {
087:
088: if (getUsers().get(user.getName()) != null) {
089: throw new Exception("User " + user.getName()
090: + " already exists.");
091: }
092:
093: // Add group if the group was not present
094: String[] userGroups = user.getArrayGroups();
095: String groupName = null;
096: for (int g = 0; g < userGroups.length; g++) {
097: groupName = userGroups[g];
098: if (!groups.containsKey(groupName)) {
099: addGroup(new Group(groupName));
100: }
101: }
102:
103: // Add role if the role was not present
104: String[] userRoles = user.getArrayRoles();
105: String roleName = null;
106: for (int g = 0; g < userRoles.length; g++) {
107: roleName = userRoles[g];
108: if (!roles.containsKey(roleName)) {
109: addRole(new Role(roleName));
110: }
111: }
112:
113: // Add user
114: getUsers().put(user.getName(), user);
115:
116: //Add Mbean
117: String userName = user.getName();
118: try {
119: // register security service mbean
120: getMBeanServer().registerMBean(user,
121: JonasObjectName.user(getName(), userName));
122: } catch (Exception e) {
123: getLogger().log(
124: BasicLevel.ERROR,
125: "Cannot register user '" + userName
126: + "' in JMX server : " + e.getMessage());
127: }
128: }
129:
130: /**
131: * Add a group to this resource.
132: * @param group the group which need to be added.
133: * @throws Exception if the group already exists
134: */
135: public void addGroup(Group group) throws Exception {
136:
137: if (groups.get(group.getName()) != null) {
138: throw new Exception("Group " + group.getName()
139: + " already exists.");
140: }
141:
142: // Add role if the role was not present
143: String[] groupRoles = group.getArrayRoles();
144: String roleName = null;
145: for (int g = 0; g < groupRoles.length; g++) {
146: roleName = groupRoles[g];
147: if (!roles.containsKey(roleName)) {
148: addRole(new Role(roleName));
149: }
150: }
151:
152: // Add group
153: groups.put(group.getName(), group);
154:
155: //Add Mbean
156: String groupName = group.getName();
157: try {
158: // register security service mbean
159: getMBeanServer().registerMBean(group,
160: JonasObjectName.group(getName(), groupName));
161: } catch (Exception e) {
162: getLogger().log(
163: BasicLevel.ERROR,
164: "Cannot register group '" + groupName
165: + "' in JMX server : " + e.getMessage());
166: }
167: }
168:
169: /**
170: * Add a role to this resource.
171: * @param role the role which need to be added.
172: * @throws Exception if the role already exists
173: */
174: public void addRole(Role role) throws Exception {
175:
176: if (roles.get(role.getName()) != null) {
177: throw new Exception("Role " + role.getName()
178: + " already exists.");
179: }
180:
181: // Add role
182: roles.put(role.getName(), role);
183:
184: //Add Mbean
185: String roleName = role.getName();
186: try {
187: // register security service mbean
188: getMBeanServer().registerMBean(role,
189: JonasObjectName.role(getName(), roleName));
190: } catch (Exception e) {
191: getLogger().log(
192: BasicLevel.ERROR,
193: "Cannot register role '" + roleName
194: + "' in JMX server : " + e.getMessage());
195: }
196: }
197:
198: /**
199: * Check if a user is found and return it
200: * @param name the wanted user name
201: * @return the user found or null
202: * @throws JResourceException if there is an error during the search
203: */
204: public User findUser(String name) throws JResourceException {
205: if (name == null) {
206: return null;
207: }
208: return ((User) getUsers().get(name));
209: }
210:
211: /**
212: * Check if the given credential is the right credential for the given user
213: * @param user user to check its credentials
214: * @param credentials the given credentials
215: * @return true if the credential is valid for this user
216: */
217: public boolean isValidUser(User user, String credentials) {
218:
219: boolean validated = false;
220:
221: //Get algorithm and hashpassword
222: String pass = user.getHashPassword().getPassword();
223: String algo = user.getHashPassword().getAlgorithm();
224:
225: // Crypt password ?
226: if (algo != null) {
227: try {
228: validated = HashHelper.hashPassword(credentials, algo)
229: .equalsIgnoreCase(pass);
230: } catch (NoSuchAlgorithmException nsae) {
231: getLogger().log(
232: BasicLevel.ERROR,
233: "Can't make a password with the algorithm "
234: + algo + ". " + nsae.getMessage());
235: }
236: } else {
237: // clear
238: validated = credentials.equals(pass);
239: }
240: return validated;
241: }
242:
243: /**
244: * Return all the groups
245: * @return the groups
246: */
247: public Hashtable getGroups() {
248: return groups;
249: }
250:
251: /**
252: * Return all the roles
253: * @return the roles
254: */
255: public Hashtable getRoles() {
256: return roles;
257: }
258:
259: /**
260: * Get all the roles (from the roles and from the groups) of the given user
261: * @param user the given user
262: * @return the array list of all the roles for a given user
263: * @throws JResourceException if it fails
264: */
265: public ArrayList getArrayListCombinedRoles(User user)
266: throws JResourceException {
267: ArrayList allCombinedRoles = new ArrayList();
268:
269: // Return empty array if user null
270: if (user == null) {
271: return allCombinedRoles;
272: }
273:
274: // Add all user roles
275: String[] userRoles = user.getArrayRoles();
276: for (int r = 0; r < userRoles.length; r++) {
277: String roleName = userRoles[r];
278: if (!allCombinedRoles.contains(roleName)) {
279: allCombinedRoles.add(roleName);
280: }
281: }
282:
283: // Add roles of each group
284: String[] userGroups = user.getArrayGroups();
285: for (int g = 0; g < userGroups.length; g++) {
286: String groupName = userGroups[g];
287:
288: // For each roles of the given group
289: Group group = (Group) groups.get(groupName);
290: if (group == null) {
291: continue;
292: }
293:
294: String[] groupRoles = group.getArrayRoles();
295: for (int gr = 0; gr < groupRoles.length; gr++) {
296: String roleName = groupRoles[gr];
297: if (!allCombinedRoles.contains(roleName)) {
298: allCombinedRoles.add(roleName);
299: }
300: }
301: }
302:
303: return allCombinedRoles;
304: }
305:
306: /**
307: * Set the groups
308: * @param groups the groups of this resource
309: */
310: public void setGroups(Hashtable groups) {
311: this .groups = groups;
312: }
313:
314: /**
315: * Set the roles
316: * @param roles the roles of this resource
317: */
318: public void setRoles(Hashtable roles) {
319: this .roles = roles;
320: }
321:
322: /**
323: * Add a user with a given principal and credential
324: * @param username the name of the user
325: * @param password password of the user
326: * @throws Exception if the user already exists
327: */
328: public void addUser(String username, String password)
329: throws Exception {
330: addUser(new User(username, password));
331: }
332:
333: /**
334: * Add a group with a given name
335: * @param groupname the name of the group
336: * @throws Exception if the group already exists
337: */
338: public void addGroup(String groupname) throws Exception {
339: addGroup(new Group(groupname));
340: }
341:
342: /**
343: * Add a role with a given name
344: * @param rolename the name of the role
345: * @throws Exception if the role already exists
346: */
347: public void addRole(String rolename) throws Exception {
348: addRole(new Role(rolename));
349: }
350:
351: /**
352: * Remove a user with a given principal
353: * @param username the name of the user
354: * @throws Exception if the user was not found
355: */
356: public void removeUser(String username) throws Exception {
357: if (getUsers().get(username) == null) {
358: throw new Exception("Can not remove user " + username
359: + ". This user doesn't exist");
360: }
361: getUsers().remove(username);
362:
363: // Remove Mbean
364: try {
365: // register security service mbean
366: getMBeanServer().unregisterMBean(
367: JonasObjectName.user(getName(), username));
368: } catch (Exception e) {
369: getLogger().log(
370: BasicLevel.ERROR,
371: "Cannot unregister user '" + username
372: + "' in JMX server : " + e.getMessage());
373: }
374:
375: }
376:
377: /**
378: * Remove a group with a given name
379: * @param groupname the name of the group
380: * @throws Exception if the group was not found
381: */
382: public void removeGroup(String groupname) throws Exception {
383: if (groups.get(groupname) == null) {
384: throw new Exception("Can not remove group " + groupname
385: + ". This group doesn't exist");
386: }
387: groups.remove(groupname);
388: // Remove Mbean
389: try {
390: // register security service mbean
391: getMBeanServer().unregisterMBean(
392: JonasObjectName.group(getName(), groupname));
393: } catch (Exception e) {
394: getLogger().log(
395: BasicLevel.ERROR,
396: "Cannot unregister group '" + groupname
397: + "' in JMX server : " + e.getMessage());
398: }
399: }
400:
401: /**
402: * Remove a role with a given name
403: * @param rolename the name of the role
404: * @throws Exception if the role was not found
405: */
406: public void removeRole(String rolename) throws Exception {
407: if (roles.get(rolename) == null) {
408: throw new Exception("Can not remove role " + rolename
409: + ". This role doesn't exist");
410: }
411: roles.remove(rolename);
412:
413: // Remove Mbean
414: try {
415: // register security service mbean
416: getMBeanServer().unregisterMBean(
417: JonasObjectName.role(getName(), rolename));
418: } catch (Exception e) {
419: getLogger().log(
420: BasicLevel.ERROR,
421: "Cannot unregister role '" + rolename
422: + "' in JMX server : " + e.getMessage());
423: }
424: }
425:
426: /**
427: * String representation of the MemoryRealm
428: * @return the xml representation of the MemoryRealm
429: */
430: public String toXML() {
431: StringBuffer xml = new StringBuffer(" <memoryrealm name=\"");
432: xml.append(getName());
433: xml.append("\">\n");
434:
435: // Roles
436: xml.append(" <roles>\n");
437: XML.xmlHashtable(xml, getRoles(), " ");
438: xml.append(" </roles>\n");
439:
440: // Groups
441: xml.append(" <groups>\n");
442: XML.xmlHashtable(xml, getGroups(), " ");
443: xml.append(" </groups>\n");
444:
445: // Users
446: xml.append(" <users>\n");
447: XML.xmlHashtable(xml, getUsers(), " ");
448: xml.append(" </users>\n");
449:
450: xml.append(" </memoryrealm>");
451: return xml.toString();
452: }
453:
454: /**
455: * The string representation of this realm is the XML
456: * @return XML representation
457: */
458: public String toString() {
459: return this .toXML();
460: }
461:
462: /**
463: * Retrieves the Reference of the object. The Reference contains the factory
464: * used to create this object and the optional parameters used to configure
465: * the factory.
466: * @return the non-null Reference of the object.
467: * @throws NamingException if a naming exception was encountered while
468: * retrieving the reference.
469: */
470: public Reference getReference() throws NamingException {
471:
472: // Build the reference to the factory FACTORY_TYPE
473: Reference reference = new Reference(FACTORY_TYPE, FACTORY_NAME,
474: null);
475:
476: // Add name
477: reference.add(new StringRefAddr("name", getName()));
478:
479: // Add users
480: byte[] bytes = JNDIUtils.getBytesFromObject(getUsers(),
481: getLogger());
482: if (bytes != null) {
483: reference.add(new BinaryRefAddr("users", bytes));
484: }
485:
486: // Add groups
487: bytes = JNDIUtils.getBytesFromObject(groups, getLogger());
488: if (bytes != null) {
489: reference.add(new BinaryRefAddr("groups", bytes));
490: }
491:
492: // Add roles
493: bytes = JNDIUtils.getBytesFromObject(roles, getLogger());
494: if (bytes != null) {
495: reference.add(new BinaryRefAddr("roles", bytes));
496: }
497:
498: return reference;
499:
500: }
501:
502: /**
503: * Get the roles
504: * @return the array of the roles
505: */
506: public String[] listRoles() {
507: String[] s = new String[roles.size()];
508: int i = 0;
509: for (Enumeration e = roles.keys(); e.hasMoreElements(); i++) {
510: s[i] = (String) e.nextElement();
511: }
512: return s;
513: }
514:
515: /**
516: * Get the groups
517: * @return the array of the groups
518: */
519: public String[] listGroups() {
520: String[] s = new String[groups.size()];
521: int i = 0;
522: for (Enumeration e = groups.keys(); e.hasMoreElements(); i++) {
523: s[i] = (String) e.nextElement();
524: }
525: return s;
526: }
527:
528: /**
529: * Remove all the Mbeans used by this resource
530: * @throws JResourceException if the MBeans can not be removed
531: */
532: public void removeMBeans() throws JResourceException {
533:
534: boolean error = false;
535: // Remove users MBeans
536: for (Enumeration e = getUsers().elements(); e.hasMoreElements();) {
537: User u = (User) e.nextElement();
538: try {
539: // unregister user mbean
540: getMBeanServer().unregisterMBean(
541: JonasObjectName.user(getName(), u.getName()));
542: } catch (Exception ex) {
543: error = true;
544: getLogger().log(
545: BasicLevel.ERROR,
546: "Cannot unregister mbean user '" + u.getName()
547: + "' in JMX server : "
548: + ex.getMessage());
549: }
550: }
551:
552: // Remove roles MBeans
553: for (Enumeration e = roles.elements(); e.hasMoreElements();) {
554: Role r = (Role) e.nextElement();
555: try {
556: // unregister role mbean
557: getMBeanServer().unregisterMBean(
558: JonasObjectName.role(getName(), r.getName()));
559: } catch (Exception ex) {
560: error = true;
561: getLogger().log(
562: BasicLevel.ERROR,
563: "Cannot unregister mbean role '" + r.getName()
564: + "' in JMX server : "
565: + ex.getMessage());
566: }
567: }
568:
569: // Remove groups MBeans
570: for (Enumeration e = groups.elements(); e.hasMoreElements();) {
571: Group g = (Group) e.nextElement();
572: try {
573: // unregister group mbean
574: getMBeanServer().unregisterMBean(
575: JonasObjectName.group(getName(), g.getName()));
576: } catch (Exception ex) {
577: error = true;
578: getLogger().log(
579: BasicLevel.ERROR,
580: "Cannot unregister mbean group '" + g.getName()
581: + "' in JMX server : "
582: + ex.getMessage());
583: }
584: }
585:
586: if (error) {
587: throw new JResourceException(
588: "There was errors during the remove of the MBeans of this resource. See the traces.");
589: }
590:
591: }
592:
593: }
|