Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 81142 invoked from network); 30 Sep 2007 12:48:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 30 Sep 2007 12:48:20 -0000 Received: (qmail 90222 invoked by uid 500); 30 Sep 2007 12:48:09 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 90214 invoked by uid 500); 30 Sep 2007 12:48:09 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 90203 invoked by uid 99); 30 Sep 2007 12:48:09 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 30 Sep 2007 05:48:09 -0700 X-ASF-Spam-Status: No, hits=-98.8 required=10.0 tests=ALL_TRUSTED,DNS_FROM_DOB,RCVD_IN_DOB X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 30 Sep 2007 12:48:18 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 502461A9838; Sun, 30 Sep 2007 05:47:58 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r580717 - in /geronimo/sandbox/gshell/trunk/gshell-remote: gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/ gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ gshell-remote-client/s... Date: Sun, 30 Sep 2007 12:47:56 -0000 To: scm@geronimo.apache.org From: jdillon@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20070930124758.502461A9838@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jdillon Date: Sun Sep 30 05:47:55 2007 New Revision: 580717 URL: http://svn.apache.org/viewvc?rev=580717&view=rev Log: Adding crude JAAS support, which has been inspired/based-on the openejb3 client login module Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf (with props) Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServer.java geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/handler/LoginHandler.java Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java?rev=580717&r1=580716&r2=580717&view=diff ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java (original) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java Sun Sep 30 05:47:55 2007 @@ -25,14 +25,20 @@ import java.security.PublicKey; import java.util.List; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; + +import org.apache.geronimo.gshell.remote.client.auth.RemoteLoginModule; import org.apache.geronimo.gshell.remote.client.handler.ClientMessageHandler; import org.apache.geronimo.gshell.remote.client.handler.ClientSessionContext; import org.apache.geronimo.gshell.remote.crypto.CryptoContext; +import org.apache.geronimo.gshell.remote.jaas.JaasConfigurationHelper; +import org.apache.geronimo.gshell.remote.jaas.UsernamePasswordCallbackHandler; import org.apache.geronimo.gshell.remote.message.CloseShellMessage; import org.apache.geronimo.gshell.remote.message.ConnectMessage; import org.apache.geronimo.gshell.remote.message.EchoMessage; import org.apache.geronimo.gshell.remote.message.ExecuteMessage; -import org.apache.geronimo.gshell.remote.message.LoginMessage; import org.apache.geronimo.gshell.remote.message.OpenShellMessage; import org.apache.geronimo.gshell.whisper.message.Message; import org.apache.geronimo.gshell.whisper.transport.Transport; @@ -44,6 +50,8 @@ import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.InstantiationStrategy; import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,6 +62,7 @@ */ @Component(role=RshClient.class, instantiationStrategy=InstantiationStrategy.PER_LOOKUP) public class RshClient + implements Initializable { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -68,6 +77,10 @@ private Transport transport; + public void initialize() throws InitializationException { + new JaasConfigurationHelper("client.login.conf").initialize(); + } + public void connect(final URI remote, final URI local) throws Exception { TransportFactory factory = locator.locate(remote); @@ -105,19 +118,19 @@ PublicKey serverKey = ((ConnectMessage.Result)response).getPublicKey(); log.debug("Logging in: {}", username); + + CallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(username, password); + LoginContext loginContext = new LoginContext("RshClient", callbackHandler); - response = transport.request(new LoginMessage(username, password)); - - if (response instanceof LoginMessage.Success) { - log.debug("Login successful"); - } - else if (response instanceof LoginMessage.Failure) { - LoginMessage.Failure failure = (LoginMessage.Failure)response; + RemoteLoginModule.setTransport(transport); + try { + loginContext.login(); - throw new Exception("Login failed: " + failure.getReason()); + Subject subject = loginContext.getSubject(); + log.debug("Subject: {}", subject); } - else { - throw new InternalError(); + finally { + RemoteLoginModule.unsetTransport(); } } @@ -211,7 +224,7 @@ // Complain if we don't have any handlers if (handlers.isEmpty()) { - throw new Error("No client message handlers were discovered"); + throw new Error("No message handlers were discovered"); } for (ClientMessageHandler handler : handlers) { Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java?rev=580717&r1=580716&r2=580717&view=diff ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java (original) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java Sun Sep 30 05:47:55 2007 @@ -22,8 +22,10 @@ import java.net.URI; import java.util.ArrayList; import java.util.List; +import java.io.PrintWriter; import jline.Terminal; +import jline.ConsoleReader; import org.apache.geronimo.gshell.ExitNotification; import org.apache.geronimo.gshell.clp.Argument; import org.apache.geronimo.gshell.clp.Option; @@ -44,10 +46,10 @@ @Option(name="-b", aliases={"--bind"}, metaVar="URI") private URI local; - @Option(name="-u", aliases={"--username"}, metaVar="USERNAME", required=true) + @Option(name="-u", aliases={"--username"}, metaVar="USERNAME") private String username; - @Option(name="-p", aliases={"--password"}, metaVar="PASSWORD", required=true) + @Option(name="-p", aliases={"--password"}, metaVar="PASSWORD") private String password; @Argument(metaVar="URI", required=true, index=0) @@ -69,9 +71,22 @@ io.info("Connected"); - // - // TODO: Allow username and/or password to be read from input, need access to the console instance to get password reading working - // + // If the username/password was not configured via cli, then prompt the user for the values + if (username == null || password == null) { + ConsoleReader reader = new ConsoleReader(io.inputStream, new PrintWriter(io.outputStream, true), /*bindings*/null, terminal); + + if (username == null) { + username = reader.readLine("Username: "); + } + + if (password == null) { + password = reader.readLine("Password: ", '*'); + } + + // + // TODO: Handle null inputs... + // + } client.login(username, password); Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java Sun Sep 30 05:47:55 2007 @@ -0,0 +1,42 @@ +package org.apache.geronimo.gshell.remote.client.auth; + +import java.security.Principal; +import java.io.Serializable; + +import org.apache.geronimo.gshell.common.tostring.ReflectionToStringBuilder; +import org.apache.geronimo.gshell.common.tostring.ToStringStyle; + +/** + * ??? + * + * @version $Rev$ $Date$ + */ +public class ClientPrincipal + implements Principal, Serializable +{ + private static final long serialVersionUID = 1; + + private final String name; + + private final Object identity; + + public ClientPrincipal(final String name, final Object identity) { + assert name != null; + assert identity != null; + + this.name = name; + this.identity = identity; + } + + public String getName() { + return name; + } + + public Object getIdentity() { + return identity; + } + + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } +} Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/ClientPrincipal.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java Sun Sep 30 05:47:55 2007 @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.geronimo.gshell.remote.client.auth; + +import java.io.IOException; +import java.security.Principal; +import java.util.Map; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +import org.apache.geronimo.gshell.remote.message.LoginMessage; +import org.apache.geronimo.gshell.whisper.message.Message; +import org.apache.geronimo.gshell.whisper.transport.Transport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * ??? + * + * @version $Rev$ $Date$ + */ +public class RemoteLoginModule + implements LoginModule +{ + private final Logger log = LoggerFactory.getLogger(getClass()); + + private Subject subject; + + private CallbackHandler callbackHandler; + + private String username; + + private Object clientIdentity; + + private Principal principal; + + public void initialize(final Subject subject, final CallbackHandler callbackHandler, final Map sharedState, final Map options) { + this.subject = subject; + this.callbackHandler = callbackHandler; + } + + private void clear() { + username = null; + clientIdentity = null; + principal = null; + } + + public boolean login() throws LoginException { + log.debug("Login"); + + // Get a handle on our transport + Transport transport = getTransport(); + + // Process the username + password callbacks + Callback[] callbacks = { + new NameCallback("Username: "), + new PasswordCallback("Password: ", false) + }; + + try { + callbackHandler.handle(callbacks); + } + catch (IOException e) { + throw new LoginException(e.getMessage()); + } + catch (UnsupportedCallbackException e) { + throw new LoginException(e.getMessage()); + } + + username = ((NameCallback)callbacks[0]).getName(); + char[] password = ((PasswordCallback) callbacks[1]).getPassword(); + + // Send the login message + Message response; + try { + // + // TODO: Encrypt the username/password with our private key here? Or should that be done in the callback? + // + + response = transport.request(new LoginMessage(username, new String(password))); + } + catch (Exception e) { + throw new LoginException(e.getMessage()); + } + + if (response instanceof LoginMessage.Success) { + log.debug("Login successful"); + + clientIdentity = ((LoginMessage.Success)response).getToken(); + + log.debug("Using client identity: {}", clientIdentity); + } + else if (response instanceof LoginMessage.Failure) { + LoginMessage.Failure failure = (LoginMessage.Failure)response; + + throw new LoginException("Login failed: " + failure.getReason()); + } + + return true; + } + + public boolean commit() throws LoginException { + log.debug("Commit"); + + principal = new ClientPrincipal(username, clientIdentity); + + log.debug("Created principal: {}", principal); + + subject.getPrincipals().add(principal); + + return true; + } + + public boolean abort() throws LoginException { + log.debug("Abort"); + + clear(); + + return true; + } + + public boolean logout() throws LoginException { + log.debug("Logout"); + + subject.getPrincipals().remove(principal); + + return true; + } + + // + // HACK: Transport access + // + + private static final ThreadLocal transportHolder = new ThreadLocal(); + + public static void setTransport(final Transport transport) { + assert transport != null; + + transportHolder.set(transport); + } + + public static void unsetTransport() { + transportHolder.remove(); + } + + private static Transport getTransport() { + Transport transport = transportHolder.get(); + + if (transport == null) { + throw new IllegalStateException("Transport has not been bound to the executing thread"); + } + + return transport; + } +} Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/auth/RemoteLoginModule.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf Sun Sep 30 05:47:55 2007 @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// +// $Rev$ $Date$ +// + +RshClient { + org.apache.geronimo.gshell.remote.client.auth.RemoteLoginModule required; +}; Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/resources/client.login.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java Sun Sep 30 05:47:55 2007 @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.geronimo.gshell.remote.jaas; + +import java.security.Principal; + +import org.apache.geronimo.gshell.common.tostring.ReflectionToStringBuilder; +import org.apache.geronimo.gshell.common.tostring.ToStringStyle; + +/** + * ??? + * + * @version $Rev$ $Date$ + */ +public class GroupPrincipal + implements Principal +{ + private final String name; + + public GroupPrincipal(final String name) { + assert name != null; + + this.name = name; + } + + public String getName() { + return name; + } + + public boolean equals(final Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + final GroupPrincipal that = (GroupPrincipal) obj; + + return name.equals(that.name); + } + + public int hashCode() { + return name.hashCode(); + } + + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } +} \ No newline at end of file Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/GroupPrincipal.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java Sun Sep 30 05:47:55 2007 @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.geronimo.gshell.remote.jaas; + +import java.net.URL; + +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * ??? + * + * @version $Rev$ $Date$ + */ +@Component(role=JaasConfigurationHelper.class) +public class JaasConfigurationHelper + implements Initializable +{ + private static final String KEY = "java.security.auth.login.config"; + + private final Logger log = LoggerFactory.getLogger(getClass()); + + // @Configuration + private String resourceName; + + public JaasConfigurationHelper(final String resourceName) { + this.resourceName = resourceName; + } + + public JaasConfigurationHelper() {} + + public void initialize() throws InitializationException { + // Initialize the JAAS configuration + String path = System.getProperty(KEY); + + if (path == null) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + URL resource = cl.getResource(resourceName); + + if (resource != null) { + path = resource.toExternalForm(); + System.setProperty(KEY, path); + } + } + + log.debug("Using JAAS login config: {}", path); + } +} \ No newline at end of file Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/JaasConfigurationHelper.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java Sun Sep 30 05:47:55 2007 @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.geronimo.gshell.remote.jaas; + +import java.security.Principal; + +import org.apache.geronimo.gshell.common.tostring.ReflectionToStringBuilder; +import org.apache.geronimo.gshell.common.tostring.ToStringStyle; + +/** + * ??? + * + * @version $Rev$ $Date$ + */ +public class UserPrincipal + implements Principal +{ + private final String name; + + public UserPrincipal(final String name) { + assert name != null; + + this.name = name; + } + + public String getName() { + return name; + } + + public boolean equals(final Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + final UserPrincipal that = (UserPrincipal) obj; + + return name.equals(that.name); + } + + public int hashCode() { + return name.hashCode(); + } + + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } +} \ No newline at end of file Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UserPrincipal.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java Sun Sep 30 05:47:55 2007 @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.geronimo.gshell.remote.jaas; + +import java.io.IOException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +/** + * ??? + * + * @version $Rev$ $Date$ + */ +public class UsernamePasswordCallbackHandler + implements CallbackHandler +{ + private final String username; + + private final String password; + + public UsernamePasswordCallbackHandler(final String username, final String password) { + this.username = username; + this.password = password; + } + + public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + NameCallback nc = (NameCallback)callback; + + nc.setName(username); + } + else if (callback instanceof PasswordCallback) { + PasswordCallback pc = (PasswordCallback)callback; + + if (password != null) { + pc.setPassword(password.toCharArray()); + } + else { + pc.setPassword(null); + } + } + else { + throw new UnsupportedCallbackException(callback); + } + } + } +} Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/jaas/UsernamePasswordCallbackHandler.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java?rev=580717&r1=580716&r2=580717&view=diff ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java (original) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java Sun Sep 30 05:47:55 2007 @@ -20,6 +20,7 @@ package org.apache.geronimo.gshell.remote.message; import java.security.PublicKey; +import java.io.Serializable; /** * Contains the user authentication details which the client will pass to the server after the @@ -87,8 +88,16 @@ public static class Success extends RshMessage { - public Success() { + private Serializable token; + + public Success(Serializable token) { super(Type.LOGIN_SUCCESS); + + this.token = token; + } + + public Serializable getToken() { + return token; } } Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServer.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServer.java?rev=580717&r1=580716&r2=580717&view=diff ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServer.java (original) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServer.java Sun Sep 30 05:47:55 2007 @@ -88,7 +88,7 @@ // Complain if we don't have any handlers if (handlers.isEmpty()) { - throw new Error("No server message handlers were discovered"); + throw new Error("No message handlers were discovered"); } for (ServerMessageHandler handler : handlers) { Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java Sun Sep 30 05:47:55 2007 @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.geronimo.gshell.remote.server.auth; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.geronimo.gshell.remote.jaas.UserPrincipal; + +/** + * ??? + * + * @version $Rev$ $Date$ + */ +public class BogusLoginModule + implements LoginModule +{ + private final Logger log = LoggerFactory.getLogger(getClass()); + + private Subject subject; + + private CallbackHandler callbackHandler; + + private Set principals = new HashSet(); + + private String username; + + public void initialize(final Subject subject, final CallbackHandler callbackHandler, final Map sharedState, final Map options) { + this.subject = subject; + this.callbackHandler = callbackHandler; + } + + private void clear() { + username = null; + } + + public boolean login() throws LoginException { + log.debug("Login"); + + // Process the username + password callbacks + Callback[] callbacks = { + new NameCallback("Username: "), + new PasswordCallback("Password: ", false) + }; + + try { + callbackHandler.handle(callbacks); + } + catch (IOException e) { + throw new LoginException(e.getMessage()); + } + catch (UnsupportedCallbackException e) { + throw new LoginException(e.getMessage()); + } + + username = ((NameCallback)callbacks[0]).getName(); + char[] passwd = ((PasswordCallback) callbacks[1]).getPassword(); + + if ("bogus".equals(username)) { + throw new FailedLoginException("Invalid username: " + username); + } + else if ("bogus".equals(new String(passwd))) { + throw new FailedLoginException("Invalid password"); + } + + return true; + } + + public boolean commit() throws LoginException { + log.debug("Commit"); + + principals.add(new UserPrincipal(username)); + + subject.getPrincipals().addAll(principals); + + clear(); + + return true; + } + + public boolean abort() throws LoginException { + log.debug("Abort"); + + clear(); + + return true; + } + + public boolean logout() throws LoginException { + log.debug("Logout"); + + subject.getPrincipals().removeAll(principals); + + principals.clear(); + + clear(); + + return true; + } +} \ No newline at end of file Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/auth/BogusLoginModule.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/handler/LoginHandler.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/handler/LoginHandler.java?rev=580717&r1=580716&r2=580717&view=diff ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/handler/LoginHandler.java (original) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/handler/LoginHandler.java Sun Sep 30 05:47:55 2007 @@ -19,12 +19,23 @@ package org.apache.geronimo.gshell.remote.server.handler; +import java.io.Serializable; +import java.util.UUID; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +import org.apache.geronimo.gshell.remote.jaas.UsernamePasswordCallbackHandler; +import org.apache.geronimo.gshell.remote.jaas.JaasConfigurationHelper; import org.apache.geronimo.gshell.remote.message.LoginMessage; import org.apache.geronimo.gshell.remote.message.RshMessage; import org.apache.geronimo.gshell.remote.server.timeout.TimeoutManager; import org.apache.mina.common.IoSession; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; /** * ??? @@ -34,6 +45,7 @@ @Component(role=ServerMessageHandler.class, hint="login") public class LoginHandler extends ServerMessageHandlerSupport + implements Initializable { @Requirement private TimeoutManager timeoutManager; @@ -41,28 +53,68 @@ public LoginHandler() { super(RshMessage.Type.LOGIN); } - + + public void initialize() throws InitializationException { + new JaasConfigurationHelper("server.login.conf").initialize(); + } + public void handle(final IoSession session, final ServerSessionContext context, final LoginMessage message) throws Exception { // Try to cancel the timeout task if (!timeoutManager.cancelTimeout(session)) { log.warn("Aborting login processing; timeout has triggered"); } else { + String realm = "BogusLogin"; String username = message.getUsername(); String password = message.getPassword(); - // - // TODO: Add JAAC Crapo here... - // - - // Remember our username - context.username = username; - - log.info("Successfull authentication for user: {}, at location: {}", username, session.getRemoteAddress()); - - LoginMessage.Success reply = new LoginMessage.Success(); - reply.setCorrelationId(message.getId()); - session.write(reply); + try { + LoginContext loginContext = new LoginContext(realm, new UsernamePasswordCallbackHandler(username, password)); + loginContext.login(); + + Subject subject = loginContext.getSubject(); + Identity identity = new Identity(subject); + + log.debug("Created client identity: {}", identity.getToken()); + + // + // TODO: Hold onto the subject, identity and username, blah, blah? + // + + log.info("Successfull authentication for user: {}", username); + + LoginMessage.Success reply = new LoginMessage.Success(identity.getToken()); + reply.setCorrelationId(message.getId()); + session.write(reply); + } + catch (LoginException e) { + String reason = e.toString(); + log.info("Login failed for user: {}, cause: {}", username, reason); + + LoginMessage.Failure reply = new LoginMessage.Failure(reason); + reply.setCorrelationId(message.getId()); + session.write(reply); + } + } + } + + private static class Identity + { + private final Subject subject; + + private final UUID token; + + public Identity(final Subject subject) { + this.subject = subject; + this.token = UUID.randomUUID(); + } + + public Subject getSubject() { + return subject; + } + + public Serializable getToken() { + return token; } } } Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf?rev=580717&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf Sun Sep 30 05:47:55 2007 @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// +// $Rev$ $Date$ +// + +BogusLogin { + org.apache.geronimo.gshell.remote.server.auth.BogusLoginModule required; +}; Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/resources/server.login.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain