/* **************************************************************************

  $Archive: /njcl_v2rmi/src/com/novell/service/security/protocols/ServiceAuthProtocolProxy.java $
  $Revision: 11 $
  $Modtime: 1/17/01 4:04p $

  Copyright (c) 1997 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.service.security.protocols;

import com.novell.java.lang.*;
import com.novell.java.security.*;
import com.novell.java.security.channels.NativeCodeChannelProxy;
import com.novell.java.util.Debug;
import java.util.Vector;
import java.util.Properties;

import com.novell.service.jncp.NSIExceptionBuilder;
import com.novell.service.jncpv2r.clx.ClxJNI;
//import com.novell.service.ldap.LdapBinding;
import com.novell.service.security.*;
import com.novell.service.security.protocols.nls.I2L;
import com.novell.service.security.protocols.nls.LF;
import com.novell.service.session.*;
import com.novell.service.session.xplat.Shibboleth;
import com.novell.service.session.xplat.ShibbolethImpl;
import com.novell.service.jncpv2r.net.NetJNI;
import com.novell.service.session.nds.NDSShibboleth;

/** @internal
 * The service authenticator protocol proxy.
 */
public class ServiceAuthProtocolProxy
   implements AuthenticatorProtocol
{
   /**
    * authentication channel to use in the protocol
    */
   protected AuthenticatorChannel channel;

   /**
    * construct the authentication protocol proxy
    */
   public ServiceAuthProtocolProxy ()
   {
      // Hard coded default. Hopefully, configuration should take care of this
      channel = new NativeCodeChannelProxy();
   }

   /**
    * configure the protocol
    */
   public void configure (
         Properties properties,
         String baseKey)
      throws ConfigurationException
   {
   }

   /**
    * set the channel for the protocol and identity
    */
   public void init (
         AuthenticatorChannel channel)
      throws InvalidAuthenticatorChannelException
   {
      this.channel = channel;
   }

   public AuthenticatorChannel getChannel()
   {
      return channel;
   }

   /**
    * perform the authentication protocol
    */
   public void login (Identity in)
      throws LoginException
   {
      if (in instanceof NdsServiceIdentity)
      {
         NdsServiceIdentity identity = (NdsServiceIdentity)in;
         boolean remote = false;
         try
         {
            if(identity.getSessionManager().getEnvironment().get(
               SessionEnv.SESSION_MANAGER_URL) != null)
               remote = true;
         }
         catch(Exception e)
         { //Ignore
         }
         if(!remote && System.getProperty ("os.name").toLowerCase().indexOf("netware") == -1)
            throw new LoginException(
               com.novell.java.security.I2L.getString(XMsg.SERVICE_AUTH_PLATFORM_UNSUPPORTED));

         channel.beginProtocol(this);
         try  {
            Shibboleth ex = XplatProtocolProxy.getShibboleth (identity, identity.getUserDomain());
            ex.authenticateService (identity.getUsername());
         }  catch(AuthenticatorException x)       {
               throw x;
         }  catch (java.lang.Throwable x)         {
               throw new LoginException(x);
         }  finally {
            channel.endProtocol(this);
         }
      }
      else
         throw new LoginException(
            com.novell.java.security.I2L.getString(XMsg.INVALID_AUTHENTICATOR_PROTOCOL));
   }


   public void logout(Identity in)
      throws LogoutException
   {
      if (in instanceof NdsServiceIdentity)
      {
         NdsServiceIdentity identity = (NdsServiceIdentity)in;
         boolean remote = false;
         try
         {
            if(identity.getSessionManager().getEnvironment().get(
               SessionEnv.SESSION_MANAGER_URL) != null)
               remote = true;
         }
         catch(Exception e)
         { //Ignore
         }
         if(!remote && System.getProperty ("os.name").toLowerCase().indexOf("netware") == -1)
            throw new LoginException(
               com.novell.java.security.I2L.getString(XMsg.SERVICE_AUTH_PLATFORM_UNSUPPORTED));

         channel.beginProtocol(this);
         try  {
            Shibboleth ex = XplatProtocolProxy.getShibboleth (identity, identity.getUserDomain());
            ex.unauthenticate ();
         }  catch(AuthenticatorException x)       {
               throw x;
         }  catch (java.lang.Throwable x)         {
               throw new LoginException(x);
         }  finally {
            channel.endProtocol(this);
         }
      }
      else
         throw new LoginException(
            com.novell.java.security.I2L.getString(XMsg.INVALID_AUTHENTICATOR_PROTOCOL));
   }

	/**
	 * @deprecated See AuthenticatorProtocol for details...
	 */
   public void createTokens (
         Identity in)
      throws CreateTokensException
   {
      throw new CreateTokensException(
         com.novell.java.security.I2L.getString(XMsg.SERVICE_AUTH_TOKENS_UNSUPPORTED));
   }

   public void createTokens (
         Identity admin, Identity user)
      throws CreateTokensException
   {
      throw new CreateTokensException(
         com.novell.java.security.I2L.getString(XMsg.SERVICE_AUTH_TOKENS_UNSUPPORTED));
   }

   public void modifyTokens(Identity in)
      throws ModifyTokensException
   {
      throw new ModifyTokensException(
         com.novell.java.security.I2L.getString(XMsg.SERVICE_AUTH_TOKENS_UNSUPPORTED));
   }

   public void verifyTokens(Identity in)
      throws VerifyTokensException
   {
      throw new VerifyTokensException(
         com.novell.java.security.I2L.getString(XMsg.SERVICE_AUTH_TOKENS_UNSUPPORTED));
   }


   public Identity[] getIdentities(Identity in)
      throws AuthenticatorException
   {
      channel.beginProtocol(this);


      Vector identities = new Vector();
      Identity ids[] = null;
      try
      {
         // Get the session manager
         SessionManager sessionManager = XplatProtocolProxy.getSessionManager(in);
         SessionAttrs attrs;

         IdentityScope sys = new NdsIdentityScope(NdsIdentityScope.ADMINISTRATIVE_DOMAIN_NAME);
         attrs = new SessionAttrs();
         attrs.add(new SessionAttr(Session.PROVIDER_NAME_ATTR_ID, "NDS"));
         attrs.add(new SessionAttr(Authenticatable.IS_AUTHENTICATED_ATTR_ID, new Boolean(true)));
         attrs.add(new SessionAttr(Session.SESSION_TYPE_ATTR_ID, "TREE"));
         SessionEnumerator enum = sessionManager.search(attrs);
         while (enum.hasMoreElements())
         {
            Session found = enum.next();
            NdsIdentityScope scope = new NdsIdentityScope(
               stripUnderscores(found.getDomainName()),sys);
            NdsIdentity id = new NdsIdentity(((Authenticatable)found).getName(),scope);
            identities.addElement(id);
         }

         ids = new Identity[identities.size()];
         identities.copyInto(ids);

//         for(int i = 0; i<ids.length; i++)
//            Debug.println("Identities: "+ids[i]);
      }
      catch(AuthenticatorException x)
      {
         throw x;
      }
      catch (java.lang.Throwable x)
      {
         throw new GetIdentitiesException(x);
      }
      finally
      {
        channel.endProtocol(this);
        return ids;
      }
   }

   String stripUnderscores (String name)
   {
      StringBuffer str = new StringBuffer(name);
      for(int i = str.length()-1; str.charAt(i) == '_'; i--)
         str.setLength(i);

      return str.toString();
   }

} // class ServiceAuthProtocolProxy

