From 55e8c25bb2fadee3a2f0b4b93df119a6087e499c Mon Sep 17 00:00:00 2001 From: Match Grun Date: Thu, 4 Mar 2004 07:33:57 +0000 Subject: [PATCH] Include TLS support for LDAP --- ChangeLog.claws | 12 ++++++++++++ configure.ac | 13 ++++++++++++- src/addressbook.c | 9 +-------- src/addrindex.c | 17 +++++++++++++++-- src/editldap.c | 45 +++++++++++++++++++++++++++++++++++++++------ src/ldapctrl.c | 21 ++++++++++++++++++++- src/ldapctrl.h | 5 ++++- src/ldapquery.c | 26 +++++++++++++++++++++++++- src/ldapserver.c | 2 +- src/ldapserver.h | 3 ++- 10 files changed, 131 insertions(+), 22 deletions(-) diff --git a/ChangeLog.claws b/ChangeLog.claws index 424f83043..bddc65350 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,15 @@ +2004-03-02 [match] 0.9.9claws38 + + * configure.ac + added definition of USE_LDAP_TLS to support TLS. + * src/ldapctrl.[ch] + * src/ldapquery.c + * src/ldapserver.[ch] + * src/addressbook.c + * src/addrindex.c + * src/editldap.c + included LDAP TLS support. + 2004-03-02 [christoph] 0.9.9claws37 * src/folder.[ch] diff --git a/configure.ac b/configure.ac index 991f1614c..539785fc5 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=9 MICRO_VERSION=9 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=37 +EXTRA_VERSION=38 if test $EXTRA_VERSION -eq 0; then VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}claws else @@ -349,16 +349,27 @@ if test "$ac_cv_enable_ldap" = yes; then [ ac_cv_enable_ldap=yes ], [ ac_cv_enable_ldap=no ], $LDAP_LIBS) + + AC_CHECK_LIB(ldap, ldap_start_tls_s, + [ ac_cv_have_tls=yes ], + [ ac_cv_have_tls=no ]) + fi AC_MSG_CHECKING([whether ldap library is available]) AC_MSG_RESULT($ac_cv_enable_ldap) + AC_MSG_CHECKING([whether TLS library is available]) + AC_MSG_RESULT($ac_cv_have_tls) + if test "$ac_cv_enable_ldap" = yes; then CFLAGS="$CFLAGS `$GLIB_CONFIG --cflags gthread`" LDAP_LIBS="$LDAP_LIBS -lldap `$GLIB_CONFIG --libs gthread`" AC_DEFINE(USE_LDAP, 1, Define if you want LDAP support in addressbook.) AC_SUBST(LDAP_LIBS) + if test "$ac_cv_have_tls" = yes; then + AC_DEFINE(USE_LDAP_TLS, 1, Define if you want LDAP TLS support in addressbook.) + fi fi else AC_MSG_RESULT(no) diff --git a/src/addressbook.c b/src/addressbook.c index dc0374230..0e7129e53 100644 --- a/src/addressbook.c +++ b/src/addressbook.c @@ -484,6 +484,7 @@ static ErrMsgTableEntry _lutErrorsLDAP_[] = { { LDAPRC_CRITERIA, N_("Error in LDAP search criteria") }, { LDAPRC_NOENTRIES, N_("No LDAP entries found for search criteria") }, { LDAPRC_STOP_FLAG, N_("LDAP search terminated on request") }, + { LDAPRC_TLS, N_("Error starting TLS connection") }, { 0, NULL } }; #endif @@ -1331,14 +1332,6 @@ static void addressbook_tree_selected(GtkCTree *ctree, GtkCTreeNode *node, ItemFolder *rootFolder = NULL; AddressObjectType aot; - if( addrbook.treeSelected == node ) { - /* - * Prevent double selection - this happens with a mouse - * click but not with a key-press. - */ - /* return; */ - } - addrbook.treeSelected = node; addrbook.listSelected = NULL; addressbook_status_show( "" ); diff --git a/src/addrindex.c b/src/addrindex.c index cba52c6c4..c85af497e 100644 --- a/src/addrindex.c +++ b/src/addrindex.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 2001-2003 Match Grun + * Copyright (C) 2001-2004 Match Grun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -95,6 +95,7 @@ #define ATTAG_LDAP_MAX_AGE "max-age" #define ATTAG_LDAP_DYN_SEARCH "dyn-search" #define ATTAG_LDAP_MATCH_OPT "match-opt" +#define ATTAG_LDAP_ENABLE_TLS "enable-tls" #define ELTAG_LDAP_ATTR_SRCH "attribute" #define ATTAG_LDAP_ATTR_NAME "name" @@ -1349,11 +1350,13 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) { gchar *serverName = NULL; gchar *criteria = NULL; gboolean bDynSearch; + gboolean bTLS; gint iMatch; /* printf( "addrindex_parse_ldap\n" ); */ /* Set up some defaults */ bDynSearch = FALSE; + bTLS = FALSE; iMatch = LDAPCTL_MATCH_BEGINWITH; ds = addrindex_create_datasource( ADDR_IF_LDAP ); @@ -1408,6 +1411,12 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) { iMatch = LDAPCTL_MATCH_CONTAINS; } } + else if( strcmp( name, ATTAG_LDAP_ENABLE_TLS ) == 0 ) { + bTLS = FALSE; + if( strcmp( value, ATVAL_BOOLEAN_YES ) == 0 ) { + bTLS = TRUE; + } + } attr = g_list_next( attr ); } @@ -1415,6 +1424,7 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) { ldapsvr_set_name( server, serverName ); ldapsvr_set_search_flag( server, bDynSearch ); ldapctl_set_matching_option( ctl, iMatch ); + ldapctl_set_tls( ctl, bTLS ); g_free( serverName ); ldapsvr_set_control( server, ctl ); ds->rawDataSource = server; @@ -1474,6 +1484,10 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) { ( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) ? ATVAL_LDAP_MATCH_CONTAINS : ATVAL_LDAP_MATCH_BEGIN ); + addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_TLS, + ctl->enableTLS ? + ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO ); + fputs(" >\n", fp); /* Output attributes */ @@ -1487,7 +1501,6 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) { /* End of element */ addrindex_write_elem_e( fp, lvl, TAG_DS_LDAP ); - } #else diff --git a/src/editldap.c b/src/editldap.c index 67e01ecd4..8a47eed1f 100644 --- a/src/editldap.c +++ b/src/editldap.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 2001-2003 Match Grun + * Copyright (C) 2001-2004 Match Grun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -79,6 +79,7 @@ static struct _LDAPEdit { GtkWidget *spinbtn_queryage; GtkWidget *check_dynsearch; GtkWidget *check_matchoption; + GtkWidget *check_tls; } ldapedit; /** @@ -372,9 +373,12 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) { GtkWidget *entry_baseDN; GtkWidget *check_btn; GtkWidget *lookdn_btn; + GtkWidget *check_tls; GtkTooltips *toolTip; gint top; + check_tls = NULL; /* Force NULL */ + vbox = gtk_vbox_new( FALSE, 8 ); gtk_widget_show( vbox ); gtk_container_add( GTK_CONTAINER( ldapedit.notebook ), vbox ); @@ -483,6 +487,19 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) { "directory names on the server." ), NULL ); +#ifdef USE_LDAP_TLS + /* Next row */ + ++top; + check_tls = gtk_check_button_new_with_label( _("Enable TLS") ); + gtk_table_attach(GTK_TABLE(table), check_tls, 1, 3, top, (top + 1), + GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0); + + toolTip = gtk_tooltips_new(); + gtk_tooltips_set_tip( toolTip, check_tls, _( + "Connect to the server using TLS encrypted connection." ), + NULL ); +#endif + /* Signal handlers */ gtk_signal_connect(GTK_OBJECT(check_btn), "clicked", GTK_SIGNAL_FUNC(edit_ldap_server_check), NULL); @@ -496,6 +513,7 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) { ldapedit.entry_server = entry_server; ldapedit.spinbtn_port = spinbtn_port; ldapedit.entry_baseDN = entry_baseDN; + ldapedit.check_tls = check_tls; } static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) { @@ -615,7 +633,7 @@ static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) { "search usually takes longer to complete. Note that for " \ "performance reasons, address completion uses " \ "\"begins-with\" for all searches against other address " \ - "interfaces." \ + "interfaces." ), NULL ); @@ -876,6 +894,10 @@ static void edit_ldap_clear_fields( void ) { GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), TRUE ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( ldapedit.check_matchoption), FALSE ); +#ifdef USE_LDAP_TLS + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON( ldapedit.check_tls), FALSE ); +#endif } /** @@ -920,12 +942,16 @@ static void edit_ldap_set_fields( LdapServer *server ) { gtk_entry_set_text(GTK_ENTRY(ldapedit.entry_criteria), "" ); } gtk_spin_button_set_value( - GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), ctl->maxQueryAge ); + GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage ), ctl->maxQueryAge ); gtk_toggle_button_set_active( - GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), server->searchFlag ); + GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ), server->searchFlag ); gtk_toggle_button_set_active( - GTK_TOGGLE_BUTTON( ldapedit.check_matchoption), + GTK_TOGGLE_BUTTON( ldapedit.check_matchoption ), ( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) ); +#ifdef USE_LDAP_TLS + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON( ldapedit.check_tls ), ctl->enableTLS ); +#endif } /** @@ -941,7 +967,7 @@ AdapterDSource *addressbook_edit_ldap( static gboolean cancelled; gchar *sName, *sHost, *sBase, *sBind, *sPass, *sCrit; gint iPort, iMaxE, iTime, iAge; - gboolean bSrch, bMatch; + gboolean bSrch, bMatch, bTLS; AddressDataSource *ds = NULL; LdapServer *server = NULL; LdapControl *ctl = NULL; @@ -997,6 +1023,12 @@ AdapterDSource *addressbook_edit_ldap( GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) ); bMatch = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ldapedit.check_matchoption ) ); +#ifdef USE_LDAP_TLS + bTLS = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON( ldapedit.check_tls ) ); +#else + bTLS = FALSE; +#endif fin = FALSE; if( *sName == '\0' ) fin = TRUE; @@ -1027,6 +1059,7 @@ AdapterDSource *addressbook_edit_ldap( ldapctl_set_matching_option( ctl, bMatch ? LDAPCTL_MATCH_CONTAINS : LDAPCTL_MATCH_BEGINWITH ); + ldapctl_set_tls( ctl, bTLS ); /* Save attributes */ editldap_parse_criteria( sCrit, ctl ); diff --git a/src/ldapctrl.c b/src/ldapctrl.c index 391694b39..74e521753 100644 --- a/src/ldapctrl.c +++ b/src/ldapctrl.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 2003 Match Grun + * Copyright (C) 2003-2004 Match Grun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,6 +56,8 @@ LdapControl *ldapctl_create( void ) { ctl->timeOut = LDAPCTL_DFL_TIMEOUT; ctl->maxQueryAge = LDAPCTL_DFL_QUERY_AGE; ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH; + ctl->version = 0; + ctl->enableTLS = FALSE; /* Mutex to protect control block */ ctl->mutexCtl = g_malloc0( sizeof( pthread_mutex_t ) ); @@ -184,6 +186,15 @@ void ldapctl_set_matching_option( LdapControl* ctl, const gint value ) { } } +/** + * Specify TLS option. + * \param ctl Control object to process. + * \param value TRUE to enable TLS. + */ +void ldapctl_set_tls( LdapControl* ctl, const gboolean value ) { + ctl->enableTLS = value; +} + /** * Specify search criteria list to be used. * \param ctl Control data object. @@ -282,6 +293,8 @@ void ldapctl_clear( LdapControl *ctl ) { ctl->timeOut = 0; ctl->maxQueryAge = 0; ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH; + ctl->version = 0; + ctl->enableTLS = FALSE; } /** @@ -323,6 +336,8 @@ void ldapctl_default_values( LdapControl *ctl ) { ctl->timeOut = LDAPCTL_DFL_TIMEOUT; ctl->maxQueryAge = LDAPCTL_DFL_QUERY_AGE; ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH; + ctl->version = 0; + ctl->enableTLS = FALSE; ldapctl_default_attributes( ctl ); } @@ -350,6 +365,8 @@ void ldapctl_print( const LdapControl *ctl, FILE *stream ) { fprintf( stream, " timeout: %d\n", ctl->timeOut ); fprintf( stream, " max age: %d\n", ctl->maxQueryAge ); fprintf( stream, "match opt: %d\n", ctl->matchingOption ); + fprintf( stream, " version: %d\n", ctl->version ); + fprintf( stream, " TLS: %s\n", ctl->enableTLS ? "yes" : "no" ); fprintf( stream, "crit list:\n" ); if( ctl->listCriteria ) { mgu_print_dlist( ctl->listCriteria, stream ); @@ -403,6 +420,8 @@ void ldapctl_copy( const LdapControl *ctlFrom, LdapControl *ctlTo ) { ctlTo->timeOut = ctlFrom->timeOut; ctlTo->maxQueryAge = ctlFrom->maxQueryAge; ctlTo->matchingOption = ctlFrom->matchingOption; + ctlTo->version = ctlFrom->version; + ctlTo->enableTLS = ctlFrom->enableTLS; /* Unlock */ pthread_mutex_unlock( ctlTo->mutexCtl ); diff --git a/src/ldapctrl.h b/src/ldapctrl.h index 568e90d7e..cf36e3646 100644 --- a/src/ldapctrl.h +++ b/src/ldapctrl.h @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 2003 Match Grun + * Copyright (C) 2003-2004 Match Grun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,6 +66,8 @@ struct _LdapControl { gint timeOut; gint maxQueryAge; gint matchingOption; + gint version; + gboolean enableTLS; gchar *attribEMail; gchar *attribCName; gchar *attribFName; @@ -85,6 +87,7 @@ void ldapctl_set_max_entries ( LdapControl* ctl, const gint value ); void ldapctl_set_timeout ( LdapControl* ctl, const gint value ); void ldapctl_set_max_query_age ( LdapControl* ctl, const gint value ); void ldapctl_set_matching_option( LdapControl* ctl, const gint value ); +void ldapctl_set_tls ( LdapControl* ctl, const gboolean value ); void ldapctl_set_criteria_list ( LdapControl* ctl, GList *value ); GList *ldapctl_get_criteria_list( const LdapControl* ctl ); void ldapctl_criteria_list_clear( LdapControl *ctl ); diff --git a/src/ldapquery.c b/src/ldapquery.c index 0180cce95..9cfd50421 100644 --- a/src/ldapquery.c +++ b/src/ldapquery.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 2003 Match Grun + * Copyright (C) 2003-2004 Match Grun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -694,6 +694,7 @@ static gint ldapqry_connect( LdapQuery *qry ) { LdapControl *ctl; LDAP *ld; gint rc; + gint version; /* Initialize connection */ /* printf( "===ldapqry_connect===\n" ); */ @@ -719,6 +720,29 @@ static gint ldapqry_connect( LdapQuery *qry ) { printf( "connected to LDAP host %s on port %d\n", ctl->hostName, ctl->port ); */ +#ifdef USE_LDAP_TLS + /* Handle TLS */ + version = LDAP_VERSION3; + rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); + if( rc == LDAP_OPT_SUCCESS ) { + ctl->version = LDAP_VERSION3; + } + + if( ctl->version == LDAP_VERSION3 ) { + if( ctl->enableTLS ) { + ADDRQUERY_RETVAL(qry) = LDAPRC_TLS; + rc = ldap_start_tls_s( ld, NULL, NULL ); + /* + printf( "rc=%d\n", rc ); + printf( "LDAP Status: set_option: %s\n", ldap_err2string( rc ) ); + */ + if( rc != LDAP_SUCCESS ) { + return ADDRQUERY_RETVAL(qry); + } + } + } +#endif + /* Bind to the server, if required */ ADDRQUERY_RETVAL(qry) = LDAPRC_BIND; if( ctl->bindDN ) { diff --git a/src/ldapserver.c b/src/ldapserver.c index beab458de..35a640f37 100644 --- a/src/ldapserver.c +++ b/src/ldapserver.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 2003 Match Grun + * Copyright (C) 2003-2004 Match Grun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ldapserver.h b/src/ldapserver.h index 21a64f5d6..d5223272f 100644 --- a/src/ldapserver.h +++ b/src/ldapserver.h @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 2003 Match Grun + * Copyright (C) 2003-2004 Match Grun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,7 @@ #define LDAPRC_CRITERIA -6 #define LDAPRC_NOENTRIES -7 #define LDAPRC_STOP_FLAG -8 +#define LDAPRC_TLS -9 typedef struct _LdapServer LdapServer; struct _LdapServer { -- 2.25.1