Package com.cubusmail.server.mail.security

Source Code of com.cubusmail.server.mail.security.MailboxLoginModule

/* MailboxLoginModule.java

   Copyright (c) 2009 Juergen Schlierf, All Rights Reserved
  
   This file is part of Cubusmail (http://code.google.com/p/cubusmail/).
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.
 
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
 
   You should have received a copy of the GNU Lesser General Public
   License along with Cubusmail. If not, see <http://www.gnu.org/licenses/>.
  
*/
package com.cubusmail.server.mail.security;

import java.io.IOException;
import java.util.Map;

import javax.mail.AuthenticationFailedException;
import javax.mail.MessagingException;
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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.cubusmail.server.mail.IMailbox;
import com.cubusmail.server.mail.MailboxFactory;
import com.cubusmail.server.mail.SessionManager;
import com.cubusmail.server.mail.exceptions.IErrorCodes;

/**
* LoginModule for the login procedure.
*
* @author Juergen Schlierf
*/
public class MailboxLoginModule implements LoginModule {

  private final Log log = LogFactory.getLog( getClass() );

  // initial state
  private Subject subject;
  private CallbackHandler callbackHandler;

  // the authentication status
  private boolean succeeded = false;
  private boolean commitSucceeded = false;

  private MailboxPrincipal mailboxPrincipal;

  /*
   * (non-Javadoc)
   *
   * @see
   * javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject
   * , javax.security.auth.callback.CallbackHandler, java.util.Map,
   * java.util.Map)
   */
  public void initialize( Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
      Map<String, ?> options ) {

    this.subject = subject;
    this.callbackHandler = callbackHandler;
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.security.auth.spi.LoginModule#login()
   */
  public boolean login() throws LoginException {

    if ( this.callbackHandler == null ) {
      log.fatal( "callbackHandler is null" );
      throw new LoginException( IErrorCodes.EXCEPTION_AUTHENTICATION_FAILED );
    }

    Callback[] callbacks = new Callback[2];
    callbacks[0] = new NameCallback( "Username" );
    callbacks[1] = new PasswordCallback( "Password", false );

    try {
      this.callbackHandler.handle( callbacks );
      String username = ((NameCallback) callbacks[0]).getName();

      char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
      if ( tmpPassword == null ) {
        // treat a NULL password as an empty password
        tmpPassword = new char[0];
      }
      char[] password = new char[tmpPassword.length];
      System.arraycopy( tmpPassword, 0, password, 0, tmpPassword.length );
      ((PasswordCallback) callbacks[1]).clearPassword();

      // start authentication
      // TODO: very dirty, must be replaced by Spring Security stuff
      ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext( SessionManager
          .getRequest().getSession().getServletContext() );
      MailboxFactory factory = context.getBean( MailboxFactory.class );
      IMailbox mailbox = factory.createMailbox( IMailbox.TYPE_IMAP );
      mailbox.init( username, new String( password ) );

      log.debug( "Start login..." );
      mailbox.login();
      log.debug( "Login successful" );

      this.mailboxPrincipal = new MailboxPrincipal( username, mailbox );
      this.succeeded = true;
    }
    catch (IOException ioe) {
      log.error( ioe.getMessage(), ioe );
      throw new LoginException( ioe.toString() );
    }
    catch (UnsupportedCallbackException uce) {
      log.error( uce.getMessage(), uce );
      throw new LoginException( IErrorCodes.EXCEPTION_AUTHENTICATION_FAILED );
    }
    catch (MessagingException e) {
      log.error( e.getMessage(), e );
      mapMessagingException( e );
    }

    return this.succeeded;
  }

  /**
   * Map a MessagingException to a LoginException.
   *
   * @param e
   * @throws LoginException
   */
  private void mapMessagingException( MessagingException e ) throws LoginException {

    if ( e instanceof AuthenticationFailedException ) {
      throw new LoginException( IErrorCodes.EXCEPTION_AUTHENTICATION_FAILED );
    }
    else if ( e.getCause() != null && e.getCause() instanceof java.net.ConnectException ) {
      throw new LoginException( IErrorCodes.EXCEPTION_CONNECT );
    }
    else {
      throw new LoginException( IErrorCodes.EXCEPTION_GENERAL );
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.security.auth.spi.LoginModule#commit()
   */
  public boolean commit() throws LoginException {

    if ( this.succeeded ) {
      if ( !subject.getPrincipals().contains( this.mailboxPrincipal ) ) {
        subject.getPrincipals().add( this.mailboxPrincipal );
      }
      this.commitSucceeded = true;
      return this.commitSucceeded;
    }
    else {
      return false;
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.security.auth.spi.LoginModule#abort()
   */
  public boolean abort() throws LoginException {

    return true;
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.security.auth.spi.LoginModule#logout()
   */
  public boolean logout() throws LoginException {

    log.debug( "Start logout..." );
    try {
      SecurityUtils.getMailboxPrincipal( this.subject ).getMailbox().logout();
    }
    catch (MessagingException e) {
      // nothing to do
      log.warn( e.getMessage() );
    }
    log.debug( "Logout successful" );

    this.subject.getPrincipals().remove( SecurityUtils.getMailboxPrincipal( this.subject ) );

    return true;
  }
}
TOP

Related Classes of com.cubusmail.server.mail.security.MailboxLoginModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.