//Sample code file: var/ndk/webBuildengine/tmp/viewable_samples/a4ad0b48-dd95-46b6-8289-721e99c8dc76/login_method/lcm/java/src/com/novell/security/nmas/lcm/clrpwd/ClearPasswordLCM.java //Warning: This code has been marked up for HTML

/*=============================================================================
  ClearPasswordLCM.java

  Copyright (c) 2004 Novell, Inc.  All Rights Reserved.

  THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL PROPRIETARY
  AND TRADE SECRET INFORMATION OF NOVELL, INC. ACCESS TO THIS WORK IS
  RESTRICTED TO (I) NOVELL, INC. EMPLOYEES WHO HAVE A NEED TO KNOW HOW
  TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS AND (II)
  ENTITIES OTHER THAN NOVELL, INC. WHO HAVE ENTERED INTO APPROPRIATE
  LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
  PERFORMED COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
  CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST, TRANSFORMED
  OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC. ANY USE
  OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT THE
  PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
==============================================================================*/
package com.novell.security.nmas.lcm.clrpwd;

import com.novell.security.nmas.lcm.*;
import com.novell.security.nmas.transport.*;
import com.novell.security.nmas.client.*;
import com.novell.security.nmas.io.*;
import com.novell.security.nmas.*;

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.callback.PasswordCallback;
import java.io.*;

public class ClearPasswordLCM implements LCM
{
   private final static String METHOD_NAME = "Clear Password";
   private final static int SIZEOF_REPLY = 4;
   private final static Integer METHOD_ID = new Integer(1);

   MAF maf = null;
   CallbackHandler callbackHandler = null;

  // getMethodID.. for implementing LCM interface
   public Integer getMethodID()
   {
      return METHOD_ID;
   }

  // getMethodName.. for implementing LCM interface
    public String getMethodName()
   {
      return METHOD_NAME;
   }

  //
  // doMethod.. for implementing LCM interface
  //
    public int doMethod(MAF maf, CallbackHandler callbackHdlr)
   {
        this.maf = maf;
        this.callbackHandler = callbackHdlr;
      String password = null;
      boolean success = false;
      int err;

      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
      NMASDataOutputStream dataOut  = new NMASDataOutputStream(byteOut);

      err = maf.begin();
      if(err != 0) return err;

      try
      {
         password = getPwd();
      }
        catch (IOException ioe)
        {
            return NMASConstants.NMAS_E_LOGIN_FAILED;
        }

      /*
         First send the password information
           - int  error
           - int infoFlags  (i.e.  change password.. != 0 if want to change, 0 if no change)
      */
      try
        {
         dataOut.writeLEInt(0);  // No errors
         dataOut.writeLEInt(0);  // Don't want to change password
         dataOut.flush();

         err = maf.write(byteOut.toByteArray()); // call mafWrite to send the data to the server
      }
      catch(IOException e)
      {
         methodError(NMASConstants.NMAS_E_TRANSPORT);
            return NMASConstants.NMAS_E_TRANSPORT;
      }
      catch(MAFTransportException e)
      {
         methodError( e.getErrorCode() );
            return e.getErrorCode();
      }

      if(err != 0) // If there was an error then end and exit
      {
         maf.end(err, 0, null);
            return err;
      }

      byteOut.reset();   //clear out the data from the last write

       // Try to get the password from the user
        try
        {
            password = getPwd();
        }
        catch(IOException ioe)
        {
            err = NMASConstants.NMAS_E_INVALID_OPERATION;
            maf.end(err, 0, null);
            return err;
        }

     //  Now we send the password to the server
      byte[] replyData = null;
      byte[] pwdBytes  = null;
      try
        {
         dataOut.writeUTF(password);
         DataInputStream dStrip = new DataInputStream(new ByteArrayInputStream(byteOut.toByteArray()));
         short byteCount = dStrip.readShort();//strip out length parameter
         pwdBytes = new byte[byteCount];
         dStrip.readFully(pwdBytes);
         err = maf.xWrite(pwdBytes);
           //err = maf.write(pwdBytes);
            if(err != NMASConstants.NMAS_SUCCESS)
            {
                methodError(err);
                return err;
            }
            replyData = maf.read(SIZEOF_REPLY);
      }
      catch(IOException e)
      {
         methodError( NMASConstants.NMAS_E_TRANSPORT );
         return NMASConstants.NMAS_E_TRANSPORT;
      }
        catch(NMASEncryptionException nee)
        {
            methodError( NMASConstants.NMAS_E_CRYPTO_FAILED_INIT );
            return NMASConstants.NMAS_E_CRYPTO_FAILED_INIT;
        }
      catch(MAFTransportException e)
      {
         methodError(e.getErrorCode());
         return e.getErrorCode();
      }

      if(replyData != null && replyData.length > 3
         && (replyData[0] != 0 || replyData[1] != 0  || replyData[2] != 0 || replyData[3] != 0 ))
      {
         success = true;
      }
      else
      {
         success = false;
      }

     // check return value from server
      if(!success)
      {
         methodError(NMASConstants.NMAS_E_LOGIN_FAILED);
      }
      else
      {
         maf.end(0, 0, null);
      }

      return 0;
   }

    private String getPwd() throws IOException
    {
        String pwd = null;

       // First see if the password was set through a MAF.setAttribute() call
        pwd = maf.getAttribute(MAF.NMAS_AID_PASSWORD);
        if(pwd != null)
        {
            return pwd;
        }

        Callback [] callbacks = new Callback[1];
        PasswordCallback pwdCallback = new PasswordCallback("Password: ", true);
        callbacks[0] = pwdCallback;

        try
        {
            callbackHandler.handle(callbacks);
            pwd = new String(((PasswordCallback)callbacks[0]).getPassword());
        }
        catch (IOException e)
        {
            e.printStackTrace();
            throw e;
        }
        catch (UnsupportedCallbackException ue)
        {
            ue.printStackTrace();
            throw new IOException();
        }

        if(pwd == null)
        {
            return "";
        }

        return pwd;
    }

   private void methodError(int errorCode)
   {
     // If desired, display error message
      maf.end( errorCode, 0, null );
   }
}