[libgda/LIBGDA_5.0] LDAP provider: added TLS_REQCERT and TLS_CACERT connection parameters
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda/LIBGDA_5.0] LDAP provider: added TLS_REQCERT and TLS_CACERT connection parameters
- Date: Sat, 10 Mar 2012 13:31:47 +0000 (UTC)
commit 23705e64a33d641c830b81baa0e17d7cdc7ad1d7
Author: Vivien Malerba <malerba gnome-db org>
Date: Sat Feb 4 12:21:36 2012 +0100
LDAP provider: added TLS_REQCERT and TLS_CACERT connection parameters
to specify how to handle server certificates for SSL/TLS sessions
doc/C/limitations.xml | 24 ++++++++++++++---
providers/ldap/gda-ldap-provider.c | 49 +++++++++++++++++++++++++++------
providers/ldap/ldap_specs_dsn.xml.in | 26 ++++++++++++++++++
3 files changed, 86 insertions(+), 13 deletions(-)
---
diff --git a/doc/C/limitations.xml b/doc/C/limitations.xml
index b65118e..0a8ba38 100644
--- a/doc/C/limitations.xml
+++ b/doc/C/limitations.xml
@@ -163,10 +163,26 @@
</para>
</sect1>
- <sect1 id="limitations_ldap"><title>For LDAP</title>
- <para>
- TODO.
- </para>
+ <sect1 id="limitations_ldap">
+ <title>For LDAP</title>
+ <sect2>
+ <title>SSL/TLS certificate validation</title>
+ <para>
+ The TLS_REQCERT and TLS_CACERT options are taken into account by the LDAP provider, and
+ passed to the OpenLDAP library which is actually used. These options are global and set
+ by the first opened LDAP connection (i.e. all other LDAP connections share the same
+ settings, regardless of their TLS_REQCERT and TLS_CACERT options).
+ </para>
+ <para>
+ The TLS_REQCERT and TLS_CACERT options have a higher priority compared to the
+ options set in the <filename>$HOME/.ldaprc</filename>.
+ </para>
+ <para>
+ If the server certificate can't he checked (i.e. the certification chain established and
+ verified) when it is required that it be, then the connection will not he established and the
+ returned error will be "Can't contact LDAP server".
+ </para>
+ </sect2>
</sect1>
<sect1 id="limitations_jdbc"><title>For JDBC based providers</title>
diff --git a/providers/ldap/gda-ldap-provider.c b/providers/ldap/gda-ldap-provider.c
index 35428cc..64c742a 100644
--- a/providers/ldap/gda-ldap-provider.c
+++ b/providers/ldap/gda-ldap-provider.c
@@ -258,12 +258,15 @@ gda_ldap_provider_open_connection (GdaServerProvider *provider, GdaConnection *c
const gchar *port;
const gchar *user = NULL;
const gchar *pwd = NULL;
+ const gchar *tls_method = NULL;
+ const gchar *tls_cacert = NULL;
+ int rtls_method = -1;
gint rport;
gboolean use_ssl, use_cache;
base_dn = gda_quark_list_find (params, "DB_NAME");
if (!base_dn) {
- gda_connection_add_event_string (cnc,
+ gda_connection_add_event_string (cnc, "%s",
_("The connection string must contain the DB_NAME value"));
return FALSE;
}
@@ -290,6 +293,26 @@ gda_ldap_provider_open_connection (GdaServerProvider *provider, GdaConnection *c
if (!pwd)
pwd = gda_quark_list_find (params, "PASSWORD");
+ tls_cacert = gda_quark_list_find (params, "TLS_CACERT");
+ tls_method = gda_quark_list_find (params, "TLS_REQCERT");
+ if (tls_method && *tls_method) {
+ if (! g_ascii_strcasecmp (tls_method, "never"))
+ rtls_method = LDAP_OPT_X_TLS_NEVER;
+ else if (! g_ascii_strcasecmp (tls_method, "hard"))
+ rtls_method = LDAP_OPT_X_TLS_HARD;
+ else if (! g_ascii_strcasecmp (tls_method, "demand"))
+ rtls_method = LDAP_OPT_X_TLS_DEMAND;
+ else if (! g_ascii_strcasecmp (tls_method, "allow"))
+ rtls_method = LDAP_OPT_X_TLS_ALLOW;
+ else if (! g_ascii_strcasecmp (tls_method, "try"))
+ rtls_method = LDAP_OPT_X_TLS_TRY;
+ else {
+ gda_connection_add_event_string (cnc, "%s",
+ _("Invalid value for 'TLS_REQCERT'"));
+ return FALSE;
+ }
+ }
+
/* open LDAP connection */
LdapConnectionData *cdata;
LDAP *ld;
@@ -330,7 +353,6 @@ gda_ldap_provider_open_connection (GdaServerProvider *provider, GdaConnection *c
}
res = ldap_set_option (cdata->handle, LDAP_OPT_RESTART, LDAP_OPT_ON);
-#ifdef NO
if (use_ssl) {
/* Configuring SSL/TLS options:
* this is for texting purpose only, and should actually be done through LDAP's conf.
@@ -343,15 +365,24 @@ gda_ldap_provider_open_connection (GdaServerProvider *provider, GdaConnection *c
* Note: if server certificate verification fails,
* the error message is: "Can't contact LDAP server"
*/
- int opt = LDAP_OPT_X_TLS_DEMAND;
- res = ldap_set_option (cdata->handle, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt);
- if (res != LDAP_SUCCESS) {
- gda_connection_add_event_string (cnc, ldap_err2string (res));
- gda_ldap_free_cnc_data (cdata);
- return FALSE;
+ if (rtls_method >= 0) {
+ res = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &rtls_method);
+ if (res != LDAP_SUCCESS) {
+ gda_connection_add_event_string (cnc, ldap_err2string (res));
+ gda_ldap_free_cnc_data (cdata);
+ return FALSE;
+ }
+ }
+
+ if (tls_cacert && *tls_cacert) {
+ res = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, tls_cacert);
+ if (res != LDAP_SUCCESS) {
+ gda_connection_add_event_string (cnc, ldap_err2string (res));
+ gda_ldap_free_cnc_data (cdata);
+ return FALSE;
+ }
}
}
-#endif
/* authentication */
struct berval cred;
diff --git a/providers/ldap/ldap_specs_dsn.xml.in b/providers/ldap/ldap_specs_dsn.xml.in
index 9e2ca99..b0fd8f4 100644
--- a/providers/ldap/ldap_specs_dsn.xml.in
+++ b/providers/ldap/ldap_specs_dsn.xml.in
@@ -5,8 +5,34 @@
<parameter id="HOST" _name="Database server" _descr="Host on which the LDAP server is running" gdatype="gchararray"/>
<parameter id="PORT" _name="Port" _descr="Database server port (leave this field empty to use the default port)" gdatype="gint"/>
<parameter id="USE_SSL" _name="Require SSL" _descr="Whether or not to use SSL to establish the connection" gdatype="gboolean"/>
+ <parameter id="TLS_REQCERT" _name="Certificate check type" _descr="Specifies what checks to perform on server certificates in a SSL/TLS session" gdatype="string" source="methods:0"/>
+ <parameter id="TLS_CACERT" _name="Certificates file" _descr="Specifies the file that contains certificates for all of the recognized Certificate Authorities, in a SSL/TLS session" gdatype="string" plugin="filesel:MODE=OPEN"/>
<parameter id="USE_CACHE" _name="Cache server data" _descr="Use a cache to store some static server data (the cached files are in the user's cache directory), default is TRUE" gdatype="gboolean">
<gda_value>TRUE</gda_value>
</parameter>
</parameters>
+ <sources>
+ <gda_array name="methods">
+ <gda_array_field name="id" gdatype="gchararray"/>
+ <gda_array_field name="text" gdatype="gchararray"/>
+ <gda_array_data>
+ <gda_array_row>
+ <gda_value>NEVER</gda_value>
+ <_gda_value>Never: certificate not requested or checked</_gda_value>
+ </gda_array_row>
+ <gda_array_row>
+ <gda_value>ALLOW</gda_value>
+ <_gda_value>Allow: certificate requested, none or a bad one accepted.</_gda_value>
+ </gda_array_row>
+ <gda_array_row>
+ <gda_value>TRY</gda_value>
+ <_gda_value>Try: certificate requested, none accepted, otherwise checked.</_gda_value>
+ </gda_array_row>
+ <gda_array_row>
+ <gda_value>DEMAND</gda_value>
+ <_gda_value>Demand: certificate requested and checked</_gda_value>
+ </gda_array_row>
+ </gda_array_data>
+ </gda_array>
+ </sources>
</data-set-spec>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]