diff --git a/debian/changelog b/debian/changelog index 678df201..db1fa272 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +syncevolution (1.5.2-3) unstable; urgency=medium + + [ Patrick Ohly ] + * libical: support libical v3 (Closes: #884158) + * GNOME: replace gnome-keyring with libsecret + + [ Tino Mettler ] + * Change build dependencies for libgtk and glade to use GTK3 for sync-ui + (Closes: #884162) + * Add Build-Dep on libjson-c-dev (Closes: #884170) + * Handle C++ conversion operator name mangling in GCC 7 (Closes: #871284) + * Build depend on libsecret-1-dev instead of deprecated libgnome-keyring-dev + (Closes: #867944) + + -- Tino Mettler Thu, 04 Jan 2018 12:24:58 +0100 + syncevolution (1.5.2-2) unstable; urgency=medium * Add missing service file for syncevo-dbus-server (Closes: #854941) diff --git a/debian/control b/debian/control index 9d8c0bdd..dfc914fa 100644 --- a/debian/control +++ b/debian/control @@ -6,11 +6,15 @@ Build-Depends: debhelper (>= 9), autotools-dev, libedataserver1.2-dev, libecal1.2-dev, libebook1.2-dev, libcurl4-gnutls-dev, libboost-dev, libsynthesis-dev (>=3.4.0.47.5), libtool, automake, intltool, pkg-config, - libglib2.0-dev, libglade2-dev, libdbus-glib-1-dev, libgtk2.0-dev, - libgconf2-dev, libgnome-keyring-dev, xsltproc, + libglib2.0-dev, libgladeui-dev, libdbus-glib-1-dev, libgtk-3-dev, + libgconf2-dev, + libsecret-1-dev, + xsltproc, libopenobex2-dev [linux-any], libnotify-dev, python-docutils, libical-dev, libneon27-gnutls-dev, libpcre3-dev, - libcppunit-dev, kdepimlibs5-dev, kdelibs5-dev + libcppunit-dev, kdepimlibs5-dev, kdelibs5-dev, + libjson-c-dev, + g++ (>= 4:7) Standards-Version: 3.9.8 Homepage: http://www.syncevolution.org Vcs-Git: git://anonscm.debian.org/collab-maint/syncevolution diff --git a/debian/patches/0002-libical-support-libical-v3.patch b/debian/patches/0002-libical-support-libical-v3.patch new file mode 100644 index 00000000..8e7de5a9 --- /dev/null +++ b/debian/patches/0002-libical-support-libical-v3.patch @@ -0,0 +1,89 @@ +From 110e57f32fcae67634f6d0edd626ccc64748047e Mon Sep 17 00:00:00 2001 +From: Patrick Ohly +Date: Thu, 14 Dec 2017 07:46:32 -0800 +Subject: [PATCH] libical: support libical v3 + +libical v3 removes some deprecated functions (like icaltime_from_timet) +and removes the "is_utc" member from icaltimetype. The replacement +code works with old and new libical and thus needs no ifdefs. + +However, that struct is part of the ABI, which impacts the tricks that +syncevolution.org binaries use to get built against libical v2 and then +run with more recent libs like libical v3. + +Depending on the platform ABI, it may still be okay, because the calling code +in SyncEvolution reserves and copies enough bytes for the icaltimetype +instances and because that code never directly accesses any member (is_date, +is_daylight, zone) whose offset changes. + +Original author: Milan Crha + +Slightly modified it so that icaltime_t.zone is not set. + +Signed-off-by: Patrick Ohly +--- + src/backends/webdav/CalDAVSource.cpp | 3 +-- + src/syncevo/icaltz-util.c | 10 +++++----- + 2 files changed, 6 insertions(+), 7 deletions(-) + +diff --git a/src/backends/webdav/CalDAVSource.cpp b/src/backends/webdav/CalDAVSource.cpp +index fa16935a..9c4a1c8d 100644 +--- a/src/backends/webdav/CalDAVSource.cpp ++++ b/src/backends/webdav/CalDAVSource.cpp +@@ -721,8 +721,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid + eptr fullcal = event.m_calendar; + loadItem(event); + event.m_sequence++; +- lastmodtime = icaltime_from_timet(event.m_lastmodtime, false); +- lastmodtime.is_utc = 1; ++ lastmodtime = icaltime_from_timet_with_zone(event.m_lastmodtime, false, icaltimezone_get_utc_timezone()); + event.m_calendar = fullcal; + for (icalcomponent *comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT); + comp; +diff --git a/src/syncevo/icaltz-util.c b/src/syncevo/icaltz-util.c +index 202a2cd9..abb9a758 100644 +--- a/src/syncevo/icaltz-util.c ++++ b/src/syncevo/icaltz-util.c +@@ -224,7 +224,7 @@ find_transidx (time_t *transitions, ttinfo *types, int *trans_idx, long int num_ + struct icaltimetype itime; + + now = time (NULL); +- itime = icaltime_from_timet (now, 0); ++ itime = icaltime_from_timet_with_zone (now, 0, NULL); + itime.month = itime.day = 1; + itime.hour = itime.minute = itime.second = 0; + year_start = icaltime_as_timet(itime); +@@ -304,13 +304,13 @@ adjust_dtstart_day_to_rrule (icalcomponent *comp, struct icalrecurrencetype rule + icalrecur_iterator *iter; + + now = time (NULL); +- itime = icaltime_from_timet (now, 0); ++ itime = icaltime_from_timet_with_zone (now, 0, NULL); + itime.month = itime.day = 1; + itime.hour = itime.minute = itime.second = 0; + year_start = icaltime_as_timet(itime); + + comp_start = icalcomponent_get_dtstart (comp); +- start = icaltime_from_timet (year_start, 0); ++ start = icaltime_from_timet_with_zone (year_start, 0, NULL); + + iter = icalrecur_iterator_new (rule, start); + iter_start = icalrecur_iterator_next (iter); +@@ -478,7 +478,7 @@ icaltzutil_fetch_timezone (const char *location) + trans = transitions [stdidx] + types [zp_idx].gmtoff; + else + trans = types [zp_idx].gmtoff; +- icaltime = icaltime_from_timet (trans, 0); ++ icaltime = icaltime_from_timet_with_zone (trans, 0, NULL); + dtstart = icaltime; + dtstart.year = 1970; + dtstart.minute = dtstart.second = 0; +@@ -520,7 +520,7 @@ icaltzutil_fetch_timezone (const char *location) + trans = transitions [dstidx] + types [zp_idx].gmtoff; + else + trans = types [zp_idx].gmtoff; +- icaltime = icaltime_from_timet (trans, 0); ++ icaltime = icaltime_from_timet_with_zone (trans, 0, NULL); + dtstart = icaltime; + dtstart.year = 1970; + dtstart.minute = dtstart.second = 0; diff --git a/debian/patches/0003-GNOME-replace-gnome-keyring-with-libsecret.patch b/debian/patches/0003-GNOME-replace-gnome-keyring-with-libsecret.patch new file mode 100644 index 00000000..b765bd89 --- /dev/null +++ b/debian/patches/0003-GNOME-replace-gnome-keyring-with-libsecret.patch @@ -0,0 +1,255 @@ +From e6dc389330b51c508d0fa25d8e9ad599756ec69b Mon Sep 17 00:00:00 2001 +From: Patrick Ohly +Date: Thu, 16 Nov 2017 15:01:11 +0100 +Subject: [PATCH] GNOME: replace gnome-keyring with libsecret + +The GNOME keyring library has been obsoleted for a long time now, +long enough that the replacement libsecret is available on all +supported distros. Therefore we can switch unconditionally. + +Signed-off-by: Patrick Ohly +--- + src/backends/gnome/GNOMEPlatform.cpp | 170 ++++++++++++++--------------------- + src/backends/gnome/configure-sub.in | 9 +- + 2 files changed, 73 insertions(+), 106 deletions(-) + +diff --git a/src/backends/gnome/GNOMEPlatform.cpp b/src/backends/gnome/GNOMEPlatform.cpp +index f2f7a1d3..37f9811a 100644 +--- a/src/backends/gnome/GNOMEPlatform.cpp ++++ b/src/backends/gnome/GNOMEPlatform.cpp +@@ -22,7 +22,7 @@ + #ifdef USE_GNOME_KEYRING + + extern "C" { +-#include ++#include + } + + #include "GNOMEPlatform.h" +@@ -30,46 +30,11 @@ extern "C" { + #include + #include + #include ++#include + + #include + SE_BEGIN_CXX + +-// Occasionally, libgnome-keyring fails with the following error messages: +-// Gkr: received an invalid, unencryptable, or non-utf8 secret +-// Gkr: call to daemon returned an invalid response: (null).(null) +-// +-// We work around that by retrying the operation a few times, for at +-// most this period of time. Didn't really help, so disable it for now +-// by using a zero duration. +-static const double GNOMEKeyringRetryDuration = 2; // seconds +-static const double GNOMEKeyringRetryInterval = 0.1; // seconds +- +-/** +- * libgnome-keyring has an internal gkr_reset_session() +- * method which gets called when the "org.freedesktop.secrets" +- * disconnects from the D-Bus session bus. +- * +- * We cannot call that method directly, but we can get it called by +- * faking the "disconnect" signal. That works because +- * on_connection_filter() in gkr-operation.c doesn't check who the +- * sender of the signal is. +- * +- * Once gkr_reset_session() got called, the next operation will +- * re-establish the connection. After the failure above, the second +- * attempt usually works. +- * +- * Any other client using libgnome-keyring will also be tricked into +- * disconnecting temporarily. That should be fine, any running +- * operation will continue to run and complete (?). +- */ +-static void FlushGNOMEKeyring() +-{ +- // Invoking dbus-send is easier than writing this in C++. +- // Besides, it ensures that the signal comes from some other +- // process. Not sure whether signals are sent back to the sender. +- system("dbus-send --session --type=signal /org/freedesktop/DBus org.freedesktop.DBus.NameOwnerChanged string:'org.freedesktop.secrets' string:':9.99' string:''"); +-} +- + /** + * GNOME keyring distinguishes between empty and unset + * password keys. This function returns NULL for an +@@ -97,6 +62,39 @@ static bool UseGNOMEKeyring(const InitStateTri &keyring) + return true; + } + ++class LibSecretHash : public GHashTableCXX ++{ ++ std::list m_buffer; ++ ++public: ++ LibSecretHash(const ConfigPasswordKey &key) : ++ GHashTableCXX(g_hash_table_new(g_str_hash, g_str_equal), TRANSFER_REF) ++ { ++ // see https://developer.gnome.org/libsecret/0.16/libsecret-SecretSchema.html#SECRET-SCHEMA-COMPAT-NETWORK:CAPS ++ insert("user", key.user); ++ insert("domain", key.domain); ++ insert("server", key.server); ++ insert("object", key.object); ++ insert("protocol", key.protocol); ++ insert("authtype", key.authtype); ++ if (key.port) { ++ std::string value = StringPrintf("%d", key.port); ++ insert("port", value); ++ } ++ } ++ ++ /** Keys are expected to be constants and not copied. Values are copied. */ ++ void insert(const char *key, const std::string &value) ++ { ++ if (!value.empty()) { ++ m_buffer.push_back(value); ++ g_hash_table_insert(get(), ++ const_cast(key), ++ const_cast(m_buffer.back().c_str())); ++ } ++ } ++}; ++ + bool GNOMELoadPasswordSlot(const InitStateTri &keyring, + const std::string &passwordName, + const std::string &descr, +@@ -108,46 +106,24 @@ bool GNOMELoadPasswordSlot(const InitStateTri &keyring, + return false; + } + +- GnomeKeyringResult result = GNOME_KEYRING_RESULT_OK; +- GList* list; +- Timespec start = Timespec::monotonic(); +- double sleepSecs = 0; +- do { +- if (sleepSecs != 0) { +- SE_LOG_DEBUG(NULL, "%s: previous attempt to load password '%s' from GNOME keyring failed, will try again: %s", +- key.description.c_str(), +- key.toString().c_str(), +- gnome_keyring_result_to_message(result)); +- FlushGNOMEKeyring(); +- Sleep(sleepSecs); +- } +- result = gnome_keyring_find_network_password_sync(passwdStr(key.user), +- passwdStr(key.domain), +- passwdStr(key.server), +- passwdStr(key.object), +- passwdStr(key.protocol), +- passwdStr(key.authtype), +- key.port, +- &list); +- sleepSecs = GNOMEKeyringRetryInterval; +- } while (result != GNOME_KEYRING_RESULT_OK && +- (Timespec::monotonic() - start).duration() < GNOMEKeyringRetryDuration); ++ GErrorCXX gerror; ++ LibSecretHash hash(key); ++ PlainGStr result(secret_password_lookupv_sync(SECRET_SCHEMA_COMPAT_NETWORK, ++ hash, ++ NULL, ++ gerror)); + + // if find password stored in gnome keyring +- if(result == GNOME_KEYRING_RESULT_OK && list && list->data ) { +- GnomeKeyringNetworkPasswordData *key_data; +- key_data = (GnomeKeyringNetworkPasswordData*)list->data; +- password = std::string(key_data->password); +- gnome_keyring_network_password_list_free(list); ++ if (gerror) { ++ gerror.throwError(SE_HERE, StringPrintf("looking up password '%s'", descr.c_str())); ++ } else if (result) { + SE_LOG_DEBUG(NULL, "%s: loaded password from GNOME keyring using %s", + key.description.c_str(), + key.toString().c_str()); ++ password = result; + } else { +- SE_LOG_DEBUG(NULL, "password not in GNOME keyring using %s: %s", +- key.toString().c_str(), +- result == GNOME_KEYRING_RESULT_NO_MATCH ? "no match" : +- result != GNOME_KEYRING_RESULT_OK ? gnome_keyring_result_to_message(result) : +- "empty result list"); ++ SE_LOG_DEBUG(NULL, "password not in GNOME keyring using %s", ++ key.toString().c_str()); + } + + return true; +@@ -173,38 +149,26 @@ bool GNOMESavePasswordSlot(const InitStateTri &keyring, + key.toString().c_str())); + } + +- guint32 itemId; +- GnomeKeyringResult result = GNOME_KEYRING_RESULT_OK; +- // write password to keyring +- Timespec start = Timespec::monotonic(); +- double sleepSecs = 0; +- do { +- if (sleepSecs != 0) { +- SE_LOG_DEBUG(NULL, "%s: previous attempt to save password '%s' in GNOME keyring failed, will try again: %s", +- key.description.c_str(), +- key.toString().c_str(), +- gnome_keyring_result_to_message(result)); +- FlushGNOMEKeyring(); +- Sleep(sleepSecs); +- } +- result = gnome_keyring_set_network_password_sync(NULL, +- passwdStr(key.user), +- passwdStr(key.domain), +- passwdStr(key.server), +- passwdStr(key.object), +- passwdStr(key.protocol), +- passwdStr(key.authtype), +- key.port, +- password.c_str(), +- &itemId); +- sleepSecs = GNOMEKeyringRetryInterval; +- } while (result != GNOME_KEYRING_RESULT_OK && +- (Timespec::monotonic() - start).duration() < GNOMEKeyringRetryDuration); +- if (result != GNOME_KEYRING_RESULT_OK) { +- Exception::throwError(SE_HERE, StringPrintf("%s: saving password '%s' in GNOME keyring failed: %s", +- key.description.c_str(), +- key.toString().c_str(), +- gnome_keyring_result_to_message(result))); ++ GErrorCXX gerror; ++ LibSecretHash hash(key); ++ std::string label; ++ if (!key.user.empty() && !key.server.empty()) { ++ // This emulates the behavior of libgnomekeyring. ++ label = key.user + "@" + key.server; ++ } else { ++ label = passwordName; ++ } ++ gboolean result = secret_password_storev_sync(SECRET_SCHEMA_COMPAT_NETWORK, ++ hash, ++ NULL, ++ label.c_str(), ++ password.c_str(), ++ NULL, ++ gerror); ++ if (!result) { ++ gerror.throwError(SE_HERE, StringPrintf("%s: saving password '%s' in GNOME keyring", ++ key.description.c_str(), ++ key.toString().c_str())); + } + SE_LOG_DEBUG(NULL, "saved password in GNOME keyring using %s", key.toString().c_str()); + +diff --git a/src/backends/gnome/configure-sub.in b/src/backends/gnome/configure-sub.in +index 199989e8..d02d52a6 100644 +--- a/src/backends/gnome/configure-sub.in ++++ b/src/backends/gnome/configure-sub.in +@@ -1,10 +1,13 @@ +-PKG_CHECK_MODULES(KEYRING, [gnome-keyring-1 >= 2.20], HAVE_KEYRING=yes, HAVE_KEYRING=no) ++# According to https://developer.gnome.org/libsecret/0.16/libsecret-Password-storage.html#secret-password-store-sync ++# the simple API was still considered unstable. All supported distros ++# now have 0.18 where the API is stable. ++PKG_CHECK_MODULES(KEYRING, [libsecret-1 >= 0.18], HAVE_KEYRING=yes, HAVE_KEYRING=no) + AC_ARG_ENABLE(gnome-keyring, + AS_HELP_STRING([--enable-gnome-keyring], +- [enables or disables support for the GNOME keyring; default is on if development files are available]), ++ [enables or disables support for the GNOME keyring via libsecret; default is on if development files are available]), + [enable_gnome_keyring="$enableval" + test "$enable_gnome_keyring" = "yes" || test "$enable_gnome_keyring" = "no" || AC_MSG_ERROR([invalid value for --enable-gnome-keyring: $enable_gnome_keyring]) +- test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([gnome-keyring-1 pkg >= 2.20 not found, needed for --enable-gnome-keyring])], ++ test "$enable_gnome_keyring" = "no" || test "$HAVE_KEYRING" = "yes" || AC_MSG_ERROR([libsecret-1 >= 0.18 not found, needed for --enable-gnome-keyring])], + enable_gnome_keyring="$HAVE_KEYRING") + if test $enable_gnome_keyring = "yes"; then + have_keyring=yes diff --git a/debian/patches/series b/debian/patches/series index 0dce5ab6..8654cbe2 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,4 @@ # debian/source/git-patches exported from git by quilt-patches-deb-export-hook 0001-Fix-FTBFS-on-kfreebsd-due-to-missing-SOCK_CLOEXEC.patch +0002-libical-support-libical-v3.patch +0003-GNOME-replace-gnome-keyring-with-libsecret.patch diff --git a/debian/rules b/debian/rules index 51715d4a..3bc15bf0 100755 --- a/debian/rules +++ b/debian/rules @@ -29,7 +29,8 @@ override_dh_auto_configure: --libexecdir=/usr/lib/$(DEB_HOST_MULTIARCH)/syncevolution \ --enable-gui \ --enable-kwallet --enable-akonadi \ - --with-rst2man --with-rst2html --enable-dav + --with-rst2man --with-rst2html --enable-dav \ + --enable-oauth2 override_dh_install: dh_install -X"*.pl" @@ -42,6 +43,9 @@ override_dh_auto_clean: src/synthesis-includes/Makefile.in test-driver dh_auto_clean +override_dh_makeshlibs: + dh_makeshlibs -V'libsyncevolution0 (>= 1.5.2-3~)' + get-orig-source: git archive --format=tar ${UPSTREAMTAG} --prefix=${SOURCEPKG}_${UPSTREAM}/ | gzip -9 > ../${ORIG} diff --git a/debian/syncevolution-libs.install b/debian/syncevolution-libs.install index 531beeba..6edeb576 100644 --- a/debian/syncevolution-libs.install +++ b/debian/syncevolution-libs.install @@ -6,4 +6,5 @@ usr/lib/*/syncevolution/backends/syncqtcontacts.so usr/lib/*/syncevolution/backends/syncmaemocal.so usr/lib/*/syncevolution/backends/syncactivesync.so usr/lib/*/syncevolution/backends/syncsqlite.so +usr/lib/*/syncevolution/backends/provideroauth2.so usr/lib/*/syncevolution/syncevo-local-sync