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

 * $Novell: SaslExternalBind.java,v 1.1 2003/08/21 11:39:49 $

 * Copyright (c) 2003 Novell, Inc. All Rights Reserved.

 *

 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND

 * TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE

 * AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS

 * THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO

 * DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE

 * CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS

 * TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF

 * DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR

 * DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE.

 *

 * $name:         SaslExternalBind.java

 * $description:  Demonstrates how to do a SASL External Bind with an LDAP 

 * server. No login dn is needed because this information is passed to the

 * LDAP server via a client public key certificate. In order for this to work

 * the LDAP server must require mutual authentication (client public key

 * certificate required).  Three files are used in this sample to do SASL

 * External Bind with an LDAP server.

 * They are:

 *     

 * 1. server trusted root certificate

 * 2. client public key certificate

 * 3. client private key

 *  

 * The server trusted root and client public key certificate files are used

 * to authenticate the server and client respectively. The  server trusted

 * root certificate is used by JSSE to validate the server it is trying to

 * connect to. The client public key certificate is sent to the server to

 * authenticate the client and it contains the clients public key information.

 * This client public key certificate is used by the LDAP server SASL External

 * mechanism (Cert Mutual) during a saslbind(EXTERNAL). Before this sample can

 * run properly the "Cert Mutual" External Method needs to be installed into

 * eDirectory. The client private key contains the key used by the ldapssl api

 * to encrypt data to send the server. The server un-encrypts data from the

 * client via the client's public key.

 *  

 * The client public key certificate file may contain the clients private key

 * if created properly. This file can be used as the client private key and 

 * public key certificate file (The private key information is never sent to

 * the server).

 *  

 * In order to run this sample some configuring needs to be done on the LDAP

 * server that you are testing against. The following are steps needed to

 * configure an eDirectory LDAP server to do SASL External Bind. It is

 * assumed that you are using ConsoleOne with admin rights to configure

 * eDirectory. eDirectory 8.7 or newer is required.

 *  

 * 1. To ensure that the client certificate is being sent to the server,

 *    require client certificates for the LDAP Server. This is done by setting 

 *    "Client Certificate:" to "Required" in the "LDAP Server" under the

 *    "TLS Configuration" tab in ConsoleOne.

 *    (LDAP Server|TLS Configuration|Client Certificate:|Required)

 *     

 * 2. Export the SSL CertificateDNS object trusted root certificate.

 *    (This is your server trusted root certificate file.) For this example

 *    name it "server.der"

 *    (SSL CertificateDNS|Certificates|Trusted Root Certificate|Export)

 *     

 * 3. Create a client in ConsoleOne. Lets call the client "dave"

 *    with a password of "foo" in the organization "Acme".

 *    (File|New|User...)

 *     

 * 4. Create a certificate for "dave".

 *    (dave|Security|Certificate|Create)

 *     

 * 5. Refresh the NLDAP server now.

 *    (LDAP Server|General|Refresh NLDAP Server Now)

 *    

 * 6. Authenticate into ConsoleOne as "dave".(This allows you to export "dave"

 *    certificate that contains both private and public keys.)

 *    (File|Authenticate)

 *    

 * 7. Export dave's certificate with the private key. (This certificate 

 *    can be used for both the client certificate and private key file.)

 *    For this example name the certificate file "dave.pfx" with a password

 *    of "evad".

 *    (dave|Security|Certificate|Export|Yes export the private key)

 * 

 * At this point you should be able to run this sample as follows. For this

 * example assume the server name is "Acme.com" and "dave" was created in

 * an organization called "Acme"

 *

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



import com.novell.ldap.LDAPConnection;

import com.novell.ldap.LDAPException;

import com.novell.ldap.LDAPJSSESecureSocketFactory;

import java.util.Map;

import java.util.HashMap;

import java.util.Properties;

import java.security.*;



public class SaslExternalBind

{

    private static void usage() {

        System.err.println("\n");

        System.err.println(

          "Usage: java SaslExternalBind <host Name> <Port Number> " +

                  "<Path Truststore> <truststore passwd> <path of keyStore> " +

                  "<keystore passwd> <keystore type> ");

        System.err.println("\n");                                        

        System.err.println(

          "Example: java SaslExternalBind Acme.com 636 \"e:\\server.keystore\" "

                    + " novell \"e:\\client.pfx\" novell PKCS12");

    }



    public static void main( String[] args ) {





        if (args.length != 7) {

            usage();

            System.exit(1);

        }



        int ldapVersion   = LDAPConnection.LDAP_V3;

        String ldapHost   = args[0];

        int ldapSSLPort   = Integer.parseInt(args[1]);

        String tStore     = args[2];

        String tStorePass = args[3];

        String kStore     = args[4];

        String kStorePass = args[5];

        String kStoreType = args[6]; 

        String[]  mechanism = {"EXTERNAL"};



        System.setProperty("javax.net.ssl.trustStore",tStore);

        System.setProperty("javax.net.ssl.trustStorePassword",tStorePass);

        System.setProperty("javax.net.ssl.keyStore",kStore);

        System.setProperty("javax.net.ssl.keyStorePassword",kStorePass);

        System.setProperty("javax.net.ssl.keyStoreType",kStoreType);

    

        LDAPJSSESecureSocketFactory ssf = new LDAPJSSESecureSocketFactory();

        LDAPConnection  conn = new LDAPConnection(ssf);



        try { 

	        Security.addProvider(new com.novell.sasl.client.SaslProvider()); 

        }catch(Exception e) {

	        System.err.println("Error loading security provider (" + 

			e.getMessage() + ")"); 

        }        

        

        

        try {

            conn.connect( ldapHost, ldapSSLPort);

            conn.bind((String) null,

                      (String) null,

                      mechanism,

                      null,

                      (Object)null);



            System.out.println((conn.isBound()) ?

                "\n\tAuthenticated to the server ( sslExternal bind )\n":

                    "\n\tNot authenticated to the server\n");

                    

            // disconnect with the server

            conn.disconnect();

        }

        catch( LDAPException e ) {

            System.out.println( "Error: " + e.toString() );

        }



    }

}

