00001
00026 package org.objectweb.jonas.security;
00027
00028 import java.io.File;
00029 import java.io.FileNotFoundException;
00030 import java.io.FileReader;
00031 import java.io.Reader;
00032 import java.io.StringReader;
00033 import java.security.NoSuchAlgorithmException;
00034
00035 import javax.management.MBeanServer;
00036 import javax.naming.Context;
00037 import javax.naming.InitialContext;
00038 import javax.naming.NamingException;
00039
00040 import org.objectweb.jonas.common.Log;
00041 import org.objectweb.jonas.jmx.JmxService;
00042 import org.objectweb.jonas.jmx.JonasObjectName;
00043 import org.objectweb.jonas.security.lib.wrapper.JResourceManagerWrapper;
00044 import org.objectweb.jonas.security.realm.factory.JResource;
00045 import org.objectweb.jonas.security.realm.factory.JResourceDS;
00046 import org.objectweb.jonas.security.realm.factory.JResourceLDAP;
00047 import org.objectweb.jonas.security.realm.factory.JResourceMemory;
00048 import org.objectweb.jonas.security.realm.lib.HashHelper;
00049 import org.objectweb.jonas.service.AbsServiceImpl;
00050 import org.objectweb.jonas.service.ServiceException;
00051 import org.objectweb.jonas.service.ServiceManager;
00052
00053 import org.objectweb.util.monolog.api.BasicLevel;
00054 import org.objectweb.util.monolog.api.Logger;
00055
00056
00066 public class JonasSecurityServiceImpl extends AbsServiceImpl implements SecurityService, JonasSecurityServiceImplMBean {
00067
00071 private static Logger logger = null;
00072
00076 public static final String CLASS = "jonas.service.security.class";
00077
00081 protected static final String CONFIG_FILE = "conf" + File.separator + "jonas-realm.xml";
00082
00086 private MBeanServer mbeanServer = null;
00087
00091 private JResources jResources;
00092
00096 private Context ictx = null;
00097
00104 public void doInit(Context ctx) throws ServiceException {
00105 if (logger == null) {
00106 logger = Log.getLogger(Log.JONAS_SECURITY_PREFIX);
00107 }
00108
00109
00110 jResources = new JResources(this);
00111
00112
00113 try {
00114 ictx = new InitialContext();
00115 } catch (NamingException e) {
00116 logger.log(BasicLevel.ERROR, "Cannot create initial context during the mail service initializing");
00117 throw new ServiceException("Cannot create initial context during the mail service initializing", e);
00118 }
00119
00120
00121 try {
00122 mbeanServer = ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer();
00123 } catch (Exception e) {
00124
00125 mbeanServer = null;
00126 }
00127
00128 logger.log(BasicLevel.DEBUG, "JonasSecurityService initialized");
00129 }
00130
00136 public void removeJResource(String resourceName) throws Exception {
00137
00138
00139 JResource jResource = jResources.remove(resourceName);
00140
00141
00142 try {
00143 ictx.unbind(resourceName);
00144 logger.log(BasicLevel.DEBUG, "jResource " + resourceName + " remove from the registry.");
00145 } catch (NamingException e) {
00146
00147 }
00148
00149 try {
00150
00151 jResource.removeMBeans();
00152
00153
00154 if (jResource instanceof JResourceMemory) {
00155 mbeanServer.unregisterMBean(JonasObjectName.securityMemoryFactory(resourceName));
00156 } else if (jResource instanceof JResourceDS) {
00157 mbeanServer.unregisterMBean(JonasObjectName.securityDatasourceFactory(resourceName));
00158 } else if (jResource instanceof JResourceLDAP) {
00159 mbeanServer.unregisterMBean(JonasObjectName.securityLdapFactory(resourceName));
00160 }
00161 } catch (ServiceException se) {
00162
00163 } catch (Exception e) {
00164 logger.log(BasicLevel.ERROR, "Can not unregister the MBean for the resource " + resourceName + " : " + e.getMessage());
00165 throw new ServiceException("Can not unregister the MBean for the resource " + resourceName + " : " + e.getMessage());
00166 }
00167
00168 }
00169
00170
00176 public void doStart() throws ServiceException {
00177 try {
00178
00179 mbeanServer.registerMBean(this, JonasObjectName.securityService());
00180 } catch (ServiceException se) {
00181
00182 } catch (Exception e) {
00183 logger.log(BasicLevel.ERROR, "SecurityService: Cannot start the Security service:\n" + e);
00184 throw new ServiceException("SecurityService: Cannot start the Security service", e);
00185 }
00186
00187 createRealm();
00188 }
00189
00190
00194 public void doStop() {
00195
00196
00197 try {
00198
00199 ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer().unregisterMBean(JonasObjectName.securityService());
00200 } catch (ServiceException se) {
00201
00202 } catch (Exception e) {
00203 logger.log(BasicLevel.ERROR, "Cannot stop the security service:\n" + e);
00204 throw new ServiceException("Cannot stop the security service", e);
00205 }
00206 }
00207
00213 public JResource getJResource(String name) {
00214 return jResources.getJResource(name);
00215 }
00216
00217
00222 private void createRealm() throws ServiceException {
00223
00224
00225 File configFile = null;
00226 Reader reader = null;
00227 try {
00228 configFile = getConfigFile();
00229 reader = new FileReader(configFile);
00230 } catch (FileNotFoundException e) {
00231 logger.log(BasicLevel.ERROR, "Cannot find config file " + configFile);
00232 throw new ServiceException(e.getMessage(), e);
00233 }
00234
00235 try {
00236 JResourceManagerWrapper.addResources(jResources, reader, configFile.getPath());
00237 } catch (Exception e1) {
00238 String err = "Cannot add security resource from '" + configFile + "'";
00239 logger.log(BasicLevel.ERROR, err);
00240 throw new ServiceException(err, e1);
00241 }
00242 }
00243
00249 protected File getConfigFile() throws FileNotFoundException {
00250 String fileName = System.getProperty("jonas.base");
00251 fileName = fileName + File.separator + CONFIG_FILE;
00252 File file = new File(fileName);
00253 if (!file.exists()) {
00254 String err = "Can't find configuration file : " + fileName;
00255 throw new FileNotFoundException(err);
00256 }
00257 return (file);
00258 }
00259
00264 public String toXML() {
00265 return jResources.toXML();
00266 }
00267
00268
00276 public String encryptPassword(String string, String algo) throws NoSuchAlgorithmException {
00277 String encrypt = HashHelper.hashPassword(string, algo);
00278
00279 return "{" + algo.toUpperCase() + "}" + encrypt;
00280 }
00281
00282
00288 public boolean isValidAlgorithm(String algo) {
00289 boolean b = true;
00290 try {
00291 encryptPassword("test", algo);
00292 } catch (NoSuchAlgorithmException nsae) {
00293 b = false;
00294 }
00295 return b;
00296 }
00297
00303 public void addResources(String xml) throws Exception {
00304
00305 try {
00306 JResourceManagerWrapper.addResources(jResources, new StringReader(xml), "");
00307 } catch (Exception e1) {
00308 String err = "Cannot add security resource from xml '" + xml + "'";
00309 logger.log(BasicLevel.ERROR, err);
00310 throw new ServiceException(err, e1);
00311 }
00312 }
00313
00314
00320 public void addJResourceMemory(String name) throws Exception {
00321
00322
00323 JResourceMemory jResourceMemory = new JResourceMemory();
00324 jResourceMemory.setName(name);
00325
00326
00327 StringBuffer xml = new StringBuffer(JResources.HEADER_XML);
00328 xml.append("<jonas-realm>");
00329 xml.append("<jonas-memoryrealm>");
00330 xml.append(jResourceMemory.toXML());
00331 xml.append("</jonas-memoryrealm>");
00332 xml.append("</jonas-realm>");
00333
00334
00335 addResources(xml.toString());
00336
00337 }
00338
00339
00355 public void addJResourceDS(String name,
00356 String dsName,
00357 String userTable,
00358 String userTableUsernameCol,
00359 String userTablePasswordCol,
00360 String roleTable,
00361 String roleTableUsernameCol,
00362 String roleTableRolenameCol,
00363 String algorithm) throws Exception {
00364
00365
00366 JResourceDS jResourceDS = new JResourceDS();
00367 jResourceDS.setName(name);
00368 jResourceDS.setDsName(dsName);
00369 jResourceDS.setUserTable(userTable);
00370 jResourceDS.setUserTableUsernameCol(userTableUsernameCol);
00371 jResourceDS.setUserTablePasswordCol(userTablePasswordCol);
00372 jResourceDS.setRoleTable(roleTable);
00373 jResourceDS.setRoleTableUsernameCol(roleTableUsernameCol);
00374 jResourceDS.setRoleTableRolenameCol(roleTableRolenameCol);
00375 jResourceDS.setAlgorithm(algorithm);
00376
00377
00378 StringBuffer xml = new StringBuffer(JResources.HEADER_XML);
00379 xml.append("<jonas-realm>");
00380 xml.append("<jonas-dsrealm>");
00381 xml.append(jResourceDS.toXML());
00382 xml.append("</jonas-dsrealm>");
00383 xml.append("</jonas-realm>");
00384
00385
00386 addResources(xml.toString());
00387
00388 }
00389
00390
00418 public void addJResourceLDAP(String name,
00419 String initialContextFactory,
00420 String providerUrl,
00421 String securityAuthentication,
00422 String securityPrincipal,
00423 String securityCredentials,
00424 String securityProtocol,
00425 String language,
00426 String referral,
00427 String stateFactories,
00428 String authenticationMode,
00429 String userPasswordAttribute,
00430 String userRolesAttribute,
00431 String roleNameAttribute,
00432 String baseDN,
00433 String userDN,
00434 String userSearchFilter,
00435 String roleDN,
00436 String roleSearchFilter,
00437 String algorithm) throws Exception {
00438
00439
00440 JResourceLDAP jResourceLDAP = new JResourceLDAP();
00441 jResourceLDAP.setName(name);
00442 jResourceLDAP.setInitialContextFactory(initialContextFactory);
00443 jResourceLDAP.setProviderUrl(providerUrl);
00444 jResourceLDAP.setSecurityAuthentication(securityAuthentication);
00445 jResourceLDAP.setSecurityPrincipal(securityPrincipal);
00446 jResourceLDAP.setSecurityCredentials(securityCredentials);
00447 jResourceLDAP.setSecurityProtocol(securityProtocol);
00448 jResourceLDAP.setLanguage(language);
00449 jResourceLDAP.setReferral(referral);
00450 jResourceLDAP.setStateFactories(stateFactories);
00451 jResourceLDAP.setAuthenticationMode(authenticationMode);
00452 jResourceLDAP.setUserPasswordAttribute(userPasswordAttribute);
00453 jResourceLDAP.setUserRolesAttribute(userRolesAttribute);
00454 jResourceLDAP.setRoleNameAttribute(roleNameAttribute);
00455 jResourceLDAP.setBaseDN(baseDN);
00456 jResourceLDAP.setUserDN(userDN);
00457 jResourceLDAP.setUserSearchFilter(userSearchFilter);
00458 jResourceLDAP.setRoleDN(roleDN);
00459 jResourceLDAP.setRoleSearchFilter(roleSearchFilter);
00460 jResourceLDAP.setAlgorithm(algorithm);
00461
00462
00463 StringBuffer xml = new StringBuffer(JResources.HEADER_XML);
00464 xml.append("<jonas-realm>");
00465 xml.append("<jonas-ldaprealm>");
00466 xml.append(jResourceLDAP.toXML());
00467 xml.append("</jonas-ldaprealm>");
00468 xml.append("</jonas-realm>");
00469
00470
00471 addResources(xml.toString());
00472
00473 }
00474
00480 public void bindResource(String name, JResource jResource) {
00481
00482 try {
00483 ictx.rebind(jResource.getName(), jResource);
00484 logger.log(BasicLevel.DEBUG, "jResource " + jResource.getName() + " bound into the registry.");
00485 } catch (NamingException e) {
00486
00487 }
00488
00489 try {
00490
00491 if (jResource instanceof JResourceMemory) {
00492 mbeanServer.registerMBean(jResource, JonasObjectName.securityMemoryFactory(jResource.getName()));
00493 } else if (jResource instanceof JResourceDS) {
00494 mbeanServer.registerMBean(jResource, JonasObjectName.securityDatasourceFactory(jResource.getName()));
00495 } else if (jResource instanceof JResourceLDAP) {
00496 mbeanServer.registerMBean(jResource, JonasObjectName.securityLdapFactory(jResource.getName()));
00497 }
00498 } catch (ServiceException se) {
00499
00500 } catch (Exception e) {
00501 logger.log(BasicLevel.ERROR, "Can not register the MBean for the resource " + jResource.getName() + " : " + e.getMessage());
00502 throw new ServiceException("Can not register the MBean for the resource " + jResource.getName() + " : " + e.getMessage());
00503 }
00504
00505 }
00506 }