From 5dca3046d3ad660485cc68e3c9f4ef3f98a5922d Mon Sep 17 00:00:00 2001 From: Chris Toshok Date: Fri, 5 Jan 2001 02:22:47 +0000 Subject: new function. (impl_BookListener_respond_authentication_result): new 2001-01-04 Chris Toshok * backend/ebook/e-book-listener.c (e_book_listener_queue_authentication_response): new function. (impl_BookListener_respond_authentication_result): new function. (e_book_listener_get_epv): fill in epv->notifyAuthenticationResult. * backend/ebook/e-book-listener.h: add AuthenticationResponse to EBookListenerOperation. * backend/ebook/e-book.c (e_book_authenticate_user): new function. * backend/ebook/e-book.h: add prototype for e_book_authenticate_user. * backend/idl/addressbook.idl (GNOME:Evolution:Addressbook:Book): add authenticateUser method. (GNOME:Evolution:Addressbook:BookListener): add AuthenticationFailed and AuthenticationRequired to CallStatus. also add notifyAuthenticationResult method. * backend/pas/pas-backend-file.c (pas_backend_file_process_authenticate_user): dummy authenticate_user function that always succeeds. (pas_backend_file_process_client_requests): respond to the AuthenticateUser request. * backend/pas/pas-backend-ldap.c (pas_backend_ldap_build_query): gtk_object_unref(sexp) => s_exp_unref(sexp). (pas_backend_ldap_process_authenticate_user): fill in to use ldap_simple_bind_s. (pas_backend_ldap_process_client_requests): respond to the AuthenticateUser request. * backend/pas/pas-book.c (pas_book_queue_authenticate_user): new function. (impl_GNOME_Evolution_Addressbook_Book_authenticateUser): new function. (pas_book_respond_authenticate_user): new function. (pas_book_get_epv): fill in epv->authenticateUser. * backend/pas/pas-book.h: add AuthenticateUser operation type, and add user/passwd to the PASRequest struct. * gui/component/addressbook-storage.c (addressbook_storage_get_source_by_uri): new function. should use a hashtable, perhaps, but the lists will generally be small anyway. * gui/component/addressbook-storage.h: add prototype for addressbook_storage_get_source_by_uri. * gui/component/addressbook-config.c (addressbook_source_dialog_set_source): fill in the binddn if the auth page is shown. * gui/component/addressbook.c (book_open_cb): shoe-horn authentication in here. if the source was configured to use authentication, authenticate the user after opening the ebook. also, be paranoid and clear out the password after authenticating. (book_auth_cb): callback for auth. set the "book" arg on the view->view here. (passwd_cb): set the view's passwd that'll be used in book_open_cb. (addressbook_view_free): g_free view->passwd. svn path=/trunk/; revision=7265 --- addressbook/ChangeLog | 67 +++++++++++++++++++++++++ addressbook/backend/ebook/e-book-listener.c | 27 ++++++++++ addressbook/backend/ebook/e-book-listener.h | 1 + addressbook/backend/ebook/e-book.c | 38 ++++++++++++++ addressbook/backend/ebook/e-book.h | 7 +++ addressbook/backend/idl/addressbook.idl | 6 +++ addressbook/backend/pas/pas-backend-file.c | 13 +++++ addressbook/backend/pas/pas-backend-ldap.c | 34 ++++++++++--- addressbook/backend/pas/pas-book.c | 48 ++++++++++++++++++ addressbook/backend/pas/pas-book.h | 7 ++- addressbook/gui/component/addressbook-config.c | 4 ++ addressbook/gui/component/addressbook-storage.c | 14 ++++++ addressbook/gui/component/addressbook-storage.h | 1 + addressbook/gui/component/addressbook.c | 55 ++++++++++++++++++++ 14 files changed, 313 insertions(+), 9 deletions(-) diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 9ee2d4b6bd..14913b5c19 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,70 @@ +2001-01-04 Chris Toshok + + * backend/ebook/e-book-listener.c + (e_book_listener_queue_authentication_response): new function. + (impl_BookListener_respond_authentication_result): new function. + (e_book_listener_get_epv): fill in + epv->notifyAuthenticationResult. + + * backend/ebook/e-book-listener.h: add AuthenticationResponse to + EBookListenerOperation. + + * backend/ebook/e-book.c (e_book_authenticate_user): new function. + + * backend/ebook/e-book.h: add prototype for + e_book_authenticate_user. + + * backend/idl/addressbook.idl (GNOME:Evolution:Addressbook:Book): + add authenticateUser method. + (GNOME:Evolution:Addressbook:BookListener): add + AuthenticationFailed and AuthenticationRequired to CallStatus. + also add notifyAuthenticationResult method. + + * backend/pas/pas-backend-file.c + (pas_backend_file_process_authenticate_user): dummy + authenticate_user function that always succeeds. + (pas_backend_file_process_client_requests): respond to the + AuthenticateUser request. + + * backend/pas/pas-backend-ldap.c (pas_backend_ldap_build_query): + gtk_object_unref(sexp) => s_exp_unref(sexp). + (pas_backend_ldap_process_authenticate_user): fill in to use + ldap_simple_bind_s. + (pas_backend_ldap_process_client_requests): respond to the + AuthenticateUser request. + + * backend/pas/pas-book.c (pas_book_queue_authenticate_user): new + function. + (impl_GNOME_Evolution_Addressbook_Book_authenticateUser): new + function. + (pas_book_respond_authenticate_user): new function. + (pas_book_get_epv): fill in epv->authenticateUser. + + * backend/pas/pas-book.h: add AuthenticateUser operation type, and + add user/passwd to the PASRequest struct. + + * gui/component/addressbook-storage.c + (addressbook_storage_get_source_by_uri): new function. should use + a hashtable, perhaps, but the lists will generally be small + anyway. + + * gui/component/addressbook-storage.h: add prototype for + addressbook_storage_get_source_by_uri. + + * gui/component/addressbook-config.c + (addressbook_source_dialog_set_source): fill in the binddn if the + auth page is shown. + + * gui/component/addressbook.c (book_open_cb): shoe-horn + authentication in here. if the source was configured to use + authentication, authenticate the user after opening the ebook. + also, be paranoid and clear out the password after authenticating. + (book_auth_cb): callback for auth. set the "book" arg on the + view->view here. + (passwd_cb): set the view's passwd that'll be used in + book_open_cb. + (addressbook_view_free): g_free view->passwd. + 2001-01-04 Christopher James Lahey * gui/component/addressbook-component.c, diff --git a/addressbook/backend/ebook/e-book-listener.c b/addressbook/backend/ebook/e-book-listener.c index abdda55b59..5e1ff72da3 100644 --- a/addressbook/backend/ebook/e-book-listener.c +++ b/addressbook/backend/ebook/e-book-listener.c @@ -187,6 +187,20 @@ e_book_listener_queue_link_status (EBookListener *listener, e_book_listener_queue_response (listener, resp); } +static void +e_book_listener_queue_authentication_response (EBookListener *listener, + EBookStatus status) +{ + EBookListenerResponse *resp; + + resp = g_new0 (EBookListenerResponse, 1); + + resp->op = AuthenticationResponse; + resp->status = status; + + e_book_listener_queue_response (listener, resp); +} + static void impl_BookListener_respond_create_card (PortableServer_Servant servant, const GNOME_Evolution_Addressbook_BookListener_CallStatus status, @@ -325,6 +339,17 @@ impl_BookListener_report_open_book_progress (PortableServer_Servant servant, listener, status_message, percent); } +static void +impl_BookListener_respond_authentication_result (PortableServer_Servant servant, + const GNOME_Evolution_Addressbook_BookListener_CallStatus status, + CORBA_Environment *ev) +{ + EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant)); + + e_book_listener_queue_authentication_response ( + listener, status); +} + static void impl_BookListener_report_connection_status (PortableServer_Servant servant, const CORBA_boolean connected, @@ -561,6 +586,8 @@ e_book_listener_get_epv (void) epv->notifyCardRemoved = impl_BookListener_respond_remove_card; epv->notifyCardModified = impl_BookListener_respond_modify_card; + epv->notifyAuthenticationResult = impl_BookListener_respond_authentication_result; + epv->notifyCursorRequested = impl_BookListener_respond_get_cursor; epv->notifyViewRequested = impl_BookListener_respond_get_view; epv->notifyChangesRequested = impl_BookListener_respond_get_changes; diff --git a/addressbook/backend/ebook/e-book-listener.h b/addressbook/backend/ebook/e-book-listener.h index d553324ee4..42b4644e60 100644 --- a/addressbook/backend/ebook/e-book-listener.h +++ b/addressbook/backend/ebook/e-book-listener.h @@ -46,6 +46,7 @@ typedef enum { GetCursorResponse, GetBookViewResponse, GetChangesResponse, + AuthenticationResponse, /* Async events */ LinkStatusEvent, diff --git a/addressbook/backend/ebook/e-book.c b/addressbook/backend/ebook/e-book.c index f6e6b324d9..65ea7a595d 100644 --- a/addressbook/backend/ebook/e-book.c +++ b/addressbook/backend/ebook/e-book.c @@ -351,6 +351,7 @@ e_book_check_listener_queue (EBookListener *listener, EBook *book) break; case RemoveCardResponse: case ModifyCardResponse: + case AuthenticationResponse: e_book_do_response_generic (book, resp); break; case GetCursorResponse: @@ -560,6 +561,43 @@ e_book_new (void) return book; } +/* User authentication. */ + +void +e_book_authenticate_user (EBook *book, + const char *user, + const char *passwd, + EBookCallback cb, + gpointer closure) +{ + CORBA_Environment ev; + + g_return_if_fail (book != NULL); + g_return_if_fail (E_IS_BOOK (book)); + + if (book->priv->load_state != URILoaded) { + g_warning ("e_book_authenticate_user: No URI loaded!\n"); + return; + } + + CORBA_exception_init (&ev); + + GNOME_Evolution_Addressbook_Book_authenticateUser (book->priv->corba_book, + user, + passwd, + &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("e_book_authenticate_user: Exception authenticating user with the PAS!\n"); + CORBA_exception_free (&ev); + return; + } + + CORBA_exception_free (&ev); + + e_book_queue_op (book, cb, closure, NULL); +} + /* Fetching cards */ /** diff --git a/addressbook/backend/ebook/e-book.h b/addressbook/backend/ebook/e-book.h index 3c3f2bc65b..7dd0917d37 100644 --- a/addressbook/backend/ebook/e-book.h +++ b/addressbook/backend/ebook/e-book.h @@ -59,6 +59,13 @@ gboolean e_book_load_uri (EBook *book, void e_book_unload_uri (EBook *book); char *e_book_get_static_capabilities (EBook *book); +/* User authentication. */ +void e_book_authenticate_user (EBook *book, + const char *user, + const char *passwd, + EBookCallback cb, + gpointer closure); + /* Fetching cards. */ ECard *e_book_get_card (EBook *book, const char *id); diff --git a/addressbook/backend/idl/addressbook.idl b/addressbook/backend/idl/addressbook.idl index 6edfee992d..14d35dc934 100644 --- a/addressbook/backend/idl/addressbook.idl +++ b/addressbook/backend/idl/addressbook.idl @@ -58,6 +58,8 @@ module Addressbook { boolean isWriteable (); boolean isCardWriteable (in CardId Id); + void authenticateUser (in string user, in string passwd); + /* * Adding and deleting cards in the book. */ @@ -101,6 +103,8 @@ module Addressbook { PermissionDenied, CardNotFound, ProtocolNotSupported, + AuthenticationFailed, + AuthenticationRequired, OtherError }; @@ -120,6 +124,8 @@ module Addressbook { void notifyChangesRequested (in CallStatus status, in BookView view); + void notifyAuthenticationResult (in CallStatus status); + /** * notifyConnectionStatus: * diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c index cfe7c90ab8..5a9a5a1005 100644 --- a/addressbook/backend/pas/pas-backend-file.c +++ b/addressbook/backend/pas/pas-backend-file.c @@ -1083,6 +1083,15 @@ pas_backend_file_extract_path_from_uri (const char *uri) return g_strdup (uri + 5); } +static void +pas_backend_file_process_authenticate_user (PASBackend *backend, + PASBook *book, + PASRequest *req) +{ + pas_book_respond_authenticate_user (book, + GNOME_Evolution_Addressbook_BookListener_Success); +} + static gboolean can_write (PASBackend *backend) { @@ -1154,6 +1163,10 @@ pas_backend_file_process_client_requests (PASBook *book) case GetChanges: pas_backend_file_process_get_changes (backend, book, req); break; + + case AuthenticateUser: + pas_backend_file_process_authenticate_user (backend, book, req); + break; } g_free (req); diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c index 4d86538a6e..1aa49cd17b 100644 --- a/addressbook/backend/pas/pas-backend-ldap.c +++ b/addressbook/backend/pas/pas-backend-ldap.c @@ -210,18 +210,18 @@ pas_backend_ldap_connect (PASBackendLDAP *bl) { PASBackendLDAPPrivate *blpriv = bl->priv; -#ifdef DEBUG - { - extern int ldap_debug; - ldap_debug = LDAP_DEBUG_ANY; - } -#endif - /* close connection first if it's open first */ if (blpriv->ldap) ldap_unbind (blpriv->ldap); blpriv->ldap = ldap_open (blpriv->ldap_host, blpriv->ldap_port); +#ifdef DEBUG + { + int debug_level = ~0; + ldap_set_option (blpriv->ldap, LDAP_OPT_DEBUG_LEVEL, &debug_level); + } +#endif + if (NULL != blpriv->ldap) { ldap_simple_bind_s(blpriv->ldap, NULL /*binddn*/, NULL /*passwd*/); @@ -1249,7 +1249,7 @@ pas_backend_ldap_build_query (gchar *query) r = e_sexp_eval(sexp); - gtk_object_unref(GTK_OBJECT(sexp)); + e_sexp_unref (sexp); e_sexp_result_free(r); if (list->next) { @@ -1550,6 +1550,20 @@ pas_backend_ldap_process_check_connection (PASBackend *backend, pas_book_report_connection (book, bl->priv->connected); } +static void +pas_backend_ldap_process_authenticate_user (PASBackend *backend, + PASBook *book, + PASRequest *req) +{ + PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); + int ldap_error = ldap_simple_bind_s(bl->priv->ldap, + req->user, + req->passwd); + + pas_book_respond_authenticate_user (book, + ldap_error_to_response (ldap_error)); +} + static gboolean pas_backend_ldap_can_write (PASBook *book) { @@ -1603,6 +1617,10 @@ pas_backend_ldap_process_client_requests (PASBook *book) case GetChanges: /* FIXME: Code this. */ break; + + case AuthenticateUser: + pas_backend_ldap_process_authenticate_user (backend, book, req); + break; } g_free (req); diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c index 6fded8301d..783c699603 100644 --- a/addressbook/backend/pas/pas-book.c +++ b/addressbook/backend/pas/pas-book.c @@ -105,6 +105,20 @@ pas_book_queue_get_cursor (PASBook *book, const char *search) pas_book_queue_request (book, req); } +static void +pas_book_queue_authenticate_user (PASBook *book, + const char *user, const char *passwd) +{ + PASRequest *req; + + req = g_new0 (PASRequest, 1); + req->op = AuthenticateUser; + req->user = g_strdup(user); + req->passwd = g_strdup(passwd); + + pas_book_queue_request (book, req); +} + static void pas_book_queue_get_book_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search) { @@ -205,6 +219,17 @@ impl_GNOME_Evolution_Addressbook_Book_isCardWriteable (PortableServer_Servant se return retval; } +static void +impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant servant, + const char* user, + const char* passwd, + CORBA_Environment *ev) +{ + PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant)); + + pas_book_queue_authenticate_user (book, user, passwd); +} + static void impl_GNOME_Evolution_Addressbook_Book_addCard (PortableServer_Servant servant, const GNOME_Evolution_Addressbook_VCard vcard, @@ -450,6 +475,28 @@ pas_book_respond_modify (PASBook *book, CORBA_exception_free (&ev); } +/** + * pas_book_respond_authenticate_user: + */ +void +pas_book_respond_authenticate_user (PASBook *book, + GNOME_Evolution_Addressbook_BookListener_CallStatus status) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + + GNOME_Evolution_Addressbook_BookListener_notifyAuthenticationResult ( + book->priv->listener, status, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("pas_book_respond_authenticate_user: Exception " + "responding to BookListener!\n"); + } + + CORBA_exception_free (&ev); +} + /** * pas_book_respond_get_cursor: */ @@ -676,6 +723,7 @@ pas_book_get_epv (void) epv->getVCard = impl_GNOME_Evolution_Addressbook_Book_getVCard; epv->isWriteable = impl_GNOME_Evolution_Addressbook_Book_isWriteable; epv->isCardWriteable = impl_GNOME_Evolution_Addressbook_Book_isCardWriteable; + epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser; epv->addCard = impl_GNOME_Evolution_Addressbook_Book_addCard; epv->removeCard = impl_GNOME_Evolution_Addressbook_Book_removeCard; epv->modifyCard = impl_GNOME_Evolution_Addressbook_Book_modifyCard; diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h index 3c7f5a2bde..d94d859d3e 100644 --- a/addressbook/backend/pas/pas-book.h +++ b/addressbook/backend/pas/pas-book.h @@ -30,7 +30,8 @@ typedef enum { GetCursor, GetBookView, GetChanges, - CheckConnection + CheckConnection, + AuthenticateUser } PASOperation; typedef struct { @@ -39,6 +40,8 @@ typedef struct { char *vcard; char *search; char *change_id; + char *user; + char *passwd; GNOME_Evolution_Addressbook_BookViewListener listener; } PASRequest; @@ -76,6 +79,8 @@ void pas_book_respond_remove (PASBook GNOME_Evolution_Addressbook_BookListener_CallStatus status); void pas_book_respond_modify (PASBook *book, GNOME_Evolution_Addressbook_BookListener_CallStatus status); +void pas_book_respond_authenticate_user (PASBook *book, + GNOME_Evolution_Addressbook_BookListener_CallStatus status); void pas_book_respond_get_cursor (PASBook *book, GNOME_Evolution_Addressbook_BookListener_CallStatus status, PASCardCursor *cursor); diff --git a/addressbook/gui/component/addressbook-config.c b/addressbook/gui/component/addressbook-config.c index ae15b7aaf1..7439fd5b6a 100644 --- a/addressbook/gui/component/addressbook-config.c +++ b/addressbook/gui/component/addressbook-config.c @@ -501,6 +501,10 @@ addressbook_source_dialog_set_source (AddressbookSourceDialog *dialog, Addressbo auth_page = g_list_nth_data (source_page->auths, source->ldap.auth); ldap_auth_type_menuitem_activate (auth_page->item, auth_page); gtk_option_menu_set_history (GTK_OPTION_MENU(source_page->auth_optionmenu), auth_page->auth_type); + + if (auth_page->auth_type == ADDRESSBOOK_LDAP_AUTH_SIMPLE) { + e_utf8_gtk_entry_set_text (GTK_ENTRY (auth_page->binddn), source->ldap.binddn); + } } else { e_utf8_gtk_entry_set_text (GTK_ENTRY (source_page->path), source->file.path); diff --git a/addressbook/gui/component/addressbook-storage.c b/addressbook/gui/component/addressbook-storage.c index e1b02ec93a..df11a38cbe 100644 --- a/addressbook/gui/component/addressbook-storage.c +++ b/addressbook/gui/component/addressbook-storage.c @@ -456,6 +456,20 @@ addressbook_storage_get_sources () return sources; } +AddressbookSource * +addressbook_storage_get_source_by_uri (const char *uri) +{ + GList *l; + + for (l = sources; l ; l = l->next) { + AddressbookSource *source = l->data; + if (!strcmp (uri, source->uri)) + return source; + } + + return NULL; +} + void addressbook_source_free (AddressbookSource *source) { diff --git a/addressbook/gui/component/addressbook-storage.h b/addressbook/gui/component/addressbook-storage.h index 0262207603..518977598e 100644 --- a/addressbook/gui/component/addressbook-storage.h +++ b/addressbook/gui/component/addressbook-storage.h @@ -69,6 +69,7 @@ void addressbook_storage_setup (EvolutionShellComponent *shell_component, const char *evolution_homedir); GList *addressbook_storage_get_sources (void); +AddressbookSource *addressbook_storage_get_source_by_uri (const char *uri); void addressbook_storage_clear_sources (void); AddressbookSource *addressbook_source_copy (const AddressbookSource *source); void addressbook_source_free (AddressbookSource *source); diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c index bdad6ae04c..e9d4f45527 100644 --- a/addressbook/gui/component/addressbook.c +++ b/addressbook/gui/component/addressbook.c @@ -44,6 +44,7 @@ typedef struct { BonoboControl *control; BonoboPropertyBag *properties; char *uri; + char *passwd; } AddressbookView; static void @@ -328,19 +329,73 @@ addressbook_view_free(AddressbookView *view) { if (view->properties) bonobo_object_unref(BONOBO_OBJECT(view->properties)); + g_free(view->passwd); g_free(view->uri); g_free(view); } +static void +book_auth_cb (EBook *book, EBookStatus status, gpointer closure) +{ + AddressbookView *view = closure; + if (status == E_BOOK_STATUS_SUCCESS) { + gtk_object_set(GTK_OBJECT(view->view), + "book", book, + NULL); + } + else { + /* pop up a nice dialog, or redo the authentication + bit some number of times. */ + } +} + +static void +passwd_cb (gchar *string, gpointer data) +{ + AddressbookView *view = (AddressbookView*)data; + + view->passwd = g_strdup (string); +} + static void book_open_cb (EBook *book, EBookStatus status, gpointer closure) { if (status == E_BOOK_STATUS_SUCCESS) { AddressbookView *view = closure; + AddressbookSource *source; + + /* check if the addressbook needs authentication */ + + source = addressbook_storage_get_source_by_uri (view->uri); + if (source && + source->type == ADDRESSBOOK_SOURCE_LDAP && + source->ldap.auth == ADDRESSBOOK_LDAP_AUTH_SIMPLE) { + int button; + char *msg = g_strdup_printf (_("Enter password for %s"), source->ldap.binddn); + /* give a password prompt for the binddn */ + GtkWidget *dialog = gnome_request_dialog (TRUE, msg, NULL, + 0, passwd_cb, view, NULL); + + button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); + + if (button == 0 && *(view->passwd)) { + e_book_authenticate_user (book, source->ldap.binddn, view->passwd, + book_auth_cb, closure); + memset (view->passwd, 0, strlen (view->passwd)); /* clear out the passwd */ + g_free (view->passwd); + view->passwd = NULL; + return; + } + } + + /* if they either didn't configure the source to use + authentication, or they canceled the dialog, + proceed without authenticating */ gtk_object_set(GTK_OBJECT(view->view), "book", book, NULL); + } else { GtkWidget *warning_dialog, *label, *href; warning_dialog = gnome_dialog_new ( -- cgit v1.2.3