Coverage Report - org.mule.extras.jaas.loginmodule.DefaultLoginModule
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultLoginModule
81%
71/88
60%
35/58
6.333
 
 1  
 /*
 2  
  * $Id: DefaultLoginModule.java 8467 2007-09-18 11:44:20Z marie.rizzo $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.extras.jaas.loginmodule;
 12  
 
 13  
 import org.mule.extras.jaas.MuleJaasPrincipal;
 14  
 
 15  
 import java.io.IOException;
 16  
 import java.util.List;
 17  
 import java.util.Map;
 18  
 import java.util.Set;
 19  
 import java.util.Vector;
 20  
 
 21  
 import javax.security.auth.Subject;
 22  
 import javax.security.auth.callback.Callback;
 23  
 import javax.security.auth.callback.CallbackHandler;
 24  
 import javax.security.auth.callback.NameCallback;
 25  
 import javax.security.auth.callback.PasswordCallback;
 26  
 import javax.security.auth.callback.UnsupportedCallbackException;
 27  
 import javax.security.auth.login.FailedLoginException;
 28  
 import javax.security.auth.login.LoginException;
 29  
 import javax.security.auth.spi.LoginModule;
 30  
 
 31  
 /**
 32  
  * This is the Default Login Module for the Mule Jaas Authentication.
 33  
  * It extends Jaas' own LoginModule interface.
 34  
  */
 35  20
 public class DefaultLoginModule implements LoginModule
 36  
 {
 37  
 
 38  
     // Callback Handlers
 39  
     private CallbackHandler callbackHandler;
 40  
 
 41  
     // the authentication status
 42  20
     private boolean succeeded = false;
 43  20
     private boolean commitSucceeded = false;
 44  
 
 45  
     // username and password
 46  
     private String username;
 47  
     private String password;
 48  
     private String credentials;
 49  
     private List credentialList;
 50  
     private Subject subject;
 51  
 
 52  
     /**
 53  
      * Abort if authentication fails
 54  
      * 
 55  
      * @return boolean
 56  
      * @throws LoginException
 57  
      */
 58  
     public final boolean abort() throws LoginException
 59  
     {
 60  12
         if (!succeeded)
 61  
         {
 62  12
             return false;
 63  
         }
 64  0
         else if (succeeded && !commitSucceeded)
 65  
         {
 66  
             // login succeeded but overall authentication failed
 67  0
             succeeded = false;
 68  0
             username = null;
 69  0
             if (password != null)
 70  
             {
 71  0
                 password = null;
 72  
             }
 73  
         }
 74  
         else
 75  
         {
 76  
             // overall authentication succeeded and commit succeeded,
 77  
             // but someone else's commit failed
 78  0
             logout();
 79  
         }
 80  0
         return true;
 81  
     }
 82  
 
 83  
     /**
 84  
      * Commit if authentication succeeds, otherwise return false
 85  
      * 
 86  
      * @return boolean
 87  
      * @throws LoginException
 88  
      */
 89  
     public final boolean commit() throws LoginException
 90  
     {
 91  8
         if (!succeeded)
 92  
         {
 93  0
             return false;
 94  
         }
 95  
         else
 96  
         {
 97  
             // set the principal just authenticated in the subject
 98  8
             if (subject == null) 
 99  
             {
 100  0
                 return false;
 101  
             }
 102  8
             MuleJaasPrincipal principal = new MuleJaasPrincipal(username); 
 103  8
             Set entities = subject.getPrincipals();
 104  8
             if (!entities.contains(principal))
 105  
             {
 106  8
               entities.add(principal);
 107  
             }
 108  
 
 109  
             // in any case, clean out state
 110  8
             username = null;
 111  8
             password = null;
 112  8
             commitSucceeded = true;
 113  8
             return true;
 114  
         }
 115  
     }
 116  
     
 117  
     /**
 118  
      * Initialises the callbackHandler, the credentials and the credentials list
 119  
      * 
 120  
      * @param subject
 121  
      * @param callbackHandler
 122  
      * @param sharedState
 123  
      * @param options
 124  
      */
 125  
     public final void initialize(Subject subject,
 126  
                                  CallbackHandler callbackHandler,
 127  
                                  Map sharedState,
 128  
                                  Map options)
 129  
     {
 130  20
         this.subject = subject;
 131  20
         this.callbackHandler = callbackHandler;
 132  
 
 133  20
         this.credentials = (String) options.get("credentials");
 134  20
         this.credentialList = getCredentialList(this.credentials);
 135  20
     }
 136  
 
 137  
     /**
 138  
      * This method attempts to login the user by checking his credentials against
 139  
      * those of the authorised users.
 140  
      * 
 141  
      * @throws LoginException This is thrown either when there is no callback Handler
 142  
      *             or else when the user fails to be authenticated
 143  
      */
 144  
     public final boolean login() throws LoginException
 145  
     {
 146  20
         if (callbackHandler == null)
 147  
         {
 148  0
             throw new LoginException("Error: no CallbackHandler available "
 149  
                                      + "to garner authentication information from the user");
 150  
         }
 151  
 
 152  20
         if (callbackHandler == null)
 153  
         {
 154  0
             throw new LoginException("no handler");
 155  
         }
 156  
 
 157  20
         NameCallback nameCb = new NameCallback("user: ");
 158  20
         PasswordCallback passCb = new PasswordCallback("password: ", true);
 159  
 
 160  
         // Create the callbacks to send to the Callback Handler
 161  20
         Callback[] callbacks = new Callback[]{nameCb, passCb};
 162  
 
 163  
         // Call the handler to get the username and password of the user.
 164  
         try
 165  
         {
 166  20
             callbackHandler.handle(callbacks);
 167  
         }
 168  0
         catch (IOException e)
 169  
         {
 170  0
             throw new LoginException(e.toString());
 171  
         }
 172  0
         catch (UnsupportedCallbackException e)
 173  
         {
 174  0
             throw new LoginException("Error: " + e.getCallback().toString()
 175  
                                      + " not available to garner authentication information "
 176  
                                      + "from the user");
 177  20
         }
 178  
 
 179  20
         username = nameCb.getName();
 180  20
         password = new String(passCb.getPassword());
 181  
 
 182  20
         boolean usernameCorrect = false;
 183  20
         boolean passwordCorrect = false;
 184  20
         succeeded = false;
 185  
 
 186  
         // check the username and password against the list of authorised users
 187  60
         for (int i = 0; i < credentialList.size(); i = i + 2)
 188  
         {
 189  40
             if (username.equals(credentialList.get(i).toString()))
 190  
             {
 191  16
                 usernameCorrect = true;
 192  
             }
 193  
             else
 194  
             {
 195  24
                 usernameCorrect = false;
 196  
             }
 197  
 
 198  40
             if (password.equals(credentialList.get(i + 1).toString()))
 199  
             {
 200  16
                 passwordCorrect = true;
 201  
             }
 202  
             else
 203  
             {
 204  24
                 passwordCorrect = false;
 205  
             }
 206  
 
 207  
             // only if both the username and password are correct will the user be
 208  
             // authenticated
 209  40
             if ((usernameCorrect) & (passwordCorrect))
 210  
             {
 211  8
                 succeeded = true;
 212  
             }
 213  
         }
 214  
 
 215  20
         if (succeeded)
 216  
         {
 217  8
             return true;
 218  
         }
 219  
         else
 220  
         {
 221  12
             succeeded = false;
 222  12
             username = null;
 223  12
             password = null;
 224  12
             if (!usernameCorrect)
 225  
             {
 226  4
                 throw new FailedLoginException("User Name Incorrect");
 227  
             }
 228  
             else
 229  
             {
 230  8
                 throw new FailedLoginException("Password Incorrect");
 231  
             }
 232  
         }
 233  
     }
 234  
     
 235  
     /**
 236  
      * Returns true when authentication succeeds or false when it fails
 237  
      * 
 238  
      * @return succeeded
 239  
      */
 240  
     public final boolean logout()
 241  
     {
 242  0
         return succeeded;
 243  
     }
 244  
 
 245  
     /**
 246  
      * This method parses the credentials string and populates the credentials list
 247  
      * against which the username and password submitted with the request will be
 248  
      * checked
 249  
      * 
 250  
      * @param credentials
 251  
      * @return outputList
 252  
      */
 253  
     public final List getCredentialList(String credentials)
 254  
     {
 255  20
         boolean semicolonIsFound = false;
 256  20
         boolean dividerIsFound = false;
 257  20
         char[] credentialArray = credentials.toCharArray();
 258  20
         String username = "";
 259  20
         String password = "";
 260  20
         List outputList = new Vector();
 261  
 
 262  600
         for (int i = 0; i < credentials.length(); i++)
 263  
         {
 264  580
             if ((credentialArray[i] != ':') && (!dividerIsFound))
 265  
             {
 266  300
                 username = username + credentialArray[i];
 267  
             }
 268  280
             else if ((credentialArray[i] == ':') && (!dividerIsFound))
 269  
             {
 270  40
                 dividerIsFound = true;
 271  
             }
 272  240
             else if ((credentialArray[i] != ';') && (!semicolonIsFound) && (dividerIsFound))
 273  
             {
 274  200
                 password = password + credentialArray[i];
 275  
             }
 276  40
             else if ((credentialArray[i] != ';') && (!semicolonIsFound) && (dividerIsFound))
 277  
             {
 278  0
                 password = password + credentialArray[i];
 279  
             }
 280  40
             else if ((credentialArray[i] == ';') && (!semicolonIsFound) && (dividerIsFound))
 281  
             {
 282  40
                 outputList.add(username);
 283  40
                 outputList.add(password);
 284  40
                 semicolonIsFound = false;
 285  40
                 dividerIsFound = false;
 286  40
                 username = "";
 287  40
                 password = "";
 288  
             }
 289  
         }
 290  20
         return outputList;
 291  
     }
 292  
 }