2008-12-22 17 views
7

Estoy intentando usar la biblioteca publicada por Novell (Novell.Directory.Ldap). Versión 2.1.10.Novell LDAP C# - Novell.Directory.Ldap - ¿Alguien ha hecho que funcione?

Lo que he hecho hasta ahora:

  • He probado el marco de una solicitud (LdapBrowser) y está funcionando, así que no es un problema de comunicación.

  • Está compilado en Mono, pero estoy trabajando con Visual Studio. Entonces creó un proyecto con las fuentes. También incluí una referencia a Mono.Security, porque el proyecto dependía de ello.

  • Comenté una llamada (freeWriteSemaphore (semId);) en la parte de error de la conexión, porque arrojaba más excepciones. Comprobé qué hizo esa llamada, y es solo un mecanismo de rastreo de errores.

  • Seguí los pasos básicos proporcionados en la documentación de Novell (http://www.novell.com/coolsolutions/feature/11204.html).

    // Creación de una instancia LdapConnection

    LdapConnection ldapConn = new LdapConnection(); ldapConn.SecureSocketLayer = ldapPort == 636;

    función

    // Conectar creará una conexión de socket al servidor

    ldapConn.Connect (ldaphost, LDAPPort);

    // función de enlace se unirán las credenciales de objeto de usuario al servidor de

    ldapConn.Bind (DN de usuario, userPasswd);

  • En este momento está fallando en la función Bind(). Obtengo el error 91.

¿Alguna vez alguien ha utilizado esta biblioteca y la ha visto funcionar? Si es así, ¿qué hiciste para que funcione? ¿Se necesita alguna configuración especial? ¿Hay alguna manera de hacerlo funcionar en el entorno .NET sin Mono (puedo tener referencias a dlls de Mono, pero no quiero que esté instalado en el servidor)?

(ACTUALIZACIÓN) La conexión está en el puerto 636, utilizando SSL. Comprobé con WireShark la comunicación y la comparé con lo que obtengo del navegador LDAP. He visto que el paso donde se comunica el certificado SSL no lo realiza la biblioteca LDAP. Entonces, ¿cuál es la mejor manera de hacer que haga lo que se supone que debe hacer?

(ACTUALIZACIÓN) Revisé la documentación y indica que no es compatible con SSL. http://www.novell.com/coolsolutions/feature/11204.html

autenticarse en el servidor LDAP con LdapConnection.Bind(). Solo admitimos la autenticación de texto sin formato . Aún no se ha agregado el soporte SSL/TLS .

Pero la documentación data de 2004, y desde entonces, se han realizado muchas actualizaciones. Y hay un parámetro en la biblioteca para definir si la conexión usa SSL. Así que ahora estoy confundido.

(ACTUALIZACIÓN) Se encontró una documentación más actualizada: http://developer.novell.com/documentation//ldapcsharp/index.html?page=/documentation//ldapcsharp/cnet/data/bqwa5p0.html. La forma en que se realiza la conexión SSL es registrando el certificado en el servidor. El problema es que lo que estoy haciendo no está vinculado a un servidor Novell específico, por lo que el certificado debe obtenerse dinámicamente.

+0

La forma habitual de obtener SSL funciona es obtener la clave pública de CA de firma en el equivalente del almacén de claves de Java (normalmente una CA de árbol). No obstante, lo que eso significa en C#. Una vez que lo tenga, todos los certificados de servidor firmados por ese árbol CA funcionarán. Entonces necesitarías uno por árbol. – geoffc

Respuesta

4

Finalmente encontré la manera de hacer que esto funcione.

En primer lugar, tesis mensajes me ayudaron en el camino correcto: http://directoryprogramming.net/forums/thread/788.aspx

En segundo lugar, tengo una DLL compilada de la Biblioteca LDAP Novell y utilizado el Mono.Security.Dll.

La solución:

I añadió esta función al código

// This is the Callback handler - after "Binding" this is called 
     public bool MySSLHandler(Syscert.X509Certificate certificate, int[] certificateErrors) 
     { 

      X509Store store = null; 
      X509Stores stores = X509StoreManager.LocalMachine; 
      store = stores.TrustedRoot; 

      //Import the details of the certificate from the server. 

      X509Certificate x509 = null; 
      X509CertificateCollection coll = new X509CertificateCollection(); 
      byte[] data = certificate.GetRawCertData(); 
      if (data != null) 
       x509 = new X509Certificate(data); 

      //List the details of the Server 

      //if (bindCount == 1) 
      //{ 

      Response.Write("<b><u>CERTIFICATE DETAILS:</b></u> <br>"); 
      Response.Write(" Self Signed = " + x509.IsSelfSigned + " X.509 version=" + x509.Version + "<br>"); 
      Response.Write(" Serial Number: " + CryptoConvert.ToHex(x509.SerialNumber) + "<br>"); 
      Response.Write(" Issuer Name: " + x509.IssuerName.ToString() + "<br>"); 
      Response.Write(" Subject Name: " + x509.SubjectName.ToString() + "<br>"); 
      Response.Write(" Valid From: " + x509.ValidFrom.ToString() + "<br>"); 
      Response.Write(" Valid Until: " + x509.ValidUntil.ToString() + "<br>"); 
      Response.Write(" Unique Hash: " + CryptoConvert.ToHex(x509.Hash).ToString() + "<br>"); 
      // } 

      bHowToProceed = true; 
      if (bHowToProceed == true) 
      { 
       //Add the certificate to the store. This is \Documents and Settings\program data\.mono. . . 
       if (x509 != null) 
        coll.Add(x509); 
       store.Import(x509); 
       if (bindCount == 1) 
        removeFlag = true; 
      } 

      if (bHowToProceed == false) 
      { 
       //Remove the certificate added from the store. 

       if (removeFlag == true && bindCount > 1) 
       { 
        foreach (X509Certificate xt509 in store.Certificates) 
        { 
         if (CryptoConvert.ToHex(xt509.Hash) == CryptoConvert.ToHex(x509.Hash)) 
         { 
          store.Remove(x509); 
         } 
        } 
       } 
       Response.Write("SSL Bind Failed."); 
      } 
      return bHowToProceed; 
     } 

Y i utilizó en el proceso de unión

// Create Connection 
       LdapConnection conn = new LdapConnection(); 
       conn.SecureSocketLayer = true; 
       Response.Write("Connecting to:" + ldapHost); 

       conn.UserDefinedServerCertValidationDelegate += new 
        CertificateValidationCallback(MySSLHandler); 

       if (bHowToProceed == false) 
        conn.Disconnect(); 
       if (bHowToProceed == true) 
       { 
        conn.Connect(ldapHost, ldapPort); 
        conn.Bind(loginDN, password); 
        Response.Write(" SSL Bind Successfull "); 

        conn.Disconnect(); 
       } 
       quit = false; 

Los elementos clave están utilizando el Handler SSL a dinámicamente obtenga el Certificado y use X509StoreManager.LocalMachine para que cuando el sitio web esté en ejecución pueda guardar y recuperar los certificados.

+0

Parece que podría ser útil para mí, pero no puedo decirlo porque no puedo encontrar un servidor Novell en ejecución que tenga la biblioteca. ¿Alguna posibilidad de que me la envíe por correo electrónico? chrisfant en G mail – Fantius

2

91 es "no se puede conectar". Intente poner el servidor en el formato "ldap: //x.x.x.x", compruebe que userDN esté configurado correctamente (con dominio, etc.).

A menudo uso WireShark para ver qué está sucediendo a nivel de red (conoce el protocolo LDAP).

2

Creo que ya le pude haber ofrecido esta respuesta a otra persona en una pregunta diferente.

[OtherQuestion en LDAP] [1]

Dos cuestiones que pienso: 1) ¿Qué tipo de aprieto estás tratando de hacer? SSL? ¿Borrar texto? ¿Anónimo?

2) ¿Cómo se configura en el lado de eDirectory para los enlaces LDAP?

La herramienta Navegador LDAP, ¿te refieres a la de este enlace? Browser LDAP gratuito

En el lado de eDirectory, pueden requerir TLS para todas las comunicaciones LDAP, y pueden rechazar enlaces anónimos.

Puede pedirle a la gente del otro lado que habilite el rastreo de LDAP (Usar DStrace con la opción + LDAP habilitada, algunos enlaces sobre cómo usar Dstrace en Novell eDirectory ver: Diferentes tipos de captura de Dstrace y comprender DS Trace para Identity Manager.)

Eso generalmente mostrará un mensaje de error que lo iluminará.

Supongo que Requiere TLS está habilitado, y es posible que no esté haciendo un enlace SSL exitoso.

Si es así, intente conectarse en el puerto 636, con SSL habilitado, y un DN completo para el usuario con el que está intentando iniciar sesión.

Si está intentando con SSL habilitado y no está recibiendo un cuadro emergente sobre la aceptación del certificado de raíz de confianza de la CA del árbol, entonces tal vez la CA o el certificado SSL que el servidor de eDirectory ha expirado o está roto. (Hay varias causas para esto que pueden ser comunes, y solo toma un momento para solucionarlo).

Normalmente en Dstrace, verá un error en el certificado SSL si hay un problema. En este artículo se incluye un ejemplo de la perspectiva de Novell Identity Manager de un certificado caducado: Certificado caducado, así como algunos detalles sobre cómo corregir los certificados.

La siguiente posibilidad es que el DN que está especificando no es del todo correcto.

Avíseme si necesita más ayuda.

+0

No podemos cambiar nada en el servidor Novell, es administrado por otro equipo y se ejecuta en un entorno en vivo. Entonces, tenemos un acceso de conexión para probar la autenticación con él, pero eso es todo lo que tenemos. Con el navegador LDAP podemos conectarnos a él, por lo que es cuestión de hacer que este archivo DLL funcione. – ceetheman

+0

¿Tiene el certificado de raíces de árboles en su Keystore? (No estoy seguro de cómo se llama el equivalente de C#). No es específico del servidor, per se. Es más específico de árbol. Es decir. Un certificado de CA raíz por árbol permitirá el acceso a todos los servidores. – geoffc

1

Siguiendo mi publicación anterior: si tiene que usar una conexión segura, intente usar ldaps: // como prefijo a la dirección del servidor.

Si no hay soporte SSL/TLS, puede probar this - guidelines y .NET wrapper para la biblioteca OpenLDAP.

Un punto importante: hay configuraciones para el nivel de seguridad TLS en OpenLDAP, por lo tanto, si su servidor LDAP tiene un certificado autofirmado, debe importarlo del lado del cliente o configurar TLS para no verificar la autoridad de firma * que es menos seguro, por supuesto).

+0

Agregar ldaps: // hace que la dirección sea inválida. El servidor usa SSL y el certificado se importa desde el lado del cliente. – ceetheman

+0

Y la biblioteca OpenLDAP está hecha con un Visual Studio y no hay una versión compilada (es anterior a 2004). – ceetheman

3

Vine en busca de una solución a un problema similar. Mi comando de enlace también fallaría al usar el mismo código en el sitio web de Novell. La solución que funcionó para mí fue agregar una llamada de validación de certificado dinámica. Puedes leer al respecto here.

 // Creating an LdapConnection instance 
     LdapConnection ldapConn = new LdapConnection(); 

     ldapConn.SecureSocketLayer = true; 

     ldapConn.UserDefinedServerCertValidationDelegate += new 
       CertificateValidationCallback(MySSLHandler); 


     //Connect function will create a socket connection to the server 
     ldapConn.Connect(ldapHost, ldapPort); 

     //Bind function will Bind the user object Credentials to the Server 
     ldapConn.Bind(userDN, userPasswd); 

     // Searches in the Marketing container and return all child entries just below this 
     //container i.e. Single level search 
     LdapSearchResults lsc = ldapConn.Search("ou=users,o=uga", 
          LdapConnection.SCOPE_SUB, 
          "objectClass=*", 
          null, 
          false); 

     while (lsc.hasMore()) 
     { 
      LdapEntry nextEntry = null; 
      try 
      { 
       nextEntry = lsc.next(); 
      } 
      catch (LdapException e) 
      { 
       Console.WriteLine("Error: " + e.LdapErrorMessage); 
       // Exception is thrown, go for next entry 
       continue; 
      } 
      Console.WriteLine("\n" + nextEntry.DN); 
      LdapAttributeSet attributeSet = nextEntry.getAttributeSet(); 
      System.Collections.IEnumerator ienum = attributeSet.GetEnumerator(); 
      while (ienum.MoveNext()) 
      { 
       LdapAttribute attribute = (LdapAttribute)ienum.Current; 
       string attributeName = attribute.Name; 
       string attributeVal = attribute.StringValue; 
       Console.WriteLine(attributeName + "value:" + attributeVal); 
      } 
     } 
     ldapConn.Disconnect(); 
     Console.ReadKey(); 
    } 

public static bool MySSLHandler(Syscert.X509Certificate certificate, 
      int[] certificateErrors) 
     { 

      X509Store store = null; 
      X509Stores stores = X509StoreManager.CurrentUser; 
      //string input; 
      store = stores.TrustedRoot; 

      X509Certificate x509 = null; 
      X509CertificateCollection coll = new X509CertificateCollection(); 
      byte[] data = certificate.GetRawCertData(); 
      if (data != null) 
       x509 = new X509Certificate(data); 

      return true; 
     } 
1

Trabajo en la integración de Forefront Identity Manager. Entonces, el código que escribo siempre proviene de unos pocos clientes llamantes. Esto puede no ser apropiado si está intentando empaquetar una aplicación para usar "en cualquier lugar".

Solo quería actualizar este hilo con una solución simple para los servidores de Novell que tienen activada la opción de confidencialidad TLS/SSL predeterminada.

1) Asegúrese de obtener los certificados SSL del servidor Novell que está vinculando también e inscribirlos en la tienda de confianza del cliente/servidor en ejecución. Normalmente hay dos 1 para la IP y para el nombre de host dependiente al que llamará (DNS preferible)

2) Importe las siguientes referencias/añada usando System.DirectoryServices; usando System.DirectoryServices.Protocols;

3) Aquí hay un fragmento. Asegúrese de elegir AuthenticationTypes.SecureSocketsLayer, que es la clave.

// serverAddress = Server IP or DNS (Match SSL certificate) 
// ObjectDN = The DN of the user you are binding to 
// userName = Account which will be used to make the bind 
// password = password of the user which will make the bind 
// value = The value you wish to add to the attribute 

// Connect to the user in LDAP 
DirectoryEntry entry = new DirectoryEntry("LDAP://" + serverAddress + "/" + ObjectDN + "" 
       , userName 
       , password 
       , AuthenticationTypes.SecureSocketsLayer); 
// Write the Updated attribute 
entry.Properties["attribute"].Value = value; 
// Read back the updated Attribute into a label 
label.Text = entry.Properties["attribute"].Value.ToString(); 
Cuestiones relacionadas