Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 49510 invoked from network); 18 Sep 2007 15:38:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 18 Sep 2007 15:38:45 -0000 Received: (qmail 45376 invoked by uid 500); 18 Sep 2007 15:38:37 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 45231 invoked by uid 500); 18 Sep 2007 15:38:36 -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 45220 invoked by uid 99); 18 Sep 2007 15:38:36 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 18 Sep 2007 08:38:36 -0700 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED 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; Tue, 18 Sep 2007 15:38:44 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C47A11A9832; Tue, 18 Sep 2007 08:38:23 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r576952 - in /geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote: filter/ security/ Date: Tue, 18 Sep 2007 15:38:23 -0000 To: scm@geronimo.apache.org From: jdillon@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20070918153823.C47A11A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jdillon Date: Tue Sep 18 08:38:22 2007 New Revision: 576952 URL: http://svn.apache.org/viewvc?rev=576952&view=rev Log: Put all of the security related bits in one package Adding an uber stupid abstraction for user auth for now Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/BogusUserAuthenticator.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/SecurityFilter.java (contents, props changed) - copied, changed from r576852, geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/filter/AuthenticationFilter.java geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/UserAuthenticator.java (with props) geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/package-info.java (with props) Removed: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/filter/AuthenticationFilter.java Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/BogusUserAuthenticator.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/BogusUserAuthenticator.java?rev=576952&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/BogusUserAuthenticator.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/BogusUserAuthenticator.java Tue Sep 18 08:38:22 2007 @@ -0,0 +1,59 @@ +/* + * 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.security; + +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A super bogus user authenticator which simply agrees to anything you give it, + * unless the username or password is "bogus", which it will reject. + * + * @version $Rev$ $Date$ + */ +@Component(role=UserAuthenticator.class, hint="bogus") +public class BogusUserAuthenticator + implements UserAuthenticator +{ + private Logger log = LoggerFactory.getLogger(getClass()); + + // + // TODO: Maybe we can use some JAAS crap or something instead of this... ? + // + + public boolean authenticate(final String username, final String password) { + assert username != null; + assert password != null; + + log.info("Authenticating; username={}, password={}", username, StringUtils.repeat("*", password.length())); + + // Unless the username or password is "bogus", then successfully authenticate + if ("bogus".equals(username)) { + return false; + } + else if ("bogus".equals(password)) { + return false; + } + + return true; + } +} \ No newline at end of file Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/BogusUserAuthenticator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/BogusUserAuthenticator.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/security/BogusUserAuthenticator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Copied: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/SecurityFilter.java (from r576852, geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/filter/AuthenticationFilter.java) URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/SecurityFilter.java?p2=geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/SecurityFilter.java&p1=geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/filter/AuthenticationFilter.java&r1=576852&r2=576952&rev=576952&view=diff ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/filter/AuthenticationFilter.java (original) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/SecurityFilter.java Tue Sep 18 08:38:22 2007 @@ -17,23 +17,242 @@ * under the License. */ -package org.apache.geronimo.gshell.remote.filter; +package org.apache.geronimo.gshell.remote.security; +import java.security.PublicKey; +import java.util.UUID; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.apache.geronimo.gshell.remote.crypto.CryptoContext; +import org.apache.geronimo.gshell.remote.message.HandShakeMessage; +import org.apache.geronimo.gshell.remote.message.LoginMessage; +import org.apache.geronimo.gshell.remote.message.Message; import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * ??? + * Provides authentication and security support. * * @version $Rev$ $Date$ */ -public class AuthenticationFilter +@Component(role=SecurityFilter.class) +public class SecurityFilter extends IoFilterAdapter { - private Logger log = LoggerFactory.getLogger(getClass()); + public static final String NAME = "security"; + + private static final String AUTHENTICATED_KEY = SecurityFilter.class.getName() + ".authenticated"; + + private static final String REMOTE_PUBLIC_KEY_KEY = SecurityFilter.class.getName() + ".remotePublicKey"; + + private static final String TIMEOUT_TASK_KEY = TimeoutTask.class.getName(); + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Requirement + private CryptoContext crypto; + + @Requirement + private UserAuthenticator userAuthenticator; + + private final ScheduledThreadPoolExecutor scheduler; + + private final UUID securityToken; + + public SecurityFilter() throws Exception { + scheduler = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors()); + + // + // TODO: Create a token based on our public key er something, so we can better use it to determine session validitaty. + // + + securityToken = UUID.randomUUID(); + } + + public void init() throws Exception { + // Install the schedule purger to purge any cancelled tasks to prevent memory leaks + scheduler.scheduleWithFixedDelay(new SchedulePurgerTask(), 10000, 10000, TimeUnit.MILLISECONDS); + } + + public void destroy() throws Exception { + scheduler.shutdownNow(); + } + + public void sessionOpened(final NextFilter nextFilter, final IoSession session) throws Exception { + assert nextFilter != null; + assert session != null; + + // Schedule a task to timeout the handshake process + scheduleTimeout(session); + + nextFilter.sessionOpened(session); + } + + public void messageReceived(final NextFilter nextFilter, final IoSession session, final Object obj) throws Exception { + assert nextFilter != null; + assert session != null; + assert obj != null; + + UUID token = (UUID) session.getAttribute(AUTHENTICATED_KEY); + + // If the session is already authenticated, then pass on the message + if (securityToken.equals(token)) { + nextFilter.messageReceived(session, obj); + } + else if (token != null) { + log.error("Invalid security token: {}", token); + + session.close(); + } + else if (obj instanceof HandShakeMessage) { + doHandShake(session, (HandShakeMessage)obj); + } + else if (obj instanceof LoginMessage) { + doLogin(session, (LoginMessage)obj); + } + else { + // If we get to here, then the message is not valid, so complain, then kill the session + log.error("Unauthenticated message: {}", obj); + + session.close(); + } + } + + private void setSession(final IoSession session, final Message msg) { + assert session != null; + assert msg != null; + + // Prep the message for reply, this is normally done by the protocol handler, but that hasn't a chance to fire at this point + msg.setSession(session); + msg.freeze(); + } + + private void doHandShake(final IoSession session, final HandShakeMessage msg) throws Exception { + assert session != null; + assert msg != null; + + log.debug("Processing handshake"); + + setSession(session, msg); + + // Try to cancel the timeout task + if (!cancelTimeout(session)) { + log.warn("Aborting handshake processing; timeout has triggered"); + } + else { + PublicKey key = msg.getPublicKey(); + + // Stuff the remote public key into the session + session.setAttribute(REMOTE_PUBLIC_KEY_KEY, key); + + // + // TODO: Do we want to pass the client back some token which it needs to put onto messages that are sent for more security? + // + + // And then send back our public key to the remote client + msg.reply(new HandShakeMessage.Result(crypto.getPublicKey())); + + // Schedule a task to timeout the login process + scheduleTimeout(session); + } + } + + private void doLogin(final IoSession session, final LoginMessage msg) throws Exception { + assert session != null; + assert msg != null; + + log.debug("Processing login"); + + setSession(session, msg); + + // Try to cancel the timeout task + if (!cancelTimeout(session)) { + log.warn("Aborting login processing; timeout has triggered"); + } + else { + String username = msg.getUsername(); + String password = msg.getPassword(); + + if (!userAuthenticator.authenticate(username, password)) { + log.error("Authentication failed for user: {}, at location: {}", username, session.getRemoteAddress()); + + session.close(); + } + else { + // Mark the session as authenticated + session.setAttribute(AUTHENTICATED_KEY, securityToken); + + log.info("Successfull authentication for user: {}, at location: {}", username, session.getRemoteAddress()); + + msg.reply(new LoginMessage.Result()); + } + } + } // - // TODO: + // Timeout Support // + + private ScheduledFuture scheduleTimeout(final IoSession session, final long l, final TimeUnit unit) { + assert session != null; + + ScheduledFuture task = scheduler.schedule(new TimeoutTask(session), l, unit); + session.setAttribute(TIMEOUT_TASK_KEY, task); + + return task; + } + + private ScheduledFuture scheduleTimeout(final IoSession session) { + return scheduleTimeout(session, 5000, TimeUnit.MILLISECONDS); + } + + private boolean cancelTimeout(final IoSession session) { + assert session != null; + + ScheduledFuture timeoutTask = (ScheduledFuture) session.getAttribute(TIMEOUT_TASK_KEY); + + return timeoutTask.cancel(false); + } + + /** + * Task to timeout sessions which fail to handshake or authenticate in a timely manner. + */ + private class TimeoutTask + implements Runnable + { + private final IoSession session; + + public TimeoutTask(final IoSession session) { + assert session != null; + + this.session = session; + } + + public void run() { + log.error("Timeout waiting for handshake or authentication from: " + session.getRemoteAddress()); + + session.close(); + } + } + + // + // SchedulePurgerTask + // + + /** + * Task to remove cancelled tasks from the scheduler + */ + private class SchedulePurgerTask + implements Runnable + { + public void run() { + scheduler.purge(); + } + } } Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/SecurityFilter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/SecurityFilter.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/security/SecurityFilter.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/UserAuthenticator.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/UserAuthenticator.java?rev=576952&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/UserAuthenticator.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/UserAuthenticator.java Tue Sep 18 08:38:22 2007 @@ -0,0 +1,30 @@ +/* + * 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.security; + +/** + * Provides a simple interface for user authentication. + * + * @version $Rev$ $Date$ + */ +public interface UserAuthenticator +{ + boolean authenticate(String username, String password); +} \ No newline at end of file Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/UserAuthenticator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/UserAuthenticator.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/security/UserAuthenticator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/package-info.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/package-info.java?rev=576952&view=auto ============================================================================== --- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/package-info.java (added) +++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/package-info.java Tue Sep 18 08:38:22 2007 @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/** + * Support for security and authentication. + * + * @version $Rev$ $Date$ + */ +package org.apache.geronimo.gshell.remote.security; \ No newline at end of file Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/package-info.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/security/package-info.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/security/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain