Skip to content
Commits on Source (10)
......@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.1)
cmake_policy(VERSION 3.1)
project(evolution-data-server
VERSION 3.46.2
VERSION 3.46.3
LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 14)
set(PROJECT_BUGREPORT "https://gitlab.gnome.org/GNOME/evolution-data-server/issues/")
......
Evolution-Data-Server 3.46.3 2023-01-06
---------------------------------------
Bug Fixes:
I#442 - e_util_change_uri_component: Reset default port when changing scheme
ews-I#208 - Prompting for password too often
Miscellaneous:
Fix a crash under source_registry_object_added_no_owner()
ESoupAuthBearer: Add debug prints
Translations:
Danial Behzadi (fa)
Nart Tlisha (ab)
Evolution-Data-Server 3.46.2 2022-12-02
---------------------------------------
......
......@@ -1469,127 +1469,127 @@ msgstr ""
#: src/calendar/libecal/e-cal-recur.c:4892
msgid "1st"
msgstr ""
msgstr "1-тәи"
#: src/calendar/libecal/e-cal-recur.c:4893
msgid "2nd"
msgstr ""
msgstr "2-тәи"
#: src/calendar/libecal/e-cal-recur.c:4894
msgid "3rd"
msgstr ""
msgstr "3-тәи"
#: src/calendar/libecal/e-cal-recur.c:4895
msgid "4th"
msgstr ""
msgstr "4-тәи"
#: src/calendar/libecal/e-cal-recur.c:4896
msgid "5th"
msgstr ""
msgstr "5-тәи"
#: src/calendar/libecal/e-cal-recur.c:4897
msgid "6th"
msgstr ""
msgstr "6-тәи"
#: src/calendar/libecal/e-cal-recur.c:4898
msgid "7th"
msgstr ""
msgstr "7-тәи"
#: src/calendar/libecal/e-cal-recur.c:4899
msgid "8th"
msgstr ""
msgstr "8-тәи"
#: src/calendar/libecal/e-cal-recur.c:4900
msgid "9th"
msgstr ""
msgstr "9-тәи"
#: src/calendar/libecal/e-cal-recur.c:4901
msgid "10th"
msgstr ""
msgstr "10-тәи"
#: src/calendar/libecal/e-cal-recur.c:4902
msgid "11th"
msgstr ""
msgstr "11-тәи"
#: src/calendar/libecal/e-cal-recur.c:4903
msgid "12th"
msgstr ""
msgstr "12-тәи"
#: src/calendar/libecal/e-cal-recur.c:4904
msgid "13th"
msgstr ""
msgstr "13-тәи"
#: src/calendar/libecal/e-cal-recur.c:4905
msgid "14th"
msgstr ""
msgstr "14-тәи"
#: src/calendar/libecal/e-cal-recur.c:4906
msgid "15th"
msgstr ""
msgstr "15-тәи"
#: src/calendar/libecal/e-cal-recur.c:4907
msgid "16th"
msgstr ""
msgstr "16-тәи"
#: src/calendar/libecal/e-cal-recur.c:4908
msgid "17th"
msgstr ""
msgstr "17-тәи"
#: src/calendar/libecal/e-cal-recur.c:4909
msgid "18th"
msgstr ""
msgstr "18-тәи"
#: src/calendar/libecal/e-cal-recur.c:4910
msgid "19th"
msgstr ""
msgstr "19-тәи"
#: src/calendar/libecal/e-cal-recur.c:4911
msgid "20th"
msgstr ""
msgstr "20-тәи"
#: src/calendar/libecal/e-cal-recur.c:4912
msgid "21st"
msgstr ""
msgstr "21-тәи"
#: src/calendar/libecal/e-cal-recur.c:4913
msgid "22nd"
msgstr ""
msgstr "22-тәи"
#: src/calendar/libecal/e-cal-recur.c:4914
msgid "23rd"
msgstr ""
msgstr "23-тәи"
#: src/calendar/libecal/e-cal-recur.c:4915
msgid "24th"
msgstr ""
msgstr "24-тәи"
#: src/calendar/libecal/e-cal-recur.c:4916
msgid "25th"
msgstr ""
msgstr "25-тәи"
#: src/calendar/libecal/e-cal-recur.c:4917
msgid "26th"
msgstr ""
msgstr "26-тәи"
#: src/calendar/libecal/e-cal-recur.c:4918
msgid "27th"
msgstr ""
msgstr "27-тәи"
#: src/calendar/libecal/e-cal-recur.c:4919
msgid "28th"
msgstr ""
msgstr "28-тәи"
#: src/calendar/libecal/e-cal-recur.c:4920
msgid "29th"
msgstr ""
msgstr "29-тәи"
#: src/calendar/libecal/e-cal-recur.c:4921
msgid "30th"
msgstr ""
msgstr "30-тәи"
#: src/calendar/libecal/e-cal-recur.c:4922
msgid "31st"
msgstr ""
msgstr "31-тәи"
#: src/calendar/libecal/e-cal-recur.c:5072
#, c-format
......@@ -2356,7 +2356,7 @@ msgstr[1] ""
#: src/calendar/libecal/e-reminder-watcher.c:2902
msgid "No Summary"
msgstr ""
msgstr "Аизак ыҟаӡам"
#. Translators: The first %s is replaced with the time string,
#. the second %s with a duration, and the third %s with an event location,
......@@ -4591,7 +4591,7 @@ msgstr ""
#: src/camel/providers/local/camel-local-folder.c:214
#, c-format
msgid "%s (%s)"
msgstr ""
msgstr "%s (%s)"
#: src/camel/providers/local/camel-local-folder.c:505
msgid "_Index message body data"
......@@ -5316,7 +5316,7 @@ msgstr ""
#: src/camel/providers/pop3/camel-pop3-folder.c:573
msgid "Unknown reason"
msgstr ""
msgstr "Еилкаам амзыз"
#: src/camel/providers/pop3/camel-pop3-folder.c:642
msgid "Retrieving POP summary"
......@@ -6658,7 +6658,7 @@ msgstr ""
#: src/libedataserver/e-time-utils.c:1691
#: src/libedataserver/e-time-utils.c:1990
msgid "%a %m/%d/%Y %I:%M:%S %p"
msgstr ""
msgstr "%a, %d.%m.%Y %I:%M:%S %p"
#. strptime format of a weekday, a date and a time,
#. * in 24-hour format.
......@@ -6667,7 +6667,7 @@ msgstr ""
#: src/libedataserver/e-time-utils.c:1696
#: src/libedataserver/e-time-utils.c:1981
msgid "%a %m/%d/%Y %H:%M:%S"
msgstr ""
msgstr "%a, %d.%m.%Y %H:%M:%S"
#. strptime format of a weekday, a date and a time,
#. * in 12-hour format, without seconds.
......@@ -6753,14 +6753,14 @@ msgstr ""
#: src/libedataserver/e-time-utils.c:1913
#: src/libedataserver/e-time-utils.c:2034
msgid "%I:%M:%S %p"
msgstr ""
msgstr "%I∶%M∶%S %p"
#. strptime format for a time of day, in 24-hour format.
#. strftime format of a time in 24-hour format.
#: src/libedataserver/e-time-utils.c:1917
#: src/libedataserver/e-time-utils.c:2026
msgid "%H:%M:%S"
msgstr ""
msgstr "%H:%M:%S"
#. strptime format for time of day, without seconds,
#. * in 12-hour format.
......@@ -6777,7 +6777,7 @@ msgstr ""
#: src/libedataserver/e-time-utils.c:1926
#: src/libedataserver/e-time-utils.c:2023
msgid "%H:%M"
msgstr ""
msgstr "%H:%M"
#. strptime format for time of day, without seconds 24-hour format,
#. * and no colon.
......@@ -7935,7 +7935,7 @@ msgstr ""
#: src/services/evolution-source-registry/builtin/contacts-stub.source.desktop.in:4
msgid "Contacts"
msgstr ""
msgstr "Аимадарақәа"
#: src/services/evolution-source-registry/builtin/google-stub.source.desktop.in:4
msgid "Google"
......
This diff is collapsed.
......@@ -2999,7 +2999,20 @@ e_util_change_uri_component (GUri **inout_uri,
g_return_if_fail (component != SOUP_URI_PORT);
g_return_if_fail (component != SOUP_URI_NONE);
tmp = soup_uri_copy (*inout_uri, component, value, SOUP_URI_NONE);
/* Make sure the default port is not "inherited" when changing scheme */
if (component == SOUP_URI_SCHEME && value && (
g_uri_get_port (*inout_uri) == 80 ||
g_uri_get_port (*inout_uri) == 443) && (
g_ascii_strcasecmp (value, "http") == 0 ||
g_ascii_strcasecmp (value, "https") == 0)) {
tmp = soup_uri_copy (*inout_uri,
component, value,
SOUP_URI_PORT, g_ascii_strcasecmp (value, "http") == 0 ? 80 : 443,
SOUP_URI_NONE);
} else {
tmp = soup_uri_copy (*inout_uri, component, value, SOUP_URI_NONE);
}
g_uri_unref (*inout_uri);
*inout_uri = tmp;
}
......
......@@ -42,6 +42,10 @@
#include "e-oauth2-service.h"
/* How many seconds earlier than reported by the server is the token considered expired
and will be refreshed. */
#define TOKEN_VALIDITY_GAP_SECS 10
G_DEFINE_INTERFACE (EOAuth2Service, e_oauth2_service, G_TYPE_OBJECT)
static gboolean
......@@ -1705,7 +1709,9 @@ e_oauth2_service_get_access_token_sync (EOAuth2Service *service,
G_LOCK (access_token_requests);
resp = eos_wait_for_access_token_request_locked (source, out_access_token, out_expires_in, cancellable, error);
if (resp != RESPONSE_UNKNOWN) {
if (resp != RESPONSE_UNKNOWN && resp != RESPONSE_FAILURE && *out_expires_in <= TOKEN_VALIDITY_GAP_SECS) {
*out_expires_in = 0;
} else if (resp != RESPONSE_UNKNOWN) {
G_UNLOCK (access_token_requests);
return resp != RESPONSE_FAILURE;
......@@ -1723,7 +1729,7 @@ e_oauth2_service_get_access_token_sync (EOAuth2Service *service,
return FALSE;
}
if (local_expires_in <= 0 && refresh_token) {
if (local_expires_in <= TOKEN_VALIDITY_GAP_SECS && refresh_token) {
success = e_oauth2_service_refresh_and_store_token_sync (service, source, refresh_token,
ref_source, ref_source_user_data, cancellable, &local_error);
......
......@@ -32,6 +32,8 @@
#include "evolution-data-server-config.h"
#include "e-data-server-util.h"
#include "e-time-utils.h"
#include "e-soup-auth-bearer.h"
#include <time.h>
......@@ -40,6 +42,9 @@
#define EXPIRY_INVALID ((time_t) -1)
/* How many seconds earlier than reported by the server is the token considered expired. */
#define TOKEN_VALIDITY_GAP_SECS 5
struct _ESoupAuthBearerPrivate {
GMutex property_lock;
gchar *access_token;
......@@ -51,6 +56,35 @@ G_DEFINE_TYPE_WITH_PRIVATE (
e_soup_auth_bearer,
SOUP_TYPE_AUTH)
static gboolean
e_soup_auth_bearer_debug_enabled (void)
{
static gint oauth2_debug = -1;
if (oauth2_debug == -1)
oauth2_debug = g_strcmp0 (g_getenv ("OAUTH2_DEBUG"), "1") == 0 ? 1 : 0;
return oauth2_debug != 0;
}
static void
e_soup_auth_bearer_debug_print (const gchar *format,
...) G_GNUC_PRINTF (1, 2);
static void
e_soup_auth_bearer_debug_print (const gchar *format,
...)
{
va_list args;
if (!e_soup_auth_bearer_debug_enabled ())
return;
va_start (args, format);
e_util_debug_printv ("BEARER", format, args);
va_end (args);
}
static gboolean
e_soup_auth_bearer_is_expired_locked (ESoupAuthBearer *bearer)
{
......@@ -81,21 +115,38 @@ e_soup_auth_bearer_update (SoupAuth *auth,
SoupMessage *message,
GHashTable *auth_header)
{
if (message && soup_message_get_status (message) == SOUP_STATUS_UNAUTHORIZED) {
ESoupAuthBearer *bearer;
ESoupAuthBearer *bearer;
g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (auth), FALSE);
g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (auth), FALSE);
bearer = E_SOUP_AUTH_BEARER (auth);
bearer = E_SOUP_AUTH_BEARER (auth);
if (message && soup_message_get_status (message) == SOUP_STATUS_UNAUTHORIZED) {
g_mutex_lock (&bearer->priv->property_lock);
/* Expire the token, it's likely to be invalid. */
bearer->priv->expiry = EXPIRY_INVALID;
e_soup_auth_bearer_debug_print ("%s: bearer:%p message:%p token:%p did set it as expired\n", G_STRFUNC, bearer, message, bearer->priv->access_token);
g_mutex_unlock (&bearer->priv->property_lock);
return FALSE;
} else if (message) {
g_mutex_lock (&bearer->priv->property_lock);
e_soup_auth_bearer_debug_print ("%s: bearer:%p message:%p message status is not UNAUTHORIZED, but %u; token:%p expired:%d\n",
G_STRFUNC, bearer, message, soup_message_get_status (message),
bearer->priv->access_token, e_soup_auth_bearer_is_expired_locked (bearer));
g_mutex_unlock (&bearer->priv->property_lock);
} else {
g_mutex_lock (&bearer->priv->property_lock);
e_soup_auth_bearer_debug_print ("%s: bearer:%p no message; token:%p expired:%d\n",
G_STRFUNC, bearer, bearer->priv->access_token, e_soup_auth_bearer_is_expired_locked (bearer));
g_mutex_unlock (&bearer->priv->property_lock);
}
return TRUE;
......@@ -123,6 +174,10 @@ e_soup_auth_bearer_is_authenticated (SoupAuth *auth)
authenticated = (bearer->priv->access_token != NULL) &&
!e_soup_auth_bearer_is_expired_locked (bearer);
e_soup_auth_bearer_debug_print ("%s: bearer:%p token:%p expired:%d authenticated:%d\n",
G_STRFUNC, bearer, bearer->priv->access_token,
e_soup_auth_bearer_is_expired_locked (bearer), authenticated);
g_mutex_unlock (&bearer->priv->property_lock);
return authenticated;
......@@ -141,6 +196,10 @@ e_soup_auth_bearer_get_authorization (SoupAuth *auth,
res = g_strdup_printf ("Bearer %s", bearer->priv->access_token);
e_soup_auth_bearer_debug_print ("%s: bearer:%p message:%p; status:%u token:%p expired:%d\n",
G_STRFUNC, bearer, message, soup_message_get_status (message),
bearer->priv->access_token, e_soup_auth_bearer_is_expired_locked (bearer));
g_mutex_unlock (&bearer->priv->property_lock);
return res;
......@@ -158,6 +217,8 @@ e_soup_auth_bearer_authenticate (SoupAuth *auth,
const gchar *password)
{
/* Not applicable here */
e_soup_auth_bearer_debug_print ("%s: bearer:%p tried to authenticate with username:'%s' password:%p\n",
G_STRFUNC, auth, username, password);
}
static void
......@@ -230,10 +291,26 @@ e_soup_auth_bearer_set_access_token (ESoupAuthBearer *bearer,
}
if (expires_in_seconds > 0)
bearer->priv->expiry = time (NULL) + expires_in_seconds - 5;
bearer->priv->expiry = time (NULL) + expires_in_seconds - TOKEN_VALIDITY_GAP_SECS;
else
bearer->priv->expiry = EXPIRY_INVALID;
if (e_soup_auth_bearer_debug_enabled ()) {
gchar time_str[128];
if (bearer->priv->expiry != EXPIRY_INVALID) {
time_t tt = (time_t) bearer->priv->expiry;
e_time_format_time (localtime (&tt), TRUE, TRUE, time_str, sizeof (time_str));
} else {
time_str[0] = '-';
time_str[1] = '1';
time_str[2] = '\0';
}
e_soup_auth_bearer_debug_print ("%s: bearer:%p token:%p changed:%d expires in %d seconds, at %s\n",
G_STRFUNC, bearer, bearer->priv->access_token, changed, expires_in_seconds, time_str);
}
g_mutex_unlock (&bearer->priv->property_lock);
if (changed) {
......
......@@ -1264,6 +1264,8 @@ typedef struct _AsyncSendData {
gulong restarted_id;
gchar *certificate_pem;
GTlsCertificateFlags certificate_errors;
gint io_priority;
gboolean caught_bearer_expired;
} AsyncSendData;
static void
......@@ -1395,6 +1397,7 @@ e_soup_session_send_message_ready_cb (GObject *source_object,
SoupMessage *message;
GInputStream *input_stream;
GError *local_error = NULL;
gboolean caught_bearer_expired = FALSE;
g_return_if_fail (asd != NULL);
......@@ -1426,14 +1429,36 @@ e_soup_session_send_message_ready_cb (GObject *source_object,
g_rec_mutex_unlock (&esession->priv->session_lock);
if (local_error) {
g_task_return_error (asd->task, local_error);
if (message && soup_message_get_status (message) == SOUP_STATUS_UNAUTHORIZED && !asd->caught_bearer_expired) {
g_mutex_lock (&esession->priv->property_lock);
if (esession->priv->using_bearer_auth && e_soup_auth_bearer_is_expired (esession->priv->using_bearer_auth)) {
g_signal_emit_by_name (message, "restarted");
asd->caught_bearer_expired = TRUE;
caught_bearer_expired = TRUE;
}
g_mutex_unlock (&esession->priv->property_lock);
}
if (caught_bearer_expired) {
g_clear_error (&local_error);
g_clear_object (&input_stream);
g_rec_mutex_lock (&esession->priv->session_lock);
soup_session_send_async (session, message, asd->io_priority, g_task_get_cancellable (asd->task),
e_soup_session_send_message_ready_cb, asd);
g_rec_mutex_unlock (&esession->priv->session_lock);
} else {
g_task_return_pointer (asd->task, input_stream, g_object_unref);
}
if (local_error) {
g_task_return_error (asd->task, local_error);
g_clear_object (&input_stream);
} else {
g_task_return_pointer (asd->task, input_stream, g_object_unref);
}
g_object_unref (asd->task);
g_object_unref (asd->task);
}
}
/**
......@@ -1475,6 +1500,8 @@ e_soup_session_send_message (ESoupSession *session,
asd->session = g_object_ref (session);
asd->task = g_task_new (session, cancellable, callback, user_data);
asd->caught_bearer_expired = FALSE;
asd->io_priority = io_priority;
g_task_set_source_tag (asd->task, e_soup_session_send_message);
g_task_set_task_data (asd->task, asd, async_send_data_free);
......@@ -1581,6 +1608,7 @@ e_soup_session_send_message_sync (ESoupSession *session,
{
GInputStream *input_stream;
gboolean redirected;
gboolean caught_bearer_expired = FALSE;
gint resend_count = 0;
gulong authenticate_id = 0;
gulong restarted_id = 0;
......@@ -1644,6 +1672,16 @@ e_soup_session_send_message_sync (ESoupSession *session,
}
}
}
} else if (soup_message_get_status (message) == SOUP_STATUS_UNAUTHORIZED && !caught_bearer_expired) {
g_mutex_lock (&session->priv->property_lock);
if (session->priv->using_bearer_auth && e_soup_auth_bearer_is_expired (session->priv->using_bearer_auth)) {
g_signal_emit_by_name (message, "restarted");
resend_count++;
redirected = TRUE;
caught_bearer_expired = TRUE;
g_clear_error (&local_error);
}
g_mutex_unlock (&session->priv->property_lock);
}
}
......
......@@ -304,10 +304,15 @@ source_registry_dbus_object_dup_uid (GDBusObject *dbus_object)
EDBusObject *e_dbus_object;
EDBusSource *e_dbus_source;
/* EDBusSource interface should always be present. */
if (!E_DBUS_IS_OBJECT (dbus_object))
return NULL;
e_dbus_object = E_DBUS_OBJECT (dbus_object);
e_dbus_source = e_dbus_object_peek_source (e_dbus_object);
if (!E_DBUS_IS_SOURCE (e_dbus_source))
return NULL;
return e_dbus_source_dup_uid (e_dbus_source);
}
......@@ -840,6 +845,9 @@ source_registry_object_added_no_owner (ESourceRegistry *registry,
uid = source_registry_dbus_object_dup_uid (dbus_object);
if (!uid)
return;
if (source_registry_service_restart_table_remove (registry, uid))
source = e_source_registry_ref_source (registry, uid);
......@@ -956,7 +964,8 @@ source_registry_object_removed_no_owner (ESourceRegistry *registry,
gchar *uid;
uid = source_registry_dbus_object_dup_uid (dbus_object);
source_registry_service_restart_table_add (registry, uid);
if (uid)
source_registry_service_restart_table_add (registry, uid);
g_free (uid);
}
}
......