1 17 package org.apache.geronimo.console.securitymanager.realm; 18 19 import org.apache.commons.logging.Log; 20 import org.apache.commons.logging.LogFactory; 21 import org.apache.geronimo.console.BasePortlet; 22 import org.apache.geronimo.console.util.PortletManager; 23 import org.apache.geronimo.deployment.xbeans.ArtifactType; 24 import org.apache.geronimo.deployment.xbeans.AttributeType; 25 import org.apache.geronimo.deployment.xbeans.ModuleDocument; 26 import org.apache.geronimo.deployment.xbeans.ModuleType; 27 import org.apache.geronimo.deployment.xbeans.DependenciesType; 28 import org.apache.geronimo.deployment.xbeans.EnvironmentType; 29 import org.apache.geronimo.deployment.xbeans.GbeanType; 30 import org.apache.geronimo.deployment.xbeans.ReferenceType; 31 import org.apache.geronimo.deployment.xbeans.XmlAttributeType; 32 import org.apache.geronimo.deployment.xbeans.AbstractServiceType; 33 import org.apache.geronimo.deployment.xbeans.ServiceDocument; 34 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 35 import org.apache.geronimo.kernel.Kernel; 36 import org.apache.geronimo.kernel.KernelRegistry; 37 import org.apache.geronimo.kernel.config.Configuration; 38 import org.apache.geronimo.kernel.config.ConfigurationManager; 39 import org.apache.geronimo.kernel.config.ConfigurationModuleType; 40 import org.apache.geronimo.kernel.config.ConfigurationUtil; 41 import org.apache.geronimo.kernel.management.State; 42 import org.apache.geronimo.kernel.proxy.GeronimoManagedBean; 43 import org.apache.geronimo.kernel.repository.Artifact; 44 import org.apache.geronimo.kernel.repository.ListableRepository; 45 import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory; 46 import org.apache.geronimo.security.jaas.JaasLoginModuleChain; 47 import org.apache.geronimo.security.jaas.LoginModuleSettings; 48 import org.apache.geronimo.security.jaas.JaasLoginModuleUse; 49 import org.apache.geronimo.security.jaas.NamedUPCredentialLoginModule; 50 import org.apache.geronimo.security.realm.providers.FileAuditLoginModule; 51 import org.apache.geronimo.security.realm.providers.GeronimoPasswordCredentialLoginModule; 52 import org.apache.geronimo.security.realm.providers.RepeatedFailureLockoutLoginModule; 53 import org.apache.geronimo.security.realm.SecurityRealm; 54 import org.apache.geronimo.xbeans.geronimo.loginconfig.GerControlFlagType; 55 import org.apache.geronimo.xbeans.geronimo.loginconfig.GerLoginConfigDocument; 56 import org.apache.geronimo.xbeans.geronimo.loginconfig.GerLoginConfigType; 57 import org.apache.geronimo.xbeans.geronimo.loginconfig.GerLoginModuleType; 58 import org.apache.geronimo.xbeans.geronimo.loginconfig.GerOptionType; 59 import org.apache.geronimo.gbean.AbstractName; 60 import org.apache.xmlbeans.XmlCursor; 61 import org.apache.xmlbeans.XmlObject; 62 import org.apache.xmlbeans.XmlOptions; 63 64 import javax.enterprise.deploy.spi.DeploymentManager ; 65 import javax.enterprise.deploy.spi.Target ; 66 import javax.enterprise.deploy.spi.TargetModuleID ; 67 import javax.enterprise.deploy.spi.status.ProgressObject ; 68 import javax.portlet.ActionRequest; 69 import javax.portlet.ActionResponse; 70 import javax.portlet.PortletConfig; 71 import javax.portlet.PortletException; 72 import javax.portlet.PortletRequest; 73 import javax.portlet.PortletRequestDispatcher; 74 import javax.portlet.PortletSession; 75 import javax.portlet.RenderRequest; 76 import javax.portlet.RenderResponse; 77 import javax.portlet.WindowState; 78 import javax.security.auth.Subject ; 79 import javax.security.auth.spi.LoginModule ; 80 import javax.management.ObjectName ; 81 import javax.management.MalformedObjectNameException ; 82 import javax.xml.namespace.QName ; 83 84 import java.io.BufferedReader ; 85 import java.io.File ; 86 import java.io.FileWriter ; 87 import java.io.IOException ; 88 import java.io.PrintWriter ; 89 import java.io.Serializable ; 90 import java.io.StringReader ; 91 import java.io.StringWriter ; 92 import java.io.Writer ; 93 import java.net.MalformedURLException ; 94 import java.net.URL ; 95 import java.net.URLClassLoader ; 96 import java.net.URI ; 97 import java.util.ArrayList ; 98 import java.util.Arrays ; 99 import java.util.Collections ; 100 import java.util.HashMap ; 101 import java.util.Iterator ; 102 import java.util.LinkedHashMap ; 103 import java.util.List ; 104 import java.util.Map ; 105 import java.util.Properties ; 106 import java.util.Set ; 107 import java.util.SortedSet ; 108 109 114 public class SecurityRealmPortlet extends BasePortlet { 115 private final static Log log = LogFactory.getLog(SecurityRealmPortlet.class); 116 private final static String [] SKIP_ENTRIES_WITH = new String []{"geronimo", "tomcat", "tranql", "commons", "directory", "activemq"}; 117 private static final String LIST_VIEW = "/WEB-INF/view/realmwizard/list.jsp"; 118 private static final String EDIT_VIEW = "/WEB-INF/view/realmwizard/edit.jsp"; 119 private static final String SELECT_TYPE_VIEW = "/WEB-INF/view/realmwizard/selectType.jsp"; 120 private static final String CONFIGURE_VIEW = "/WEB-INF/view/realmwizard/configure.jsp"; 121 private static final String ADVANCED_VIEW = "/WEB-INF/view/realmwizard/advanced.jsp"; 122 private static final String TEST_LOGIN_VIEW = "/WEB-INF/view/realmwizard/testLogin.jsp"; 123 private static final String TEST_RESULTS_VIEW = "/WEB-INF/view/realmwizard/testResults.jsp"; 124 private static final String SHOW_PLAN_VIEW = "/WEB-INF/view/realmwizard/showPlan.jsp"; 125 private static final String USAGE_VIEW = "/WEB-INF/view/realmwizard/usage.jsp"; 126 private static final String LIST_MODE = "list"; 127 private static final String EDIT_MODE = "edit"; 128 private static final String SELECT_TYPE_MODE = "type"; 129 private static final String CONFIGURE_MODE = "configure"; 130 private static final String ADVANCED_MODE = "advanced"; 131 private static final String TEST_LOGIN_MODE = "test"; 132 private static final String TEST_RESULTS_MODE = "results"; 133 private static final String SHOW_PLAN_MODE = "plan"; 134 private static final String EDIT_EXISTING_MODE = "editExisting"; 135 private static final String USAGE_MODE = "usage"; 136 private static final String SAVE_MODE = "save"; 137 private static final String MODE_KEY = "mode"; 138 private static final String CUSTOM_MODE = "custom"; 139 140 private static Kernel kernel; 141 142 private PortletRequestDispatcher listView; 143 private PortletRequestDispatcher editView; 144 private PortletRequestDispatcher selectTypeView; 145 private PortletRequestDispatcher configureView; 146 private PortletRequestDispatcher advancedView; 147 private PortletRequestDispatcher testLoginView; 148 private PortletRequestDispatcher testResultsView; 149 private PortletRequestDispatcher planView; 150 private PortletRequestDispatcher usageView; 151 private static final QName GBEAN_QNAME = new QName (ServiceDocument.type.getDocumentElementName().getNamespaceURI(), "gbean"); 152 153 public void init(PortletConfig portletConfig) throws PortletException { 154 super.init(portletConfig); 155 kernel = KernelRegistry.getSingleKernel(); 156 listView = portletConfig.getPortletContext().getRequestDispatcher(LIST_VIEW); 157 editView = portletConfig.getPortletContext().getRequestDispatcher(EDIT_VIEW); 158 selectTypeView = portletConfig.getPortletContext().getRequestDispatcher(SELECT_TYPE_VIEW); 159 configureView = portletConfig.getPortletContext().getRequestDispatcher(CONFIGURE_VIEW); 160 advancedView = portletConfig.getPortletContext().getRequestDispatcher(ADVANCED_VIEW); 161 testLoginView = portletConfig.getPortletContext().getRequestDispatcher(TEST_LOGIN_VIEW); 162 testResultsView = portletConfig.getPortletContext().getRequestDispatcher(TEST_RESULTS_VIEW); 163 planView = portletConfig.getPortletContext().getRequestDispatcher(SHOW_PLAN_VIEW); 164 usageView = portletConfig.getPortletContext().getRequestDispatcher(USAGE_VIEW); 165 } 166 167 public void destroy() { 168 listView = null; 169 editView = null; 170 selectTypeView = null; 171 configureView = null; 172 advancedView = null; 173 testLoginView = null; 174 usageView = null; 175 planView = null; 176 super.destroy(); 177 } 178 179 public void processAction(ActionRequest actionRequest, 180 ActionResponse actionResponse) throws PortletException, IOException { 181 String mode = actionRequest.getParameter(MODE_KEY); 182 RealmData data = new RealmData(); 183 data.load(actionRequest); 184 if (mode.equals(SELECT_TYPE_MODE)) { 185 data.realmType = "Properties File Realm"; 186 actionResponse.setRenderParameter(MODE_KEY, SELECT_TYPE_MODE); 187 } else if (mode.equals("process-" + SELECT_TYPE_MODE)) { 188 if (data.getName() != null && !data.getName().trim().equals("")) { 189 if (data.getRealmType().equals("Other")) { 191 actionResponse.setRenderParameter(MODE_KEY, CUSTOM_MODE); 192 } else { 193 actionResponse.setRenderParameter(MODE_KEY, CONFIGURE_MODE); 194 } 195 } else { 196 actionResponse.setRenderParameter(MODE_KEY, SELECT_TYPE_MODE); 197 } 198 } else if (mode.equals("process-" + CONFIGURE_MODE)) { 199 final String error = actionTestLoginModuleLoad(actionRequest, data); 200 if (error == null) { 201 actionResponse.setRenderParameter(MODE_KEY, ADVANCED_MODE); 202 } else { 203 actionResponse.setRenderParameter("LoginModuleError", error); 204 actionResponse.setRenderParameter(MODE_KEY, CONFIGURE_MODE); 205 } 206 } else if (mode.equals("process-" + ADVANCED_MODE)) { 207 String test = actionRequest.getParameter("test"); 208 if (test == null || test.equals("true")) { 209 actionResponse.setRenderParameter(MODE_KEY, TEST_LOGIN_MODE); 210 } else { 211 actionSaveRealm(actionRequest, data); 212 actionResponse.setRenderParameter(MODE_KEY, LIST_MODE); 213 } 214 } else if (mode.equals("process-" + TEST_LOGIN_MODE)) { 215 actionAttemptLogin(data, actionRequest, actionRequest.getPortletSession(true), actionRequest.getParameter("username"), actionRequest.getParameter("password")); 216 actionResponse.setRenderParameter(MODE_KEY, TEST_RESULTS_MODE); 217 } else if (mode.equals(SHOW_PLAN_MODE)) { 218 XmlObject object = actionGeneratePlan(actionRequest, data); 219 savePlanToSession(actionRequest.getPortletSession(true), object); 220 actionResponse.setRenderParameter(MODE_KEY, SHOW_PLAN_MODE); 221 } else if (mode.equals(EDIT_EXISTING_MODE)) { 222 actionLoadExistingRealm(actionRequest, data); 223 actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE); 224 } else if (mode.equals(CONFIGURE_MODE)) { 225 if (data.getAbstractName() != null) { 226 actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE); 227 } else if((data.getRealmType() != null && data.getRealmType().equals("Other"))) { 228 actionResponse.setRenderParameter(MODE_KEY, CUSTOM_MODE); 229 } else { 230 actionResponse.setRenderParameter(MODE_KEY, CONFIGURE_MODE); 231 } 232 } else if (mode.equals(SAVE_MODE)) { 233 actionSaveRealm(actionRequest, data); 234 actionResponse.setRenderParameter(MODE_KEY, LIST_MODE); 235 } else { 236 actionResponse.setRenderParameter(MODE_KEY, mode); 237 } 238 data.store(actionResponse); 239 } 240 241 protected void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException , PortletException { 242 if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) { 243 return; 244 } 245 try { 246 String mode = renderRequest.getParameter(MODE_KEY); 247 RealmData data = new RealmData(); 248 data.load(renderRequest); 249 renderRequest.setAttribute("realm", data); 250 if (mode == null || mode.equals("")) { 251 mode = LIST_MODE; 252 } 253 if (mode.equals(LIST_MODE)) { 254 renderList(renderRequest, renderResponse); 255 } else if (mode.equals(EDIT_MODE) || mode.equals(CUSTOM_MODE)) { 256 renderRequest.setAttribute("mode", mode); 257 if(mode.equals(CUSTOM_MODE)) loadDriverJARList(renderRequest); 258 renderEdit(renderRequest, renderResponse, data); 259 } else if (mode.equals(SELECT_TYPE_MODE)) { 260 renderSelectType(renderRequest, renderResponse); 261 } else if (mode.equals(CONFIGURE_MODE)) { 262 renderConfigure(renderRequest, renderResponse, data); 263 } else if (mode.equals(ADVANCED_MODE)) { 264 renderAdvanced(renderRequest, renderResponse, data); 265 } else if (mode.equals(TEST_LOGIN_MODE)) { 266 renderTestLoginForm(renderRequest, renderResponse); 267 } else if (mode.equals(TEST_RESULTS_MODE)) { 268 renderTestResults(renderRequest, renderResponse); 269 } else if (mode.equals(SHOW_PLAN_MODE)) { 270 renderPlan(renderRequest, renderResponse); 271 } else if (mode.equals(USAGE_MODE)) { 272 renderUsage(renderRequest, renderResponse); 273 } 274 } catch (Throwable e) { 275 log.error("Unable to render portlet", e); 276 } 277 } 278 279 private String actionTestLoginModuleLoad(PortletRequest request, RealmData data) { 280 Map options = new HashMap (); 281 try { 282 LoginModule module = loadModule(request, data, options); 283 log.warn("Testing with options " + options); 284 try { 285 PortletManager.testLoginModule(request, module, options); 286 return null; 287 } catch (Exception e) { 288 log.warn("Unable to initialize LoginModule", e); 289 return "Unable to initialize LoginModule: " + e.getMessage(); 290 } 291 } catch (Exception e) { 292 log.warn("Unable to load LoginModule class", e); 293 return "Unable to load LoginModule class: " + e.getMessage(); 294 } 295 } 296 297 private LoginModule loadModule(PortletRequest request, RealmData data, Map options) throws ClassNotFoundException , InstantiationException , IllegalAccessException { 298 ClassLoader loader = getClass().getClassLoader(); 299 if (data.jar != null && !data.jar.equals("")) { 300 try { 301 Artifact one = Artifact.create(data.getJar()); 302 ListableRepository[] repos = PortletManager.getCurrentServer(request).getRepositories(); 303 for (int i = 0; i < repos.length; i++) { 304 ListableRepository repo = repos[i]; 305 File file = repo.getLocation(one); 306 if (file != null) { 307 loader = new URLClassLoader (new URL []{file.toURL()}, loader); 308 break; 309 } 310 } 311 } catch (MalformedURLException e) { 312 log.warn("Repository unable to look up JAR file", e); 313 } 314 } 315 Class cls = loader.loadClass(getSelectedModule(data).getClassName()); 316 LoginModule module = (LoginModule) cls.newInstance(); 317 for (Iterator it = data.getOptions().keySet().iterator(); it.hasNext();) { 318 String key = (String ) it.next(); 319 final Object value = data.getOptions().get(key); 320 if (value != null && !value.equals("")) { 321 options.put(key, value); 322 } 323 } 324 options.put(JaasLoginModuleUse.CLASSLOADER_LM_OPTION, loader); 325 return module; 326 } 327 328 private void actionAttemptLogin(RealmData data, PortletRequest request, PortletSession session, String username, String password) { 329 session.removeAttribute("TestLoginPrincipals"); 330 session.removeAttribute("TestLoginError"); 331 Map options = new HashMap (); 332 try { 333 LoginModule module = loadModule(request, data, options); 334 Subject sub = PortletManager.testLoginModule(request, module, options, username, password); 335 session.setAttribute("TestLoginPrincipals", sub.getPrincipals()); 336 } catch (Exception e) { 337 log.warn("Test login failed", e); 338 session.setAttribute("TestLoginError", "Login Failed: " + (e.getMessage() == null ? "no message" : e.getMessage())); 339 } 340 } 341 342 private XmlObject actionGeneratePlan(PortletRequest request, RealmData data) { 343 normalize(data); 344 ModuleDocument doc = ModuleDocument.Factory.newInstance(); 345 ModuleType root = doc.addNewModule(); 346 EnvironmentType environment = root.addNewEnvironment(); 347 ArtifactType configId = environment.addNewModuleId(); 348 configId.setGroupId("console.realm"); 349 String artifactId = data.getName(); 350 if(artifactId.indexOf('/') != -1) { 351 artifactId = artifactId.replaceAll("/", "%2F"); 354 } 355 configId.setArtifactId(artifactId); 356 configId.setVersion("1.0"); 357 configId.setType("car"); 358 359 361 DependenciesType dependenciesType = environment.addNewDependencies(); 362 ArtifactType parent = dependenciesType.addNewDependency(); 363 parent.setGroupId("org.apache.geronimo.configs"); 364 parent.setArtifactId("j2ee-security"); 365 parent.setType("car"); 366 if (data.getJar() != null) { 368 ArtifactType artifactType = dependenciesType.addNewDependency(); 369 Artifact artifact = Artifact.create(data.getJar()); 370 artifactType.setGroupId(artifact.getGroupId()); 371 artifactType.setArtifactId(artifact.getArtifactId()); 372 artifactType.setVersion(artifact.getVersion().toString()); 373 artifactType.setType(artifact.getType()); 374 } 375 GbeanType realm = GbeanType.Factory.newInstance(); 377 realm.setName(data.getName()); 378 realm.setClass1("org.apache.geronimo.security.realm.GenericSecurityRealm"); 379 AttributeType realmName = realm.addNewAttribute(); 380 realmName.setName("realmName"); 381 realmName.setStringValue(data.getName()); 382 ReferenceType serverInfo = realm.addNewReference(); 383 serverInfo.setName2("ServerInfo"); 384 serverInfo.setName((String ) PortletManager.getNameFor(request, PortletManager.getCurrentServer(request).getServerInfo()).getName().get("name")); 385 ReferenceType loginService = realm.addNewReference(); 386 loginService.setName2("LoginService"); 387 loginService.setName((String ) PortletManager.getNameFor(request, PortletManager.getCurrentServer(request).getLoginService()).getName().get("name")); 388 XmlAttributeType config = realm.addNewXmlReference(); 389 GerLoginConfigDocument lcDoc = GerLoginConfigDocument.Factory.newInstance(); 391 GerLoginConfigType login = lcDoc.addNewLoginConfig(); 392 for (int i = 0; i < data.getModules().length; i++) { 393 LoginModuleDetails details = data.getModules()[i]; 394 if (details.getLoginDomainName() == null || details.getLoginDomainName().equals("")) { 395 continue; 396 } 397 GerLoginModuleType module = login.addNewLoginModule(); 398 module.setControlFlag(details.getControlFlag().equals("OPTIONAL") ? GerControlFlagType.OPTIONAL : 399 details.getControlFlag().equals("REQUIRED") ? GerControlFlagType.REQUIRED : 400 details.getControlFlag().equals("REQUISITE") ? GerControlFlagType.REQUISITE : 401 details.getControlFlag().equals("SUFFICIENT") ? GerControlFlagType.SUFFICIENT : 402 GerControlFlagType.OPTIONAL); 403 module.setServerSide(details.isServerSide()); 404 module.setLoginDomainName(details.getLoginDomainName()); 405 module.setLoginModuleClass(details.getClassName()); 406 module.setWrapPrincipals(details.isWrapPrincipals()); 407 for (Iterator it = details.getOptions().entrySet().iterator(); it.hasNext();) { 408 Map.Entry entry = (Map.Entry ) it.next(); 409 GerOptionType option = module.addNewOption(); 410 option.setName((String ) entry.getKey()); 411 option.setStringValue((String ) entry.getValue()); 412 } 413 414 if (details.getClassName().indexOf("SQL") > -1) { 416 String poolName = (String ) details.getOptions().get("dataSourceName"); 417 String appName = (String ) details.getOptions().get("dataSourceApplication"); 418 if (poolName != null) { 419 if (appName == null) appName = "null"; 420 JCAManagedConnectionFactory[] factories = PortletManager.getOutboundFactoriesOfType(request, "javax.sql.DataSource"); 421 for (int j = 0; j < factories.length; j++) { 422 JCAManagedConnectionFactory factory = factories[j]; 423 try { 424 ObjectName objectName = ObjectName.getInstance(factory.getObjectName()); 425 final String testName = objectName.getKeyProperty(NameFactory.J2EE_NAME); 426 final String testApp = objectName.getKeyProperty(NameFactory.J2EE_APPLICATION); 427 if (testName.equals(poolName) && testApp.equals(appName)) { 428 String moduleName = objectName.getKeyProperty(NameFactory.JCA_RESOURCE); 429 430 ArtifactType artifactType = dependenciesType.addNewDependency(); 431 Artifact artifact = Artifact.create(moduleName); 432 artifactType.setGroupId(artifact.getGroupId()); 433 artifactType.setArtifactId(artifact.getArtifactId()); 434 artifactType.setVersion(artifact.getVersion().toString()); 435 artifactType.setType(artifact.getType()); 436 break; 437 } 438 } catch (MalformedObjectNameException e) { 439 log.error("Unable to parse ObjectName", e); 440 } 441 } 442 } 443 } 444 } 445 XmlCursor loginCursor = lcDoc.newCursor(); 447 loginCursor.toFirstContentToken(); 448 XmlCursor destination = config.newCursor(); 449 destination.toNextToken(); 450 loginCursor.moveXml(destination); 451 loginCursor.dispose(); 452 destination.dispose(); 453 config.setName("LoginModuleConfiguration"); 454 root.setServiceArray(new AbstractServiceType[]{realm}); 455 456 457 XmlCursor gbeanCursor = root.newCursor(); 460 try { 461 if (!gbeanCursor.toChild(ServiceDocument.type.getDocumentElementName())) { 462 throw new RuntimeException ("Could not find service element"); 463 } 464 gbeanCursor.setName(GBEAN_QNAME); 465 } finally { 466 gbeanCursor.dispose(); 467 } 468 469 return doc; 470 } 471 472 private void actionLoadExistingRealm(PortletRequest request, RealmData data) { 473 SecurityRealm realm = (SecurityRealm) PortletManager.getManagedBean(request, new AbstractName(URI.create(data.getAbstractName()))); 474 data.name = realm.getRealmName(); 475 List list = new ArrayList (); 476 JaasLoginModuleChain node = realm.getLoginModuleChain(); 477 while (node != null) { 478 LoginModuleDetails details = new LoginModuleDetails(); 479 details.setControlFlag(node.getControlFlag()); 480 LoginModuleSettings module = node.getLoginModule(); 481 details.setLoginDomainName(module.getLoginDomainName()); 482 details.setClassName(module.getLoginModuleClass()); 483 details.setServerSide(module.isServerSide()); 484 details.setWrapPrincipals(module.isWrapPrincipals()); 485 details.setOptions(module.getOptions()); 486 list.add(details); 487 node = node.getNext(); 488 if (node == null) { 489 break; 490 } 491 } 492 data.modules = (LoginModuleDetails[]) list.toArray(new LoginModuleDetails[list.size()]); 493 } 494 495 private void actionSaveRealm(PortletRequest request, RealmData data) { 496 normalize(data); 497 if (data.getAbstractName() == null || data.getAbstractName().equals("")) { try { 499 XmlObject plan = actionGeneratePlan(request, data); 500 data.name = data.name.replaceAll("\\s", ""); 501 DeploymentManager mgr = PortletManager.getDeploymentManager(request); 502 File tempFile = File.createTempFile("console-deployment", ".xml"); 503 tempFile.deleteOnExit(); 504 log.debug("Writing security realm deployment plan to " + tempFile.getAbsolutePath()); 505 PrintWriter out = new PrintWriter (new FileWriter (tempFile)); 506 savePlanToStream(plan, out); 507 out.flush(); 508 out.close(); 509 Target [] targets = mgr.getTargets(); 510 ProgressObject po = mgr.distribute(targets, null, tempFile); 511 waitForProgress(po); 512 if (po.getDeploymentStatus().isCompleted()) { 513 TargetModuleID [] ids = po.getResultTargetModuleIDs(); 514 po = mgr.start(ids); 515 waitForProgress(po); 516 if (po.getDeploymentStatus().isCompleted()) { 517 log.info("Deployment completed successfully!"); 518 } 519 } 520 } catch (IOException e) { 521 log.error("Unable to save security realm", e); 522 } 523 } else { 524 SecurityRealm realm = (SecurityRealm) PortletManager.getManagedBean(request, new AbstractName(URI.create(data.getAbstractName()))); 525 Map nodes = new HashMap (); 527 JaasLoginModuleChain node = realm.getLoginModuleChain(); 528 while (node != null) { 529 LoginModuleSettings module = node.getLoginModule(); 530 nodes.put(module.getLoginDomainName(), node); 531 node = node.getNext(); 532 if (node == null) { 533 break; 534 } 535 } 536 for (int i = 0; i < data.getModules().length; i++) { 538 LoginModuleDetails details = data.getModules()[i]; 539 node = (JaasLoginModuleChain) nodes.get(details.getLoginDomainName()); 540 node.setControlFlag(details.getControlFlag()); 541 LoginModuleSettings module = node.getLoginModule(); 542 module.setOptions(details.getOptions()); 543 module.setServerSide(details.isServerSide()); 544 module.setWrapPrincipals(details.isWrapPrincipals()); 545 module.setLoginModuleClass(details.getClassName()); 546 } 547 } 548 } 549 550 private void renderList(RenderRequest request, RenderResponse response) throws IOException , PortletException { 551 org.apache.geronimo.management.geronimo.SecurityRealm[] realms = PortletManager.getCurrentServer(request).getSecurityRealms(); 555 ExistingRealm[] results = new ExistingRealm[realms.length]; 556 557 ConfigurationManager configMgr = null; 559 if(results.length > 0) { 560 configMgr = ConfigurationUtil.getConfigurationManager(kernel); 562 } 563 for (int i = 0; i < results.length; i++) { 564 final GeronimoManagedBean managedBean = (GeronimoManagedBean) realms[i]; 565 AbstractName abstractName = PortletManager.getNameFor(request, realms[i]); 566 String parent; 567 Configuration parentConfig = configMgr.getConfiguration(abstractName.getArtifact()); 568 ConfigurationModuleType parentType = parentConfig.getModuleType(); 569 if(ConfigurationModuleType.SERVICE.equals(parentType)) { 570 parent = null; } else { 572 parent = abstractName.getArtifact().toString(); 573 } 574 results[i] = new ExistingRealm(realms[i].getRealmName(), abstractName, managedBean.getState(), parent); 575 } 576 if(configMgr != null) { 578 ConfigurationUtil.releaseConfigurationManager(kernel, configMgr); 579 } 580 request.setAttribute("realms", results); 581 listView.include(request, response); 582 } 583 584 private void renderEdit(RenderRequest request, RenderResponse response, RealmData data) throws IOException , PortletException { 585 normalize(data); 586 editView.include(request, response); 587 } 588 589 private void renderSelectType(RenderRequest request, RenderResponse response) throws IOException , PortletException { 590 request.setAttribute("moduleTypes", MasterLoginModuleInfo.getAllModules()); 591 selectTypeView.include(request, response); 592 } 593 594 private void renderConfigure(RenderRequest request, RenderResponse response, RealmData data) throws IOException , PortletException { 595 if (request.getParameter("LoginModuleError") != null) { 597 request.setAttribute("LoginModuleError", request.getParameter("LoginModuleError")); 598 } 599 data.modules = null; 601 MasterLoginModuleInfo info = getSelectedModule(data); 603 for (int i = 0; i < info.getOptions().length; i++) { 604 MasterLoginModuleInfo.OptionInfo option = info.getOptions()[i]; 605 if (!data.getOptions().containsKey(option.getName())) { 606 data.getOptions().put(option.getName(), null); 607 } 608 } 609 data.reorderOptions(info.getOptions()); 610 request.setAttribute("optionMap", info.getOptionMap()); 611 if (info.getName().indexOf("SQL") > -1) { 612 loadDriverJARList(request); 613 loadDatabasePoolList(request); 614 } 615 configureView.include(request, response); 616 } 617 618 private void renderAdvanced(RenderRequest request, RenderResponse response, RealmData data) throws IOException , PortletException { 619 data.modules = null; 621 advancedView.include(request, response); 623 } 624 625 private void renderTestLoginForm(RenderRequest request, RenderResponse response) throws IOException , PortletException { 626 testLoginView.include(request, response); 627 } 628 629 private void renderTestResults(RenderRequest request, RenderResponse response) throws IOException , PortletException { 630 PortletSession session = request.getPortletSession(); 631 String status = (String ) session.getAttribute("TestLoginError"); 632 if (status == null) { 633 Set principals = (Set ) session.getAttribute("TestLoginPrincipals"); 634 status = "Login succeeded with " + (principals == null ? 0 : principals.size()) + " principals"; 635 request.setAttribute("principals", principals); 636 } 637 request.setAttribute("LoginResults", status); 638 testResultsView.include(request, response); 639 } 640 641 private void renderPlan(RenderRequest request, RenderResponse response) throws IOException , PortletException { 642 String plan = (String ) request.getPortletSession().getAttribute("SecurityRealmPlan"); 643 request.setAttribute("deploymentPlan", plan); 644 planView.include(request, response); 645 } 646 647 private void renderUsage(RenderRequest request, RenderResponse response) throws IOException , PortletException { 648 usageView.include(request, response); 649 } 650 651 private static MasterLoginModuleInfo getSelectedModule(RealmData data) { 652 MasterLoginModuleInfo[] all = MasterLoginModuleInfo.getAllModules(); 653 for (int i = 0; i < all.length; i++) { 654 MasterLoginModuleInfo info = all[i]; 655 if (info.getName().equals(data.getRealmType())) { 656 return info; 657 } 658 } 659 return null; 660 } 661 662 private void loadDatabasePoolList(RenderRequest renderRequest) { 663 JCAManagedConnectionFactory[] factories = PortletManager.getOutboundFactoriesOfType(renderRequest, "javax.sql.DataSource"); 664 List pools = new ArrayList (); 665 try { 666 for (int i = 0; i < factories.length; i++) { 667 JCAManagedConnectionFactory factory = factories[i]; 668 ObjectName objectName = ObjectName.getInstance(factory.getObjectName()); 669 final String name = objectName.getKeyProperty(NameFactory.J2EE_NAME); 670 String display = name; 671 final String appName = objectName.getKeyProperty(NameFactory.J2EE_APPLICATION); 672 if (appName != null && !appName.equals("null")) { 673 display = display + " (" + appName + ")"; 674 } 675 pools.add(new DatabasePool(name, display, appName, PortletManager.getNameFor(renderRequest, factory))); 676 } 677 renderRequest.setAttribute("pools", pools); 678 } catch (MalformedObjectNameException e) { 679 log.error("Unable to parse ObjectName", e); 680 } 681 } 682 683 private void loadDriverJARList(RenderRequest renderRequest) { 684 List list = new ArrayList (); 686 ListableRepository[] repos = PortletManager.getCurrentServer(renderRequest).getRepositories(); 687 for (int i = 0; i < repos.length; i++) { 688 ListableRepository repo = repos[i]; 689 690 SortedSet artifacts = repo.list(); 691 outer: 692 for (Iterator iterator = artifacts.iterator(); iterator.hasNext();) { 693 Artifact artifact = (Artifact) iterator.next(); 694 String test = artifact.toString(); 695 for (int k = 0; k < SKIP_ENTRIES_WITH.length; k++) { 697 String skip = SKIP_ENTRIES_WITH[k]; 698 if (test.indexOf(skip) > -1) { 699 continue outer; 700 } 701 } 702 list.add(test); 703 } 704 } 705 Collections.sort(list); 706 renderRequest.setAttribute("jars", list); 707 } 708 709 private void savePlanToSession(PortletSession session, XmlObject object) { 710 StringWriter out = new StringWriter (); 711 try { 712 savePlanToStream(object, out); 713 session.setAttribute("SecurityRealmPlan", out.getBuffer().toString()); 714 } catch (IOException e) { 715 log.error("Unable to write deployment plan", e); 716 } 717 } 718 719 private void savePlanToStream(XmlObject object, Writer out) throws IOException { 720 XmlOptions options = new XmlOptions(); 721 options.setSavePrettyPrint(); 722 options.setSavePrettyPrintIndent(4); 723 options.setUseDefaultNamespace(); 724 object.save(out, options); 725 out.close(); 726 } 727 728 private static void waitForProgress(ProgressObject po) { 729 while (po.getDeploymentStatus().isRunning()) { 730 try { 731 Thread.sleep(100); 732 } catch (InterruptedException e) { 733 log.error(e.getMessage(), e); 734 } 735 } 736 } 737 738 public static void normalize(RealmData data) { 739 List list = new ArrayList (); 740 if (data.modules == null) { 741 LoginModuleDetails module = new LoginModuleDetails(); 742 module.setClassName(getSelectedModule(data).getClassName()); 743 module.setControlFlag("REQUIRED"); 744 module.setLoginDomainName(data.getName()); 745 module.setServerSide(data.getRealmType().indexOf("erberos") < 0); 746 Properties props = module.getOptions(); 747 for (Iterator it = data.getOptions().entrySet().iterator(); it.hasNext();) { 748 Map.Entry entry = (Map.Entry ) it.next(); 749 props.setProperty((String ) entry.getKey(), (String ) entry.getValue()); 750 } 751 list.add(module); 752 if (data.isStorePassword()) { 753 module = new LoginModuleDetails(); 754 module.setClassName(GeronimoPasswordCredentialLoginModule.class.getName()); 755 module.setControlFlag("OPTIONAL"); 756 module.setLoginDomainName(data.getName() + "-Password"); 757 module.setServerSide(true); 758 list.add(module); 759 } 760 if (data.getAuditPath() != null) { 761 module = new LoginModuleDetails(); 762 module.setClassName(FileAuditLoginModule.class.getName()); 763 module.setControlFlag("OPTIONAL"); 764 module.setLoginDomainName(data.getName() + "-Audit"); 765 module.setServerSide(true); 766 props = module.getOptions(); 767 props.setProperty("file", data.getAuditPath()); 768 list.add(module); 769 } 770 if (data.isLockoutEnabled()) { 771 module = new LoginModuleDetails(); 772 module.setClassName(RepeatedFailureLockoutLoginModule.class.getName()); 773 module.setControlFlag("REQUISITE"); 774 module.setLoginDomainName(data.getName() + "-Lockout"); 775 module.setServerSide(true); 776 props = module.getOptions(); 777 props.setProperty("failureCount", data.getLockoutCount()); 778 props.setProperty("failurePeriodSecs", data.getLockoutWindow()); 779 props.setProperty("lockoutDurationSecs", data.getLockoutDuration()); 780 list.add(module); 781 } 782 if (data.getCredentialName() != null) { 783 module = new LoginModuleDetails(); 784 module.setClassName(NamedUPCredentialLoginModule.class.getName()); 785 module.setControlFlag("OPTIONAL"); 786 module.setLoginDomainName(data.getName() + "-NamedUPC"); 787 module.setServerSide(true); 788 props = module.getOptions(); 789 props.setProperty(NamedUPCredentialLoginModule.CREDENTIAL_NAME, data.getCredentialName()); 790 list.add(module); 791 } 792 } else { 793 list.addAll(Arrays.asList(data.modules)); 794 } 795 if (data.getAbstractName() == null) { 796 for (int i = list.size(); i < 5; i++) { 797 LoginModuleDetails module = new LoginModuleDetails(); 798 list.add(module); 799 } 800 } 801 data.modules = (LoginModuleDetails[]) list.toArray(new LoginModuleDetails[list.size()]); 802 } 803 804 public static class RealmData implements Serializable { 805 private String name; 806 private String realmType; 807 private String jar; 808 private Map options = new LinkedHashMap (); 809 private String auditPath; 810 private String lockoutCount; 811 private String lockoutWindow; 812 private String lockoutDuration; 813 private boolean storePassword; 814 private String abstractName; private LoginModuleDetails[] modules; 816 private String credentialName; 817 818 public void load(PortletRequest request) { 819 name = request.getParameter("name"); 820 if (name != null && name.equals("")) name = null; 821 realmType = request.getParameter("realmType"); 822 if (realmType != null && realmType.equals("")) realmType = null; 823 jar = request.getParameter("jar"); 824 if (jar != null && jar.equals("")) jar = null; 825 auditPath = request.getParameter("auditPath"); 826 if (auditPath != null && auditPath.equals("")) auditPath = null; 827 lockoutCount = request.getParameter("lockoutCount"); 828 if (lockoutCount != null && lockoutCount.equals("")) lockoutCount = null; 829 lockoutWindow = request.getParameter("lockoutWindow"); 830 if (lockoutWindow != null && lockoutWindow.equals("")) lockoutWindow = null; 831 lockoutDuration = request.getParameter("lockoutDuration"); 832 if (lockoutDuration != null && lockoutDuration.equals("")) lockoutDuration = null; 833 abstractName = request.getParameter("abstractName"); 834 if (abstractName != null && abstractName.equals("")) abstractName = null; 835 String test = request.getParameter("storePassword"); 836 storePassword = test != null && !test.equals("") && !test.equals("false"); 837 credentialName = request.getParameter("credentialName"); 838 if (credentialName != null && credentialName.equals("")) credentialName = null; 839 Map map = request.getParameterMap(); 840 for (Iterator it = map.keySet().iterator(); it.hasNext();) { 841 String key = (String ) it.next(); 842 if (key.startsWith("option-")) { 843 if (key.equals("option-databasePoolAbstractName")) 844 { String nameString = request.getParameter(key); 846 if (nameString != null && !nameString.equals("")) { 847 AbstractName an = new AbstractName(URI.create(nameString)); 848 options.put("dataSourceName", an.getNameProperty(NameFactory.J2EE_NAME)); 849 options.put("dataSourceApplication", an.getNameProperty(NameFactory.J2EE_APPLICATION)); 850 } 851 } else { 852 final String optionName = key.substring(7); 853 final String value = request.getParameter(key); 854 if (value != null && !value.equals("")) { 855 options.put(optionName, value); 856 } 857 } 858 } 859 } 860 int count = 0; 861 List list = new ArrayList (); 862 while (true) { 863 int index = count; 864 ++count; 865 String name = request.getParameter("module-domain-" + index); 866 if (name == null || name.equals("")) break; 867 LoginModuleDetails details = new LoginModuleDetails(); 868 details.setLoginDomainName(name); 869 String cls = request.getParameter("module-class-" + index); 870 if (cls == null || cls.equals("")) continue; 871 details.setClassName(cls); 872 String flag = request.getParameter("module-control-" + index); 873 if (flag == null || flag.equals("")) continue; 874 details.setControlFlag(flag); 875 String wrap = request.getParameter("module-wrap-" + index); 876 if (wrap == null || wrap.equals("")) continue; 877 details.setWrapPrincipals(Boolean.valueOf(wrap).booleanValue()); 878 String server = request.getParameter("module-server-" + index); 879 if (server == null || server.equals("")) continue; 880 details.setServerSide(Boolean.valueOf(server).booleanValue()); 881 String options = request.getParameter("module-options-" + index); 882 if (options != null && !options.equals("")) { 883 BufferedReader in = new BufferedReader (new StringReader (options)); 884 String line; 885 try { 886 while ((line = in.readLine()) != null) { 887 if (line.startsWith("#") || line.equals("")) { 888 continue; 889 } 890 int pos = line.indexOf('='); 891 if (pos > -1) { 892 details.getOptions().setProperty(line.substring(0, pos), line.substring(pos + 1)); 893 } 894 } 895 } catch (IOException e) { 896 log.error("Unable to read properties '" + options + "'", e); 897 } 898 } 899 list.add(details); 900 } 901 if (list.size() > 0) { 902 modules = (LoginModuleDetails[]) list.toArray(new LoginModuleDetails[list.size()]); 903 } 904 } 905 906 public void reorderOptions(MasterLoginModuleInfo.OptionInfo[] info) { 907 if (info == null || info.length == 0) { 908 return; } 910 Map map = new LinkedHashMap (); 911 for (int i = 0; i < info.length; i++) { 912 if (options.containsKey(info[i].getName())) { 913 map.put(info[i].getName(), options.get(info[i].getName())); 914 } 915 } 916 options = map; 917 } 918 919 public void store(ActionResponse response) { 920 if (name != null) response.setRenderParameter("name", name); 921 if (realmType != null) response.setRenderParameter("realmType", realmType); 922 if (jar != null) response.setRenderParameter("jar", jar); 923 if (auditPath != null) response.setRenderParameter("auditPath", auditPath); 924 if (lockoutCount != null) response.setRenderParameter("lockoutCount", lockoutCount); 925 if (lockoutWindow != null) response.setRenderParameter("lockoutWindow", lockoutWindow); 926 if (lockoutDuration != null) response.setRenderParameter("lockoutDuration", lockoutDuration); 927 if (abstractName != null) response.setRenderParameter("abstractName", abstractName); 928 if (storePassword) response.setRenderParameter("storePassword", "true"); 929 if (credentialName != null) response.setRenderParameter("credentialName", credentialName); 930 for (Iterator it = options.keySet().iterator(); it.hasNext();) { 931 String name = (String ) it.next(); 932 String value = (String ) options.get(name); 933 if (value != null) { 934 response.setRenderParameter("option-" + name, value); 935 } 936 } 937 if (modules != null) { 938 for (int i = 0; i < modules.length; i++) { 939 LoginModuleDetails module = modules[i]; 940 if (module.getLoginDomainName() != null) 941 response.setRenderParameter("module-domain-" + i, module.getLoginDomainName()); 942 if (module.getClassName() != null) 943 response.setRenderParameter("module-class-" + i, module.getClassName()); 944 if (module.getControlFlag() != null) 945 response.setRenderParameter("module-control-" + i, module.getControlFlag()); 946 response.setRenderParameter("module-wrap-" + i, Boolean.toString(module.isWrapPrincipals())); 947 response.setRenderParameter("module-server-" + i, Boolean.toString(module.isServerSide())); 948 if (module.getOptions().size() > 0) 949 response.setRenderParameter("module-options-" + i, module.getOptionString()); 950 } 951 } 952 } 953 954 public String getName() { 955 return name; 956 } 957 958 public String getRealmType() { 959 return realmType; 960 } 961 962 public Map getOptions() { 963 return options; 964 } 965 966 public Set getOptionNames() { 967 return options.keySet(); 968 } 969 970 public String getJar() { 971 return jar; 972 } 973 974 public String getAuditPath() { 975 return auditPath; 976 } 977 978 public String getLockoutCount() { 979 return lockoutCount; 980 } 981 982 public String getLockoutWindow() { 983 return lockoutWindow; 984 } 985 986 public String getLockoutDuration() { 987 return lockoutDuration; 988 } 989 990 public boolean isStorePassword() { 991 return storePassword; 992 } 993 994 public boolean isLockoutEnabled() { 995 return lockoutCount != null || lockoutWindow != null || lockoutDuration != null; 996 } 997 998 public String getCredentialName() { 999 return credentialName; 1000 } 1001 1002 public String getAbstractName() { 1003 return abstractName; 1004 } 1005 1006 public boolean isTestable() { 1007 return getSelectedModule(this).isTestable(); 1008 } 1009 1010 public LoginModuleDetails[] getModules() { 1011 return modules; 1012 } 1013 } 1014 1015 public static class LoginModuleDetails implements Serializable { 1016 private String loginDomainName; 1017 private String className; 1018 private String controlFlag; 1019 private boolean serverSide = true; 1020 private boolean wrapPrincipals = false; 1021 private Properties options = new Properties (); 1022 1023 public String getLoginDomainName() { 1024 return loginDomainName; 1025 } 1026 1027 public void setLoginDomainName(String loginDomainName) { 1028 this.loginDomainName = loginDomainName; 1029 } 1030 1031 public String getClassName() { 1032 return className; 1033 } 1034 1035 public void setClassName(String className) { 1036 this.className = className; 1037 } 1038 1039 public String getControlFlag() { 1040 return controlFlag; 1041 } 1042 1043 public void setControlFlag(String controlFlag) { 1044 this.controlFlag = controlFlag; 1045 } 1046 1047 public boolean isServerSide() { 1048 return serverSide; 1049 } 1050 1051 public void setServerSide(boolean serverSide) { 1052 this.serverSide = serverSide; 1053 } 1054 1055 public Properties getOptions() { 1056 return options; 1057 } 1058 1059 public void setOptions(Properties options) { 1060 this.options = options; 1061 } 1062 1063 public boolean isWrapPrincipals() { 1064 return wrapPrincipals; 1065 } 1066 1067 public void setWrapPrincipals(boolean wrapPrincipals) { 1068 this.wrapPrincipals = wrapPrincipals; 1069 } 1070 1071 public String getOptionString() { 1072 StringBuffer buf = new StringBuffer (); 1073 for (Iterator it = options.keySet().iterator(); it.hasNext();) { 1074 String key = (String ) it.next(); 1075 buf.append(key).append("=").append(options.getProperty(key)).append("\n"); 1076 } 1077 return buf.toString(); 1078 } 1079 } 1080 1081 public static class ExistingRealm implements Serializable { 1082 private final String name; 1083 private final String abstractName; 1084 private final String parentName; 1085 private final int state; 1086 1087 public ExistingRealm(String name, AbstractName abstractName, int state, String parent) { 1088 this.name = name; 1089 this.abstractName = abstractName.toString(); 1090 parentName = parent; 1091 this.state = state; 1092 1093 } 1094 1095 public String getName() { 1096 return name; 1097 } 1098 1099 public String getAbstractName() { 1100 return abstractName; 1101 } 1102 1103 public String getParentName() { 1104 return parentName; 1105 } 1106 1107 public int getState() { 1108 return state; 1109 } 1110 1111 public String getStateName() { 1112 return State.toString(state); 1113 } 1114 } 1115 1116 public static class DatabasePool implements Serializable , Comparable { 1117 private final String name; 1118 private final String displayName; 1119 private final String applicationName; 1120 private final String abstractName; 1121 1122 public DatabasePool(String name, String displayName, String applicationName, AbstractName abstractName) { 1123 this.name = name; 1124 this.displayName = displayName; 1125 this.applicationName = applicationName; 1126 this.abstractName = abstractName.toString(); 1127 } 1128 1129 public String getName() { 1130 return name; 1131 } 1132 1133 public String getApplicationName() { 1134 return applicationName; 1135 } 1136 1137 public String getAbstractName() { 1138 return abstractName; 1139 } 1140 1141 public String getDisplayName() { 1142 return displayName; 1143 } 1144 1145 public int compareTo(Object o) { 1146 final DatabasePool pool = (DatabasePool) o; 1147 int names = name.compareTo(pool.name); 1148 if (applicationName == null) { 1149 if (pool.applicationName == null) { 1150 return names; 1151 } else { 1152 return -1; 1153 } 1154 } else { 1155 if (pool.applicationName == null) { 1156 return 1; 1157 } else { 1158 int test = applicationName.compareTo(pool.applicationName); 1159 if (test != 0) { 1160 return test; 1161 } else { 1162 return names; 1163 } 1164 } 1165 } 1166 } 1167 } 1168} | Popular Tags |