1237 lines
36 KiB
Diff
1237 lines
36 KiB
Diff
|
Index: configure.in
|
||
|
===================================================================
|
||
|
--- configure.in (revision 7790)
|
||
|
+++ configure.in (working copy)
|
||
|
@@ -1252,6 +1252,11 @@
|
||
|
dnl Flags for the various libraries we build
|
||
|
dnl ****************************************
|
||
|
|
||
|
+PKG_CHECK_EXISTS([gnome-certauth-0.0],[
|
||
|
+ gnome_certauth="gnome-certauth-0.0 >= 0.0"
|
||
|
+ AC_DEFINE([HAVE_GNOME_CERTAUTH], [1], [Define if you have gnome-certauth])
|
||
|
+])
|
||
|
+
|
||
|
dnl --- libedataserver and libedataserverui flags
|
||
|
|
||
|
E_DATA_SERVER_DEPS="libxml-2.0 gobject-2.0 >= $GLIB_REQUIRED libbonobo-2.0 >= $LIBBONOBO_REQUIRED gconf-2.0 $mozilla_nspr"
|
||
|
@@ -1390,7 +1390,7 @@ AC_SUBST(E_DATA_SERVER_UI_LIBS)
|
||
|
|
||
|
dnl --- evolution-addressbook flags
|
||
|
|
||
|
-EVOLUTION_ADDRESSBOOK_DEPS="libxml-2.0 libgnome-2.0 gnome-vfs-2.0"
|
||
|
+EVOLUTION_ADDRESSBOOK_DEPS="libxml-2.0 libgnome-2.0 gnome-vfs-2.0 $gnome_certauth"
|
||
|
|
||
|
EVO_SET_COMPILE_FLAGS(EVOLUTION_ADDRESSBOOK, $EVOLUTION_ADDRESSBOOK_DEPS)
|
||
|
AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS)
|
||
|
@@ -1398,7 +1398,7 @@ AC_SUBST(EVOLUTION_ADDRESSBOOK_LIBS)
|
||
|
|
||
|
dnl --- evolution-calendar flags
|
||
|
if test "x${enable_calendar}" = "xyes"; then
|
||
|
- EVOLUTION_CALENDAR_DEPS="libxml-2.0 libgnome-2.0 gnome-vfs-2.0"
|
||
|
+ EVOLUTION_CALENDAR_DEPS="libxml-2.0 libgnome-2.0 gnome-vfs-2.0 $gnome_certauth"
|
||
|
|
||
|
EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, $EVOLUTION_CALENDAR_DEPS)
|
||
|
AC_SUBST(EVOLUTION_CALENDAR_CFLAGS)
|
||
|
Index: servers/exchange/storage/exchange-account.c
|
||
|
===================================================================
|
||
|
--- servers/exchange/storage/exchange-account.c (revision 7790)
|
||
|
+++ servers/exchange/storage/exchange-account.c (working copy)
|
||
|
@@ -39,6 +39,9 @@
|
||
|
#include "e2k-utils.h"
|
||
|
#include "exchange-hierarchy-foreign.h"
|
||
|
|
||
|
+#include <sys/types.h>
|
||
|
+#include <unistd.h>
|
||
|
+
|
||
|
/* This is an ugly hack to avoid API break */
|
||
|
/* Added for get_authtype */
|
||
|
#include "exchange-esource.h"
|
||
|
@@ -53,11 +56,23 @@
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
-#define d(x) (x)
|
||
|
+#define TRACE(s, ...) d(fprintf (stderr, "%d:%s:%s():%d "s"\n", getpid(), __FILE__, __PRETTY_FUNCTION__, __LINE__, __VA_ARGS__))
|
||
|
+#define TRACEMSG(s) TRACE("%s", (s))
|
||
|
+#define ENTER TRACEMSG("ENTER")
|
||
|
+#define EXIT TRACEMSG("EXIT")
|
||
|
+#define HASLOCK TRACEMSG("HAS LOCK")
|
||
|
+#define ALREADYLOCKED TRACEMSG("ALREADY LOCKED")
|
||
|
+
|
||
|
+#define d(x)
|
||
|
#define ADS_UF_DONT_EXPIRE_PASSWORD 0x10000
|
||
|
#define ONE_HUNDRED_NANOSECOND 0.000000100
|
||
|
#define SECONDS_IN_DAY 86400
|
||
|
|
||
|
+typedef struct {
|
||
|
+ E2kCreds creds;
|
||
|
+ ExchangeAccount *account;
|
||
|
+} AccountCreds;
|
||
|
+
|
||
|
struct _ExchangeAccountPrivate {
|
||
|
E2kContext *ctx;
|
||
|
E2kGlobalCatalog *gc;
|
||
|
@@ -86,6 +101,10 @@
|
||
|
|
||
|
GMutex *discover_data_lock;
|
||
|
GList *discover_datas;
|
||
|
+
|
||
|
+ AccountCreds creds;
|
||
|
+ GMutex *creds_mutex;
|
||
|
+ GSList *creds_list;
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
@@ -229,6 +248,13 @@
|
||
|
account->priv->fresh_folders = NULL;
|
||
|
}
|
||
|
|
||
|
+ if (account->priv->creds_mutex) {
|
||
|
+ g_mutex_free (account->priv->creds_mutex);
|
||
|
+ account->priv->creds_mutex = NULL;
|
||
|
+ }
|
||
|
+ g_slist_free (account->priv->creds_list);
|
||
|
+ account->priv->creds_list = NULL;
|
||
|
+
|
||
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||
|
}
|
||
|
|
||
|
@@ -1169,14 +1195,21 @@
|
||
|
|
||
|
g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), FALSE);
|
||
|
|
||
|
- g_mutex_lock (account->priv->connect_lock);
|
||
|
- if (account->priv->ctx) {
|
||
|
- g_object_unref (account->priv->ctx);
|
||
|
- account->priv->ctx = NULL;
|
||
|
+ ENTER;
|
||
|
+
|
||
|
+ if (g_mutex_trylock (account->priv->connect_lock)) {
|
||
|
+ HASLOCK;
|
||
|
+ if (account->priv->ctx) {
|
||
|
+ g_object_unref (account->priv->ctx);
|
||
|
+ account->priv->ctx = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ account->priv->account_online = OFFLINE_MODE;
|
||
|
+ g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ } else {
|
||
|
+ ALREADYLOCKED;
|
||
|
}
|
||
|
-
|
||
|
- account->priv->account_online = OFFLINE_MODE;
|
||
|
- g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ EXIT;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
@@ -1195,11 +1228,15 @@
|
||
|
exchange_account_set_online (ExchangeAccount *account)
|
||
|
{
|
||
|
g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), FALSE);
|
||
|
-
|
||
|
- g_mutex_lock (account->priv->connect_lock);
|
||
|
- account->priv->account_online = ONLINE_MODE;
|
||
|
- g_mutex_unlock (account->priv->connect_lock);
|
||
|
-
|
||
|
+ ENTER;
|
||
|
+ if (g_mutex_trylock (account->priv->connect_lock)) {
|
||
|
+ HASLOCK;
|
||
|
+ account->priv->account_online = ONLINE_MODE;
|
||
|
+ g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ } else {
|
||
|
+ ALREADYLOCKED;
|
||
|
+ }
|
||
|
+ EXIT;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
@@ -1342,6 +1379,117 @@
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
+/* we are just a patsy */
|
||
|
+static char *
|
||
|
+account_creds_http_auth_method (E2kCreds *ecreds)
|
||
|
+{
|
||
|
+ AccountCreds *creds = (AccountCreds *)ecreds;
|
||
|
+ ExchangeAccount *account = creds->account;
|
||
|
+ E2kCreds *sub_creds;
|
||
|
+ char *method;
|
||
|
+
|
||
|
+ g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
|
||
|
+
|
||
|
+ g_mutex_lock (account->priv->creds_mutex);
|
||
|
+ sub_creds = g_slist_nth_data (account->priv->creds_list, 0);
|
||
|
+ method = sub_creds ? sub_creds->http_auth_method (sub_creds) : NULL;
|
||
|
+ g_mutex_unlock (account->priv->creds_mutex);
|
||
|
+
|
||
|
+ return method;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+account_creds_http_authenticate (E2kCreds *ecreds,
|
||
|
+ const char *auth_type, const char *auth_realm,
|
||
|
+ char **username, char **password)
|
||
|
+{
|
||
|
+ AccountCreds *creds = (AccountCreds *)ecreds;
|
||
|
+ ExchangeAccount *account = creds->account;
|
||
|
+ E2kCreds *sub_creds;
|
||
|
+
|
||
|
+ g_return_if_fail (EXCHANGE_IS_ACCOUNT (account));
|
||
|
+
|
||
|
+ g_mutex_lock (account->priv->creds_mutex);
|
||
|
+ sub_creds = g_slist_nth_data (account->priv->creds_list, 0);
|
||
|
+ if (sub_creds) {
|
||
|
+ sub_creds->http_authenticate (sub_creds, auth_type, auth_realm, username, password);
|
||
|
+ }
|
||
|
+ g_mutex_unlock (account->priv->creds_mutex);
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+account_creds_ssl_cert_request (E2kCreds *ecreds,
|
||
|
+ const gnutls_datum_t *req_ca_rdn_der,
|
||
|
+ int nreqs,
|
||
|
+ gnutls_datum_t **cert_der_ret,
|
||
|
+ int *cert_der_ret_length)
|
||
|
+{
|
||
|
+ AccountCreds *creds = (AccountCreds *)ecreds;
|
||
|
+ ExchangeAccount *account = creds->account;
|
||
|
+ E2kCreds *sub_creds;
|
||
|
+ int ret = 0;
|
||
|
+ ENTER;
|
||
|
+ g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), -1);
|
||
|
+
|
||
|
+ g_mutex_lock (account->priv->creds_mutex);
|
||
|
+ HASLOCK;
|
||
|
+ sub_creds = g_slist_nth_data (account->priv->creds_list, 0);
|
||
|
+ if (sub_creds) {
|
||
|
+ TRACEMSG("delegating cert request...");
|
||
|
+ sub_creds->ssl_cert_request (sub_creds,
|
||
|
+ req_ca_rdn_der, nreqs,
|
||
|
+ cert_der_ret, cert_der_ret_length);
|
||
|
+ }
|
||
|
+ g_mutex_unlock (account->priv->creds_mutex);
|
||
|
+ EXIT;
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+account_creds_ssl_cert_sign (E2kCreds *ecreds,
|
||
|
+ const gnutls_datum_t *cert_der,
|
||
|
+ const gnutls_datum_t *hash_data,
|
||
|
+ gnutls_datum_t *sig_data)
|
||
|
+{
|
||
|
+ AccountCreds *creds = (AccountCreds *)ecreds;
|
||
|
+ ExchangeAccount *account = creds->account;
|
||
|
+ E2kCreds *sub_creds;
|
||
|
+ int ret = 0;
|
||
|
+
|
||
|
+ g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), -1);
|
||
|
+
|
||
|
+ g_mutex_lock (account->priv->creds_mutex);
|
||
|
+ sub_creds = g_slist_nth_data (account->priv->creds_list, 0);
|
||
|
+ if (sub_creds) {
|
||
|
+ ret = sub_creds->ssl_cert_sign (sub_creds,
|
||
|
+ cert_der,
|
||
|
+ hash_data, sig_data);
|
||
|
+ }
|
||
|
+ g_mutex_unlock (account->priv->creds_mutex);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+void
|
||
|
+exchange_account_add_creds (ExchangeAccount *account,
|
||
|
+ E2kCreds *creds)
|
||
|
+{
|
||
|
+ g_return_if_fail (EXCHANGE_IS_ACCOUNT (account));
|
||
|
+ g_mutex_lock (account->priv->creds_mutex);
|
||
|
+ account->priv->creds_list = g_slist_prepend (account->priv->creds_list, creds);
|
||
|
+ g_mutex_unlock (account->priv->creds_mutex);
|
||
|
+}
|
||
|
+
|
||
|
+void
|
||
|
+exchange_account_remove_creds (ExchangeAccount *account,
|
||
|
+ E2kCreds *creds)
|
||
|
+{
|
||
|
+ g_return_if_fail (EXCHANGE_IS_ACCOUNT (account));
|
||
|
+ g_mutex_lock (account->priv->creds_mutex);
|
||
|
+ account->priv->creds_list = g_slist_remove (account->priv->creds_list, creds);
|
||
|
+ g_mutex_unlock (account->priv->creds_mutex);
|
||
|
+}
|
||
|
+
|
||
|
/**
|
||
|
* exchange_account_connect:
|
||
|
* @account: an #ExchangeAccount
|
||
|
@@ -1370,13 +1518,16 @@
|
||
|
E2kOperation gcop;
|
||
|
char *user_name = NULL;
|
||
|
|
||
|
+ ENTER;
|
||
|
+
|
||
|
*info_result = EXCHANGE_ACCOUNT_UNKNOWN_ERROR;
|
||
|
g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
|
||
|
|
||
|
*info_result = EXCHANGE_ACCOUNT_CONNECT_SUCCESS;
|
||
|
- exchange_account_is_offline (account, &mode);
|
||
|
|
||
|
g_mutex_lock (account->priv->connect_lock);
|
||
|
+ HASLOCK;
|
||
|
+ exchange_account_is_offline (account, &mode);
|
||
|
|
||
|
if (mode == UNSUPPORTED_MODE) {
|
||
|
*info_result = EXCHANGE_ACCOUNT_CONNECT_ERROR;
|
||
|
@@ -1394,10 +1545,17 @@
|
||
|
else {
|
||
|
*info_result = EXCHANGE_ACCOUNT_CONNECT_ERROR;
|
||
|
}
|
||
|
+ EXIT;
|
||
|
return NULL;
|
||
|
} else if (account->priv->ctx) {
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ EXIT;
|
||
|
return account->priv->ctx;
|
||
|
+ } else if (!pword && !account->priv->creds_list) {
|
||
|
+ g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ *info_result = EXCHANGE_ACCOUNT_PASSWORD_INCORRECT;
|
||
|
+ EXIT;
|
||
|
+ return NULL;
|
||
|
}
|
||
|
|
||
|
account->priv->connecting = TRUE;
|
||
|
@@ -1409,7 +1567,7 @@
|
||
|
|
||
|
ac = e2k_autoconfig_new (account->home_uri,
|
||
|
user_name,
|
||
|
- NULL,
|
||
|
+ pword,
|
||
|
account->priv->auth_pref);
|
||
|
g_free (user_name);
|
||
|
|
||
|
@@ -1417,15 +1575,10 @@
|
||
|
account->priv->ad_limit);
|
||
|
|
||
|
if (!pword) {
|
||
|
- account->priv->connecting = FALSE;
|
||
|
- g_mutex_unlock (account->priv->connect_lock);
|
||
|
- *info_result = EXCHANGE_ACCOUNT_PASSWORD_INCORRECT;
|
||
|
- e2k_autoconfig_free (ac);
|
||
|
- return NULL;
|
||
|
+ TRACEMSG("setting creds...");
|
||
|
+ e2k_autoconfig_set_creds (ac, &account->priv->creds.creds);
|
||
|
}
|
||
|
|
||
|
- e2k_autoconfig_set_password (ac, pword);
|
||
|
-
|
||
|
try_connect_again:
|
||
|
account->priv->ctx = e2k_autoconfig_get_context (ac, NULL, &result);
|
||
|
|
||
|
@@ -1435,12 +1588,14 @@
|
||
|
account->priv->nt_domain = NULL;
|
||
|
|
||
|
if (result != E2K_AUTOCONFIG_OK) {
|
||
|
+ TRACE("result was not ok: %d", result);
|
||
|
#ifdef HAVE_KRB5
|
||
|
if ( is_password_expired (account, ac)) {
|
||
|
*info_result = EXCHANGE_ACCOUNT_PASSWORD_EXPIRED;
|
||
|
account->priv->connecting = FALSE;
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
e2k_autoconfig_free (ac);
|
||
|
+ EXIT;
|
||
|
return NULL;
|
||
|
}
|
||
|
#endif
|
||
|
@@ -1451,6 +1606,7 @@
|
||
|
e2k_autoconfig_free (ac);
|
||
|
account->priv->connecting = FALSE;
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ EXIT;
|
||
|
return NULL;
|
||
|
|
||
|
case E2K_AUTOCONFIG_AUTH_ERROR_TRY_DOMAIN:
|
||
|
@@ -1458,6 +1614,7 @@
|
||
|
e2k_autoconfig_free (ac);
|
||
|
account->priv->connecting = FALSE;
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ EXIT;
|
||
|
return NULL;
|
||
|
|
||
|
case E2K_AUTOCONFIG_AUTH_ERROR_TRY_NTLM:
|
||
|
@@ -1515,6 +1672,7 @@
|
||
|
}
|
||
|
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ EXIT;
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
@@ -1531,6 +1689,7 @@
|
||
|
account->priv->connecting = FALSE;
|
||
|
*info_result = EXCHANGE_ACCOUNT_UNKNOWN_ERROR;
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
+ EXIT;
|
||
|
return NULL; /* FIXME: what error has happened? */
|
||
|
}
|
||
|
|
||
|
@@ -1555,6 +1714,7 @@
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
if (nresults)
|
||
|
e2k_results_free (results, nresults);
|
||
|
+ EXIT;
|
||
|
return NULL; /* FIXME: what error has happened? */
|
||
|
}
|
||
|
|
||
|
@@ -1600,6 +1760,7 @@
|
||
|
g_mutex_unlock (account->priv->connect_lock);
|
||
|
if (nresults)
|
||
|
e2k_results_free (results, nresults);
|
||
|
+ EXIT;
|
||
|
return account->priv->ctx;
|
||
|
}
|
||
|
|
||
|
@@ -2253,6 +2414,14 @@
|
||
|
|
||
|
e2k_uri_free (uri);
|
||
|
|
||
|
+ account->priv->creds.creds.http_auth_method = account_creds_http_auth_method;
|
||
|
+ account->priv->creds.creds.http_authenticate = account_creds_http_authenticate;
|
||
|
+ account->priv->creds.creds.ssl_cert_request = account_creds_ssl_cert_request;
|
||
|
+ account->priv->creds.creds.ssl_cert_sign = account_creds_ssl_cert_sign;
|
||
|
+ account->priv->creds.account = account;
|
||
|
+
|
||
|
+ account->priv->creds_mutex = g_mutex_new ();
|
||
|
+
|
||
|
return account;
|
||
|
}
|
||
|
|
||
|
Index: servers/exchange/storage/exchange-account.h
|
||
|
===================================================================
|
||
|
--- servers/exchange/storage/exchange-account.h (revision 7790)
|
||
|
+++ servers/exchange/storage/exchange-account.h (working copy)
|
||
|
@@ -93,6 +93,11 @@
|
||
|
|
||
|
char *exchange_account_get_authtype (ExchangeAccount *account);
|
||
|
|
||
|
+void exchange_account_add_creds (ExchangeAccount *acct,
|
||
|
+ E2kCreds *creds);
|
||
|
+void exchange_account_remove_creds (ExchangeAccount *acct,
|
||
|
+ E2kCreds *creds);
|
||
|
+
|
||
|
E2kContext *exchange_account_connect (ExchangeAccount *acct,
|
||
|
const char *pword,
|
||
|
ExchangeAccountResult *result);
|
||
|
Index: servers/exchange/lib/e2k-context.c
|
||
|
===================================================================
|
||
|
--- servers/exchange/lib/e2k-context.c (revision 7790)
|
||
|
+++ servers/exchange/lib/e2k-context.c (working copy)
|
||
|
@@ -51,7 +51,6 @@
|
||
|
|
||
|
#include <libsoup/soup-address.h>
|
||
|
#include <libsoup/soup-message-filter.h>
|
||
|
-#include <libsoup/soup-session-async.h>
|
||
|
#include <libsoup/soup-session-sync.h>
|
||
|
#include <libsoup/soup-socket.h>
|
||
|
#include <libsoup/soup-uri.h>
|
||
|
@@ -59,6 +58,15 @@
|
||
|
#include <libxml/tree.h>
|
||
|
#include <libxml/xmlmemory.h>
|
||
|
|
||
|
+#define GCA_TRACE(s, ...) d(fprintf (stderr, "%d:%s:%s():%d "s"\n", getpid(), __FILE__, __PRETTY_FUNCTION__, __LINE__, __VA_ARGS__))
|
||
|
+#define d(x)
|
||
|
+
|
||
|
+#define GCA_TRACEMSG(s) GCA_TRACE("%s", (s))
|
||
|
+#define GCA_ENTER GCA_TRACEMSG("ENTER")
|
||
|
+#define GCA_EXIT GCA_TRACEMSG("EXIT")
|
||
|
+#define GCA_HASLOCK GCA_TRACEMSG("HAS LOCK")
|
||
|
+#define GCA_ALREADYLOCKED GCA_TRACEMSG("ALREADY LOCKED")
|
||
|
+
|
||
|
#ifdef G_OS_WIN32
|
||
|
/* The strtok() in Microsoft's C library is MT-safe (not stateless,
|
||
|
* but that is not needed here).
|
||
|
@@ -89,8 +97,8 @@
|
||
|
static guint signals [LAST_SIGNAL] = { 0 };
|
||
|
|
||
|
struct _E2kContextPrivate {
|
||
|
- SoupSession *session, *async_session;
|
||
|
- char *owa_uri, *username, *password;
|
||
|
+ SoupSession *session;
|
||
|
+ char *owa_uri;
|
||
|
time_t last_timestamp;
|
||
|
|
||
|
/* Notification listener */
|
||
|
@@ -114,8 +114,18 @@
|
||
|
char *cookie;
|
||
|
gboolean cookie_verified;
|
||
|
EProxy* proxy;
|
||
|
+
|
||
|
+ E2kCreds *creds;
|
||
|
+ gboolean free_creds;
|
||
|
};
|
||
|
|
||
|
+typedef struct {
|
||
|
+ E2kCreds creds;
|
||
|
+ char *username;
|
||
|
+ char *authmech;
|
||
|
+ char *password;
|
||
|
+} E2kAuthCreds;
|
||
|
+
|
||
|
/* For operations with progress */
|
||
|
#define E2K_CONTEXT_MIN_BATCH_SIZE 25
|
||
|
#define E2K_CONTEXT_MAX_BATCH_SIZE 100
|
||
|
@@ -144,6 +162,31 @@
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
+release_creds (E2kContext *ctx)
|
||
|
+{
|
||
|
+ E2kAuthCreds *creds;
|
||
|
+
|
||
|
+ if (!ctx->priv->creds) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!ctx->priv->free_creds) {
|
||
|
+ ctx->priv->creds = NULL;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ creds = (E2kAuthCreds *)ctx->priv->creds;
|
||
|
+
|
||
|
+ g_free (creds->username);
|
||
|
+ g_free (creds->authmech);
|
||
|
+ g_free (creds->password);
|
||
|
+
|
||
|
+ g_free (creds);
|
||
|
+ ctx->priv->free_creds = FALSE;
|
||
|
+ ctx->priv->creds = NULL;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
dispose (GObject *object)
|
||
|
{
|
||
|
E2kContext *ctx = E2K_CONTEXT (object);
|
||
|
@@ -151,10 +194,6 @@
|
||
|
if (ctx->priv) {
|
||
|
if (ctx->priv->owa_uri)
|
||
|
g_free (ctx->priv->owa_uri);
|
||
|
- if (ctx->priv->username)
|
||
|
- g_free (ctx->priv->username);
|
||
|
- if (ctx->priv->password)
|
||
|
- g_free (ctx->priv->password);
|
||
|
|
||
|
if (ctx->priv->get_local_address_sock)
|
||
|
g_object_unref (ctx->priv->get_local_address_sock);
|
||
|
@@ -237,11 +247,11 @@
|
||
|
|
||
|
if (ctx->priv->session)
|
||
|
g_object_unref (ctx->priv->session);
|
||
|
- if (ctx->priv->async_session)
|
||
|
- g_object_unref (ctx->priv->async_session);
|
||
|
|
||
|
g_free (ctx->priv->cookie);
|
||
|
|
||
|
+ release_creds (ctx);
|
||
|
+
|
||
|
if (ctx->priv->proxy) {
|
||
|
g_object_unref (ctx->priv->proxy);
|
||
|
ctx->priv->proxy = NULL;
|
||
|
@@ -340,10 +379,116 @@
|
||
|
{
|
||
|
E2kContext *ctx = user_data;
|
||
|
|
||
|
- *username = g_strdup (ctx->priv->username);
|
||
|
- *password = g_strdup (ctx->priv->password);
|
||
|
+ if (ctx->priv->creds && ctx->priv->creds->http_authenticate) {
|
||
|
+ ctx->priv->creds->http_authenticate (ctx->priv->creds,
|
||
|
+ auth_type, auth_realm,
|
||
|
+ username, password);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+session_certificate_requested (SoupSession *session,
|
||
|
+ const gnutls_datum_t *req_ca_rdn,
|
||
|
+ int nreqs,
|
||
|
+ gnutls_datum_t **cert_der_ret,
|
||
|
+ int *cert_der_ret_length,
|
||
|
+ gpointer user_data)
|
||
|
+{
|
||
|
+ E2kContext *ctx = user_data;
|
||
|
+ int ret = 0;
|
||
|
+ GCA_ENTER;
|
||
|
+ g_return_val_if_fail (E2K_IS_CONTEXT (ctx), -1);
|
||
|
+
|
||
|
+ if (ctx->priv->creds && ctx->priv->creds->ssl_cert_request) {
|
||
|
+ ret = ctx->priv->creds->ssl_cert_request (
|
||
|
+ ctx->priv->creds,
|
||
|
+ req_ca_rdn, nreqs,
|
||
|
+ cert_der_ret, cert_der_ret_length);
|
||
|
+ }
|
||
|
+ GCA_EXIT;
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+session_sign_data (SoupSession *session,
|
||
|
+ gnutls_datum_t *cert,
|
||
|
+ const gnutls_datum_t *hash_data,
|
||
|
+ gnutls_datum_t *sig_data,
|
||
|
+ gpointer user_data)
|
||
|
+{
|
||
|
+ E2kContext *ctx = user_data;
|
||
|
+ int ret = 0;
|
||
|
+ GCA_ENTER;
|
||
|
+ g_return_val_if_fail (E2K_IS_CONTEXT (ctx), -1);
|
||
|
+
|
||
|
+ if (ctx->priv->creds && ctx->priv->creds->ssl_cert_sign) {
|
||
|
+ ret = ctx->priv->creds->ssl_cert_sign (
|
||
|
+ ctx->priv->creds, cert,
|
||
|
+ hash_data, sig_data);
|
||
|
+ }
|
||
|
+ GCA_EXIT;
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+void
|
||
|
+e2k_context_set_creds (E2kContext *ctx,
|
||
|
+ E2kCreds *creds)
|
||
|
+{
|
||
|
+ guint timeout = E2K_SOUP_SESSION_TIMEOUT;
|
||
|
+ char *authmech = NULL;
|
||
|
+
|
||
|
+ g_return_if_fail (E2K_IS_CONTEXT (ctx));
|
||
|
+ g_return_if_fail (creds != NULL);
|
||
|
+
|
||
|
+ /* Destroy the old sessions so we don't reuse old auths */
|
||
|
+ if (ctx->priv->session)
|
||
|
+ g_object_unref (ctx->priv->session);
|
||
|
+
|
||
|
+ release_creds (ctx);
|
||
|
+ ctx->priv->creds = creds;
|
||
|
+
|
||
|
+ /* Set a default timeout value of 30 seconds.
|
||
|
+ FIXME: Make timeout configurable
|
||
|
+ */
|
||
|
+ if (g_getenv ("SOUP_SESSION_TIMEOUT"))
|
||
|
+ timeout = atoi (g_getenv ("SOUP_SESSION_TIMEOUT"));
|
||
|
+
|
||
|
+ if (ctx->priv->creds->http_auth_method) {
|
||
|
+ authmech = ctx->priv->creds->http_auth_method (ctx->priv->creds);
|
||
|
+ }
|
||
|
+
|
||
|
+ ctx->priv->session = soup_session_sync_new_with_options (
|
||
|
+ SOUP_SESSION_USE_NTLM, !authmech || !strcmp (authmech, "NTLM"),
|
||
|
+ SOUP_SESSION_TIMEOUT, timeout,
|
||
|
+ NULL);
|
||
|
+ g_signal_connect (ctx->priv->session, "authenticate",
|
||
|
+ G_CALLBACK (session_authenticate), ctx);
|
||
|
+ g_signal_connect (ctx->priv->session, "certificate-requested",
|
||
|
+ G_CALLBACK (session_certificate_requested), ctx);
|
||
|
+ g_signal_connect (ctx->priv->session, "sign-data",
|
||
|
+ G_CALLBACK (session_sign_data), ctx);
|
||
|
+ soup_session_add_filter (ctx->priv->session,
|
||
|
+ SOUP_MESSAGE_FILTER (ctx));
|
||
|
+ g_free (authmech);
|
||
|
+}
|
||
|
+
|
||
|
+static char *
|
||
|
+auth_creds_http_auth_method (E2kCreds *e2k_creds)
|
||
|
+{
|
||
|
+ E2kAuthCreds *creds = (E2kAuthCreds *)e2k_creds;
|
||
|
+ return creds->authmech ? g_strdup (creds->authmech) : NULL;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+auth_creds_http_authenticate (E2kCreds *e2k_creds,
|
||
|
+ const char *auth_type, const char *auth_realm,
|
||
|
+ char **username, char **password)
|
||
|
+{
|
||
|
+ E2kAuthCreds *creds = (E2kAuthCreds *)e2k_creds;
|
||
|
+ *username = g_strdup (creds->username);
|
||
|
+ *password = g_strdup (creds->password);
|
||
|
+}
|
||
|
+
|
||
|
/**
|
||
|
* e2k_context_set_auth:
|
||
|
* @ctx: the context
|
||
|
@@ -533,59 +548,34 @@
|
||
|
const char *domain, const char *authmech,
|
||
|
const char *password)
|
||
|
{
|
||
|
- guint timeout = E2K_SOUP_SESSION_TIMEOUT;
|
||
|
- SoupUri* uri = NULL;
|
||
|
+ E2kAuthCreds *creds;
|
||
|
|
||
|
g_return_if_fail (E2K_IS_CONTEXT (ctx));
|
||
|
|
||
|
+ creds = g_new0 (E2kAuthCreds, 1);
|
||
|
if (username) {
|
||
|
- g_free (ctx->priv->username);
|
||
|
if (domain) {
|
||
|
- ctx->priv->username =
|
||
|
- g_strdup_printf ("%s\\%s", domain,
|
||
|
- username);
|
||
|
+ creds->username =
|
||
|
+ g_strdup_printf ("%s\\%s", domain, username);
|
||
|
} else
|
||
|
- ctx->priv->username = g_strdup (username);
|
||
|
+ creds->username = g_strdup (username);
|
||
|
}
|
||
|
|
||
|
+ if (authmech) {
|
||
|
+ creds->authmech = g_strdup (authmech);
|
||
|
+ }
|
||
|
+
|
||
|
if (password) {
|
||
|
- g_free (ctx->priv->password);
|
||
|
- ctx->priv->password = g_strdup (password);
|
||
|
+ creds->password = g_strdup (password);
|
||
|
}
|
||
|
|
||
|
- /* Destroy the old sessions so we don't reuse old auths */
|
||
|
- if (ctx->priv->session)
|
||
|
- g_object_unref (ctx->priv->session);
|
||
|
- if (ctx->priv->async_session)
|
||
|
- g_object_unref (ctx->priv->async_session);
|
||
|
-
|
||
|
- /* Set a default timeout value of 30 seconds.
|
||
|
- FIXME: Make timeout configurable
|
||
|
- */
|
||
|
- if (g_getenv ("SOUP_SESSION_TIMEOUT"))
|
||
|
- timeout = atoi (g_getenv ("SOUP_SESSION_TIMEOUT"));
|
||
|
-
|
||
|
- /* Check do we need a proxy to contact the server? */
|
||
|
- if (e_proxy_require_proxy_for_uri (ctx->priv->proxy, ctx->priv->owa_uri))
|
||
|
- uri = e_proxy_peek_uri (ctx->priv->proxy);
|
||
|
-
|
||
|
- ctx->priv->session = soup_session_sync_new_with_options (
|
||
|
- SOUP_SESSION_USE_NTLM, !authmech || !strcmp (authmech, "NTLM"),
|
||
|
- SOUP_SESSION_TIMEOUT, timeout,
|
||
|
- SOUP_SESSION_PROXY_URI, uri,
|
||
|
- NULL);
|
||
|
- g_signal_connect (ctx->priv->session, "authenticate",
|
||
|
- G_CALLBACK (session_authenticate), ctx);
|
||
|
- soup_session_add_filter (ctx->priv->session,
|
||
|
- SOUP_MESSAGE_FILTER (ctx));
|
||
|
-
|
||
|
- ctx->priv->async_session = soup_session_async_new_with_options (
|
||
|
- SOUP_SESSION_USE_NTLM, !authmech || !strcmp (authmech, "NTLM"),
|
||
|
- SOUP_SESSION_PROXY_URI, uri, NULL);
|
||
|
- g_signal_connect (ctx->priv->async_session, "authenticate",
|
||
|
- G_CALLBACK (session_authenticate), ctx);
|
||
|
- soup_session_add_filter (ctx->priv->async_session,
|
||
|
- SOUP_MESSAGE_FILTER (ctx));
|
||
|
+ creds->creds.http_auth_method = auth_creds_http_auth_method;
|
||
|
+ creds->creds.http_authenticate = auth_creds_http_authenticate;
|
||
|
+
|
||
|
+ e2k_context_set_creds (ctx, &creds->creds);
|
||
|
+ /* we can't set this before because release_creds would then
|
||
|
+ * free it */
|
||
|
+ ctx->priv->free_creds = TRUE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
@@ -550,6 +676,8 @@
|
||
|
SoupMessage *post_msg;
|
||
|
GString *form_body, *cookie_str;
|
||
|
const GSList *cookies, *c;
|
||
|
+ char *username = NULL;
|
||
|
+ char *password = NULL;
|
||
|
|
||
|
g_return_val_if_fail (E2K_IS_CONTEXT (ctx), FALSE);
|
||
|
|
||
|
@@ -568,7 +696,7 @@
|
||
|
/* Otherwise, it's just expired. */
|
||
|
}
|
||
|
|
||
|
- if (!ctx->priv->username || !ctx->priv->password)
|
||
|
+ if (!ctx->priv->creds || !ctx->priv->creds->http_authenticate)
|
||
|
return FALSE;
|
||
|
|
||
|
in_fba_auth = TRUE;
|
||
|
@@ -608,6 +736,15 @@
|
||
|
action = g_strdup (value);
|
||
|
xmlFree (value);
|
||
|
|
||
|
+ /* we already checked this above */
|
||
|
+ ctx->priv->creds->http_authenticate (ctx->priv->creds,
|
||
|
+ "", "", /* fake these... */
|
||
|
+ &username, &password);
|
||
|
+
|
||
|
+ if (!username || !password) {
|
||
|
+ goto failed;
|
||
|
+ }
|
||
|
+
|
||
|
form_body = g_string_new (NULL);
|
||
|
while ((node = e2k_xml_find (node, "input"))) {
|
||
|
name = xmlGetProp (node, "name");
|
||
|
@@ -626,11 +763,11 @@
|
||
|
g_string_append_c (form_body, '&');
|
||
|
} else if (!g_ascii_strcasecmp (name, "username")) {
|
||
|
g_string_append (form_body, "username=");
|
||
|
- e2k_uri_append_encoded (form_body, ctx->priv->username, FALSE, NULL);
|
||
|
+ e2k_uri_append_encoded (form_body, username, FALSE, NULL);
|
||
|
g_string_append_c (form_body, '&');
|
||
|
} else if (!g_ascii_strcasecmp (name, "password")) {
|
||
|
g_string_append (form_body, "password=");
|
||
|
- e2k_uri_append_encoded (form_body, ctx->priv->password, FALSE, NULL);
|
||
|
+ e2k_uri_append_encoded (form_body, password, FALSE, NULL);
|
||
|
g_string_append_c (form_body, '&');
|
||
|
}
|
||
|
|
||
|
@@ -638,6 +775,12 @@
|
||
|
xmlFree (value);
|
||
|
xmlFree (name);
|
||
|
}
|
||
|
+ g_free (username);
|
||
|
+ username = NULL;
|
||
|
+
|
||
|
+ g_free (password);
|
||
|
+ password = NULL;
|
||
|
+
|
||
|
g_string_append_printf (form_body, "trusted=%d", E2K_FBA_FLAG_TRUSTED);
|
||
|
xmlFreeDoc (doc);
|
||
|
doc = NULL;
|
||
|
@@ -687,6 +830,8 @@
|
||
|
in_fba_auth = FALSE;
|
||
|
if (doc)
|
||
|
xmlFreeDoc (doc);
|
||
|
+ g_free (username);
|
||
|
+ g_free (password);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
@@ -842,7 +987,7 @@
|
||
|
{
|
||
|
g_return_if_fail (E2K_IS_CONTEXT (ctx));
|
||
|
|
||
|
- soup_session_queue_message (ctx->priv->async_session, msg,
|
||
|
+ soup_session_queue_message (ctx->priv->session, msg,
|
||
|
callback, user_data);
|
||
|
}
|
||
|
|
||
|
--- servers/exchange/lib/e2k-context.c~ 2007-07-31 15:59:43.000000000 -0400
|
||
|
+++ servers/exchange/lib/e2k-context.c 2007-07-31 16:08:11.000000000 -0400
|
||
|
@@ -463,6 +473,7 @@
|
||
|
E2kCreds *creds)
|
||
|
{
|
||
|
guint timeout = E2K_SOUP_SESSION_TIMEOUT;
|
||
|
+ SoupUri* uri = NULL;
|
||
|
char *authmech = NULL;
|
||
|
|
||
|
g_return_if_fail (E2K_IS_CONTEXT (ctx));
|
||
|
@@ -481,6 +492,10 @@
|
||
|
if (g_getenv ("SOUP_SESSION_TIMEOUT"))
|
||
|
timeout = atoi (g_getenv ("SOUP_SESSION_TIMEOUT"));
|
||
|
|
||
|
+ /* Check do we need a proxy to contact the server? */
|
||
|
+ if (e_proxy_require_proxy_for_uri (ctx->priv->proxy, ctx->priv->owa_uri))
|
||
|
+ uri = e_proxy_peek_uri (ctx->priv->proxy);
|
||
|
+
|
||
|
if (ctx->priv->creds->http_auth_method) {
|
||
|
authmech = ctx->priv->creds->http_auth_method (ctx->priv->creds);
|
||
|
}
|
||
|
@@ -488,6 +503,7 @@
|
||
|
ctx->priv->session = soup_session_sync_new_with_options (
|
||
|
SOUP_SESSION_USE_NTLM, !authmech || !strcmp (authmech, "NTLM"),
|
||
|
SOUP_SESSION_TIMEOUT, timeout,
|
||
|
+ SOUP_SESSION_PROXY_URI, uri,
|
||
|
NULL);
|
||
|
g_signal_connect (ctx->priv->session, "authenticate",
|
||
|
G_CALLBACK (session_authenticate), ctx);
|
||
|
Index: servers/exchange/lib/e2k-context.h
|
||
|
===================================================================
|
||
|
--- servers/exchange/lib/e2k-context.h (revision 7790)
|
||
|
+++ servers/exchange/lib/e2k-context.h (working copy)
|
||
|
@@ -9,6 +9,8 @@
|
||
|
|
||
|
#include <glib-object.h>
|
||
|
|
||
|
+#include <gnutls/gnutls.h>
|
||
|
+
|
||
|
#include "e2k-types.h"
|
||
|
#include "e2k-operation.h"
|
||
|
#include "e2k-http-utils.h"
|
||
|
@@ -47,6 +49,25 @@
|
||
|
const char *domain,
|
||
|
const char *authmech,
|
||
|
const char *password);
|
||
|
+struct _E2kCreds {
|
||
|
+ char *(*http_auth_method) (E2kCreds *creds);
|
||
|
+ void (*http_authenticate) (E2kCreds *creds,
|
||
|
+ const char *auth_type, const char *auth_realm,
|
||
|
+ char **username, char **password);
|
||
|
+ int (*ssl_cert_request) (E2kCreds *creds,
|
||
|
+ const gnutls_datum_t *req_ca_rdn_der,
|
||
|
+ int nreqs,
|
||
|
+ gnutls_datum_t **cert_der_ret,
|
||
|
+ int *cert_der_ret_length);
|
||
|
+ int (*ssl_cert_sign) (E2kCreds *creds,
|
||
|
+ const gnutls_datum_t *cert,
|
||
|
+ const gnutls_datum_t *hash_data,
|
||
|
+ gnutls_datum_t *sig_data);
|
||
|
+};
|
||
|
+
|
||
|
+void e2k_context_set_creds (E2kContext *ctx,
|
||
|
+ E2kCreds *creds);
|
||
|
+
|
||
|
gboolean e2k_context_fba (E2kContext *ctx,
|
||
|
SoupMessage *failed_msg);
|
||
|
|
||
|
Index: servers/exchange/lib/e2k-autoconfig.c
|
||
|
===================================================================
|
||
|
--- servers/exchange/lib/e2k-autoconfig.c (revision 7790)
|
||
|
+++ servers/exchange/lib/e2k-autoconfig.c (working copy)
|
||
|
@@ -337,6 +337,13 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+void
|
||
|
+e2k_autoconfig_set_creds (E2kAutoconfig *ac,
|
||
|
+ E2kCreds *creds)
|
||
|
+{
|
||
|
+ ac->creds = creds;
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* e2k_autoconfig_get_context:
|
||
|
* @ac: an autoconfig context
|
||
|
@@ -395,8 +402,12 @@
|
||
|
*result = E2K_AUTOCONFIG_FAILED;
|
||
|
return NULL;
|
||
|
}
|
||
|
- e2k_context_set_auth (ctx, ac->username, ac->nt_domain,
|
||
|
- ac->use_ntlm ? "NTLM" : "Basic", ac->password);
|
||
|
+ if (ac->creds) {
|
||
|
+ e2k_context_set_creds (ctx, ac->creds);
|
||
|
+ } else {
|
||
|
+ e2k_context_set_auth (ctx, ac->username, ac->nt_domain,
|
||
|
+ ac->use_ntlm ? "NTLM" : "Basic", ac->password);
|
||
|
+ }
|
||
|
|
||
|
msg = e2k_soup_message_new (ctx, ac->owa_uri, SOUP_METHOD_GET);
|
||
|
soup_message_add_header (msg->request_headers, "Accept-Language",
|
||
|
Index: servers/exchange/lib/e2k-autoconfig.h
|
||
|
===================================================================
|
||
|
--- servers/exchange/lib/e2k-autoconfig.h (revision 7790)
|
||
|
+++ servers/exchange/lib/e2k-autoconfig.h (working copy)
|
||
|
@@ -47,6 +47,7 @@
|
||
|
gboolean require_ntlm, use_ntlm;
|
||
|
gboolean saw_basic, saw_ntlm;
|
||
|
gboolean nt_domain_defaulted, gc_server_autodetected;
|
||
|
+ E2kCreds *creds;
|
||
|
} E2kAutoconfig;
|
||
|
|
||
|
E2kAutoconfig *e2k_autoconfig_new (const char *owa_uri,
|
||
|
@@ -64,7 +65,8 @@
|
||
|
const char *username);
|
||
|
void e2k_autoconfig_set_password (E2kAutoconfig *ac,
|
||
|
const char *password);
|
||
|
-
|
||
|
+void e2k_autoconfig_set_creds (E2kAutoconfig *ac,
|
||
|
+ E2kCreds *creds);
|
||
|
E2kContext *e2k_autoconfig_get_context (E2kAutoconfig *ac,
|
||
|
E2kOperation *op,
|
||
|
E2kAutoconfigResult *result);
|
||
|
Index: servers/exchange/lib/e2k-types.h
|
||
|
===================================================================
|
||
|
--- servers/exchange/lib/e2k-types.h (revision 7790)
|
||
|
+++ servers/exchange/lib/e2k-types.h (working copy)
|
||
|
@@ -14,6 +14,7 @@
|
||
|
typedef struct _E2kContext E2kContext;
|
||
|
typedef struct _E2kContextPrivate E2kContextPrivate;
|
||
|
typedef struct _E2kContextClass E2kContextClass;
|
||
|
+typedef struct _E2kCreds E2kCreds;
|
||
|
|
||
|
typedef struct _E2kGlobalCatalog E2kGlobalCatalog;
|
||
|
typedef struct _E2kGlobalCatalogPrivate E2kGlobalCatalogPrivate;
|
||
|
Index: addressbook/libebook/e-book.c
|
||
|
===================================================================
|
||
|
--- addressbook/libebook/e-book.c (revision 7790)
|
||
|
+++ addressbook/libebook/e-book.c (working copy)
|
||
|
@@ -17,6 +17,10 @@
|
||
|
#include <glib/gi18n-lib.h>
|
||
|
#include <libedataserver/e-component-listener.h>
|
||
|
|
||
|
+#ifdef HAVE_GNOME_CERTAUTH
|
||
|
+#include <gnome-certauth/gca-nss-certificate-source.h>
|
||
|
+#endif
|
||
|
+
|
||
|
#include "e-book-listener.h"
|
||
|
|
||
|
#define d(x)
|
||
|
@@ -3277,6 +3281,9 @@
|
||
|
GError **error)
|
||
|
{
|
||
|
GNOME_Evolution_Addressbook_Book corba_book = CORBA_OBJECT_NIL;
|
||
|
+#ifdef HAVE_GNOME_CERTAUTH
|
||
|
+ GObject *nss_source;
|
||
|
+#endif
|
||
|
gchar *uri;
|
||
|
gchar *source_xml;
|
||
|
GList *factories;
|
||
|
@@ -3293,6 +3300,7 @@
|
||
|
/* try to find a list of factories that can handle the protocol */
|
||
|
factories = activate_factories_for_uri (book, uri);
|
||
|
if (!factories) {
|
||
|
+ g_free (uri);
|
||
|
g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED,
|
||
|
_("%s: no factories available for URI `%s'"), "e_book_load_uri", uri);
|
||
|
return FALSE;
|
||
|
@@ -3304,11 +3312,28 @@
|
||
|
*/
|
||
|
book->priv->listener = e_book_listener_new ();
|
||
|
if (book->priv->listener == NULL) {
|
||
|
+ g_free (uri);
|
||
|
g_warning ("e_book_load_uri: Could not create EBookListener!\n");
|
||
|
g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR,
|
||
|
_("%s: Could not create EBookListener"), "e_book_load_uri");
|
||
|
return FALSE;
|
||
|
}
|
||
|
+#ifdef HAVE_GNOME_CERTAUTH
|
||
|
+ nss_source = g_object_new (GCA_TYPE_NSS_CERTIFICATE_SOURCE,
|
||
|
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST),
|
||
|
+ NULL);
|
||
|
+ if (!nss_source) {
|
||
|
+ g_object_unref (book->priv->listener);
|
||
|
+ book->priv->listener = NULL;
|
||
|
+ g_free (uri);
|
||
|
+ g_warning ("e_book_load_uri: Could not create GcaNssCertificateSource!\n");
|
||
|
+ g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR,
|
||
|
+ _("%s: Could not create GcaNssCertificateSource"), "e_book_load_uri");
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+ bonobo_object_add_interface (BONOBO_OBJECT (book->priv->listener),
|
||
|
+ BONOBO_OBJECT (nss_source));
|
||
|
+#endif
|
||
|
book->priv->listener_signal = g_signal_connect_object (book->priv->listener, "response",
|
||
|
G_CALLBACK (e_book_handle_response),
|
||
|
book, 0);
|
||
|
Index: addressbook/libedata-book/e-book-backend.c
|
||
|
===================================================================
|
||
|
--- addressbook/libedata-book/e-book-backend.c (revision 7790)
|
||
|
+++ addressbook/libedata-book/e-book-backend.c (working copy)
|
||
|
@@ -27,6 +27,8 @@
|
||
|
/* Signal IDs */
|
||
|
enum {
|
||
|
LAST_CLIENT_GONE,
|
||
|
+ ADD_CLIENT,
|
||
|
+ REMOVE_CLIENT,
|
||
|
LAST_SIGNAL
|
||
|
};
|
||
|
|
||
|
@@ -570,6 +572,8 @@
|
||
|
backend->priv->clients = g_list_prepend (backend->priv->clients, book);
|
||
|
g_mutex_unlock (backend->priv->clients_mutex);
|
||
|
|
||
|
+ g_signal_emit (backend, e_book_backend_signals[ADD_CLIENT], 0, book);
|
||
|
+
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
@@ -592,6 +596,8 @@
|
||
|
lock) */
|
||
|
g_object_ref (backend);
|
||
|
|
||
|
+ g_signal_emit (backend, e_book_backend_signals[REMOVE_CLIENT], 0, book);
|
||
|
+
|
||
|
/* Disconnect */
|
||
|
g_mutex_lock (backend->priv->clients_mutex);
|
||
|
backend->priv->clients = g_list_remove (backend->priv->clients, book);
|
||
|
@@ -1085,6 +1091,24 @@
|
||
|
NULL, NULL,
|
||
|
g_cclosure_marshal_VOID__VOID,
|
||
|
G_TYPE_NONE, 0);
|
||
|
+
|
||
|
+ e_book_backend_signals[ADD_CLIENT] =
|
||
|
+ g_signal_new ("add_client",
|
||
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
||
|
+ G_SIGNAL_RUN_FIRST,
|
||
|
+ G_STRUCT_OFFSET (EBookBackendClass, add_client),
|
||
|
+ NULL, NULL,
|
||
|
+ g_cclosure_marshal_VOID__POINTER,
|
||
|
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||
|
+
|
||
|
+ e_book_backend_signals[REMOVE_CLIENT] =
|
||
|
+ g_signal_new ("remove_client",
|
||
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
||
|
+ G_SIGNAL_RUN_FIRST,
|
||
|
+ G_STRUCT_OFFSET (EBookBackendClass, remove_client),
|
||
|
+ NULL, NULL,
|
||
|
+ g_cclosure_marshal_VOID__POINTER,
|
||
|
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Index: addressbook/libedata-book/e-book-backend.h
|
||
|
===================================================================
|
||
|
--- addressbook/libedata-book/e-book-backend.h (revision 7790)
|
||
|
+++ addressbook/libedata-book/e-book-backend.h (working copy)
|
||
|
@@ -73,9 +73,10 @@
|
||
|
|
||
|
void (*sync) (EBookBackend *backend);
|
||
|
|
||
|
+ void (*add_client) (EBookBackend *backend, EDataBook *book);
|
||
|
+ void (*remove_client) (EBookBackend *backend, EDataBook *book);
|
||
|
+
|
||
|
/* Padding for future expansion */
|
||
|
- void (*_pas_reserved1) (void);
|
||
|
- void (*_pas_reserved2) (void);
|
||
|
void (*_pas_reserved3) (void);
|
||
|
void (*_pas_reserved4) (void);
|
||
|
};
|
||
|
Index: calendar/libedata-cal/e-cal-backend.c
|
||
|
===================================================================
|
||
|
--- calendar/libedata-cal/e-cal-backend.c (revision 7790)
|
||
|
+++ calendar/libedata-cal/e-cal-backend.c (working copy)
|
||
|
@@ -66,6 +66,8 @@
|
||
|
LAST_CLIENT_GONE,
|
||
|
OPENED,
|
||
|
REMOVED,
|
||
|
+ ADD_CLIENT,
|
||
|
+ REMOVE_CLIENT,
|
||
|
LAST_SIGNAL
|
||
|
};
|
||
|
static guint e_cal_backend_signals[LAST_SIGNAL];
|
||
|
@@ -237,6 +239,22 @@
|
||
|
G_TYPE_NONE, 1,
|
||
|
G_TYPE_INT);
|
||
|
|
||
|
+ e_cal_backend_signals[ADD_CLIENT] =
|
||
|
+ g_signal_new ("add_client",
|
||
|
+ G_TYPE_FROM_CLASS (class),
|
||
|
+ G_SIGNAL_RUN_FIRST,
|
||
|
+ 0, NULL, NULL,
|
||
|
+ g_cclosure_marshal_VOID__POINTER,
|
||
|
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||
|
+
|
||
|
+ e_cal_backend_signals[ADD_CLIENT] =
|
||
|
+ g_signal_new ("remove_client",
|
||
|
+ G_TYPE_FROM_CLASS (class),
|
||
|
+ G_SIGNAL_RUN_FIRST,
|
||
|
+ 0, NULL, NULL,
|
||
|
+ g_cclosure_marshal_VOID__POINTER,
|
||
|
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||
|
+
|
||
|
class->last_client_gone = NULL;
|
||
|
class->opened = NULL;
|
||
|
class->obj_updated = NULL;
|
||
|
@@ -422,6 +440,8 @@
|
||
|
g_mutex_lock (priv->clients_mutex);
|
||
|
priv->clients = g_list_append (priv->clients, cal);
|
||
|
g_mutex_unlock (priv->clients_mutex);
|
||
|
+
|
||
|
+ g_signal_emit (backend, e_cal_backend_signals[ADD_CLIENT], 0, cal);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
@@ -446,6 +466,8 @@
|
||
|
|
||
|
priv = backend->priv;
|
||
|
|
||
|
+ g_signal_emit (backend, e_cal_backend_signals[REMOVE_CLIENT], 0, cal);
|
||
|
+
|
||
|
/* Disconnect */
|
||
|
g_mutex_lock (priv->clients_mutex);
|
||
|
priv->clients = g_list_remove (priv->clients, cal);
|
||
|
Index: calendar/libecal/e-cal.c
|
||
|
===================================================================
|
||
|
--- calendar/libecal/e-cal.c (revision 7790)
|
||
|
+++ calendar/libecal/e-cal.c (working copy)
|
||
|
@@ -41,6 +41,9 @@
|
||
|
#include "e-cal-view-private.h"
|
||
|
#include "e-cal.h"
|
||
|
|
||
|
+#ifdef HAVE_GNOME_CERTAUTH
|
||
|
+#include <gnome-certauth/gca-nss-certificate-source.h>
|
||
|
+#endif
|
||
|
|
||
|
static gboolean
|
||
|
open_calendar (ECal *ecal, gboolean only_if_exists, GError **error, ECalendarStatus *status, gboolean needs_auth);
|
||
|
@@ -987,19 +991,19 @@
|
||
|
g_mutex_unlock (op->mutex);
|
||
|
}
|
||
|
|
||
|
-static gboolean
|
||
|
+static gpointer
|
||
|
reopen_with_auth (gpointer data)
|
||
|
{
|
||
|
ECalendarStatus status;
|
||
|
|
||
|
open_calendar (E_CAL (data), TRUE, NULL, &status, TRUE);
|
||
|
- return FALSE;
|
||
|
+ return NULL;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
auth_required_cb (ECalListener *listener, gpointer data)
|
||
|
{
|
||
|
- g_idle_add (reopen_with_auth, data);
|
||
|
+ g_thread_create (reopen_with_auth, data, FALSE, NULL);
|
||
|
|
||
|
}
|
||
|
|
||
|
@@ -1141,7 +1145,9 @@
|
||
|
e_cal_init (ECal *ecal, ECalClass *klass)
|
||
|
{
|
||
|
ECalPrivate *priv;
|
||
|
-
|
||
|
+#ifdef HAVE_GNOME_CERTAUTH
|
||
|
+ GObject *nss_source;
|
||
|
+#endif
|
||
|
priv = g_new0 (ECalPrivate, 1);
|
||
|
ecal->priv = priv;
|
||
|
|
||
|
@@ -1151,6 +1157,18 @@
|
||
|
priv->mutex = g_mutex_new ();
|
||
|
priv->listener = e_cal_listener_new (cal_set_mode_cb, ecal);
|
||
|
|
||
|
+#ifdef HAVE_GNOME_CERTAUTH
|
||
|
+ nss_source = g_object_new (GCA_TYPE_NSS_CERTIFICATE_SOURCE,
|
||
|
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST),
|
||
|
+ NULL);
|
||
|
+ if (!nss_source) {
|
||
|
+ g_warning ("e_cal_init: Could not create GcaNssCertificateSource!\n");
|
||
|
+ } else {
|
||
|
+ bonobo_object_add_interface (BONOBO_OBJECT (priv->listener),
|
||
|
+ BONOBO_OBJECT (nss_source));
|
||
|
+ }
|
||
|
+#endif
|
||
|
+
|
||
|
priv->cal_address = NULL;
|
||
|
priv->alarm_email_address = NULL;
|
||
|
priv->ldap_attribute = NULL;
|
||
|
@@ -1730,7 +1748,7 @@
|
||
|
g_mutex_unlock (priv->mutex);
|
||
|
|
||
|
/* see if the backend needs authentication */
|
||
|
- if ( (priv->mode != CAL_MODE_LOCAL) && e_source_get_property (priv->source, "auth")) {
|
||
|
+ if ( needs_auth && (priv->mode != CAL_MODE_LOCAL) && e_source_get_property (priv->source, "auth")) {
|
||
|
char *prompt, *key;
|
||
|
const char *parent_user;
|
||
|
|
||
|
--- servers/exchange/lib/e2k-context.c~ 2007-07-31 16:29:07.000000000 -0400
|
||
|
+++ servers/exchange/lib/e2k-context.c 2007-07-31 16:33:45.000000000 -0400
|
||
|
@@ -154,9 +154,7 @@
|
||
|
{
|
||
|
SoupUri *proxy_uri = NULL;
|
||
|
E2kContext* ctx = (E2kContext *)user_data;
|
||
|
- if (!ctx || !ctx->priv ||
|
||
|
- (!ctx->priv->session && !ctx->priv->async_session) ||
|
||
|
- (!ctx->priv->owa_uri))
|
||
|
+ if (!ctx || !ctx->priv || !ctx->priv->session || !ctx->priv->owa_uri)
|
||
|
return;
|
||
|
|
||
|
if (!e_proxy_require_proxy_for_uri (proxy, ctx->priv->owa_uri))
|
||
|
@@ -167,9 +165,6 @@
|
||
|
if (ctx->priv->session)
|
||
|
g_object_set (ctx->priv->session, SOUP_SESSION_PROXY_URI,
|
||
|
proxy_uri, NULL);
|
||
|
- if (ctx->priv->async_session)
|
||
|
- g_object_set (ctx->priv->async_session, SOUP_SESSION_PROXY_URI,
|
||
|
- proxy_uri, NULL);
|
||
|
}
|
||
|
|
||
|
static void
|