Version in base suite: 3.38.3-1 Base version: evolution-ews_3.38.3-1 Target version: evolution-ews_3.38.3-1+deb11u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/e/evolution-ews/evolution-ews_3.38.3-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/e/evolution-ews/evolution-ews_3.38.3-1+deb11u1.dsc changelog | 9 control | 4 control.in | 4 gbp.conf | 2 patches/Contacts-Retrieve-user-certificate.patch | 723 +++++++++++++++++++++++ patches/series | 1 6 files changed, 738 insertions(+), 5 deletions(-) diff -Nru evolution-ews-3.38.3/debian/changelog evolution-ews-3.38.3/debian/changelog --- evolution-ews-3.38.3/debian/changelog 2021-01-25 16:26:40.000000000 +0000 +++ evolution-ews-3.38.3/debian/changelog 2022-10-12 07:05:46.000000000 +0000 @@ -1,3 +1,12 @@ +evolution-ews (3.38.3-1+deb11u1) bullseye; urgency=medium + + * Non-maintainer upload. + * Backport from upstream: + - Fix retrieval of user certificates of contacts + (Closes: #1021531, #1021651) + + -- Claudius Heine Wed, 12 Oct 2022 09:05:46 +0200 + evolution-ews (3.38.3-1) unstable; urgency=medium * New upstream release diff -Nru evolution-ews-3.38.3/debian/control evolution-ews-3.38.3/debian/control --- evolution-ews-3.38.3/debian/control 2021-01-25 16:26:40.000000000 +0000 +++ evolution-ews-3.38.3/debian/control 2022-10-12 07:05:46.000000000 +0000 @@ -29,8 +29,8 @@ libsqlite3-dev, pkg-config, Standards-Version: 4.5.0 -Vcs-Browser: https://salsa.debian.org/gnome-team/evolution-ews -Vcs-Git: https://salsa.debian.org/gnome-team/evolution-ews.git +Vcs-Browser: https://salsa.debian.org/gnome-team/evolution-ews/tree/debian/bullseye +Vcs-Git: https://salsa.debian.org/gnome-team/evolution-ews.git -b debian/bullseye Homepage: https://wiki.gnome.org/Apps/Evolution Package: evolution-ews diff -Nru evolution-ews-3.38.3/debian/control.in evolution-ews-3.38.3/debian/control.in --- evolution-ews-3.38.3/debian/control.in 2021-01-25 16:26:40.000000000 +0000 +++ evolution-ews-3.38.3/debian/control.in 2022-10-12 07:05:46.000000000 +0000 @@ -25,8 +25,8 @@ libsqlite3-dev, pkg-config, Standards-Version: 4.5.0 -Vcs-Browser: https://salsa.debian.org/gnome-team/evolution-ews -Vcs-Git: https://salsa.debian.org/gnome-team/evolution-ews.git +Vcs-Browser: https://salsa.debian.org/gnome-team/evolution-ews/tree/debian/bullseye +Vcs-Git: https://salsa.debian.org/gnome-team/evolution-ews.git -b debian/bullseye Homepage: https://wiki.gnome.org/Apps/Evolution Package: evolution-ews diff -Nru evolution-ews-3.38.3/debian/gbp.conf evolution-ews-3.38.3/debian/gbp.conf --- evolution-ews-3.38.3/debian/gbp.conf 2021-01-25 16:26:40.000000000 +0000 +++ evolution-ews-3.38.3/debian/gbp.conf 2022-10-12 07:05:46.000000000 +0000 @@ -1,6 +1,6 @@ [DEFAULT] pristine-tar = True -debian-branch = debian/master +debian-branch = debian/bullseye upstream-branch = upstream/latest upstream-vcs-tag = %(version)s diff -Nru evolution-ews-3.38.3/debian/patches/Contacts-Retrieve-user-certificate.patch evolution-ews-3.38.3/debian/patches/Contacts-Retrieve-user-certificate.patch --- evolution-ews-3.38.3/debian/patches/Contacts-Retrieve-user-certificate.patch 1970-01-01 00:00:00.000000000 +0000 +++ evolution-ews-3.38.3/debian/patches/Contacts-Retrieve-user-certificate.patch 2022-10-12 07:05:46.000000000 +0000 @@ -0,0 +1,723 @@ +From: Milan Crha +Date: Fri, 17 Sep 2021 12:29:02 +0200 +Subject: I#3 - Contacts: Retrieve user certificate + +Closes https://gitlab.gnome.org/GNOME/evolution-ews/-/issues/3 + +(cherry picked from commit 9ea6bc01136e420078c2a0f4140108e79cf8d538) + +Bug-Debian: https://bugs.debian.org/994252 +--- + src/EWS/addressbook/e-book-backend-ews.c | 335 ++++++++++++++++++++++++++++--- + src/EWS/addressbook/ews-oab-decoder.c | 54 ++++- + src/EWS/common/e-ews-connection.c | 8 +- + src/EWS/common/e-ews-item.c | 65 ++++++ + src/EWS/common/e-ews-item.h | 5 + + 5 files changed, 431 insertions(+), 36 deletions(-) + +diff --git a/src/EWS/addressbook/e-book-backend-ews.c b/src/EWS/addressbook/e-book-backend-ews.c +index 197d49f..9bf7510 100644 +--- a/src/EWS/addressbook/e-book-backend-ews.c ++++ b/src/EWS/addressbook/e-book-backend-ews.c +@@ -60,6 +60,10 @@ + #define X_EWS_CHANGEKEY "X-EWS-CHANGEKEY" + #define X_EWS_GAL_SHA1 "X-EWS-GAL-SHA1" + #define X_EWS_PHOTO_CHECK_DATE "X-EWS-PHOTO-CHECK-DATE" /* YYYYMMDD of the last check for photo */ ++#define X_EWS_CERT_KIND "X-EWS-CERT-KIND" ++ ++#define E_EWS_CERT_KIND_USER "UserSMIMECertificate" ++#define E_EWS_CERT_KIND_MSEX "MSExchangeCertificate" + + #define EWS_MAX_FETCH_COUNT 500 + +@@ -69,7 +73,19 @@ + /* passing field uris for PhysicalAddress, PhoneNumbers causes error, so we + * use Default view to fetch them. Thus the summary props just have attachments + * and some additional properties that are not return with Default view */ +-#define CONTACT_ITEM_PROPS "item:Attachments item:HasAttachments item:Body item:LastModifiedTime contacts:Manager contacts:Department contacts:SpouseName contacts:AssistantName contacts:BusinessHomePage contacts:Birthday" ++#define CONTACT_ITEM_PROPS "item:Attachments "\ ++ "item:HasAttachments "\ ++ "item:Body "\ ++ "item:LastModifiedTime "\ ++ "contacts:Manager "\ ++ "contacts:Department "\ ++ "contacts:SpouseName "\ ++ "contacts:AssistantName "\ ++ "contacts:BusinessHomePage "\ ++ "contacts:Birthday" ++#define CONTACT_ITEM_PROPS_10SP2 CONTACT_ITEM_PROPS " "\ ++ "contacts:UserSMIMECertificate "\ ++ "contacts:MSExchangeCertificate" + + struct _EBookBackendEwsPrivate { + GRecMutex cnc_lock; +@@ -551,6 +567,238 @@ ebews_populate_photo (EBookBackendEws *bbews, + e_contact_photo_free (photo); + } + ++static void ++ebews_populate_cert (EBookBackendEws *bbews, ++ EContact *contact, ++ EEwsItem *item, ++ const gchar *kind, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ EVCardAttribute *attr; ++ EContactCert cert; ++ ++ g_return_if_fail (g_str_equal (kind, E_EWS_CERT_KIND_USER) || g_str_equal (kind, E_EWS_CERT_KIND_MSEX)); ++ ++ /* Support for certificates was added in Exchange 2010 SP2. */ ++ if (!e_ews_connection_satisfies_server_version (bbews->priv->cnc, E_EWS_EXCHANGE_2010_SP2)) ++ return; ++ ++ if (g_str_equal (kind, E_EWS_CERT_KIND_USER)) ++ cert.data = (gchar *) e_ews_item_get_user_certificate (item, &cert.length); ++ else ++ cert.data = (gchar *) e_ews_item_get_msexchange_certificate (item, &cert.length); ++ ++ if (!cert.data || !cert.length) ++ return; ++ ++ attr = e_vcard_attribute_new (NULL, EVC_KEY); ++ ++ e_vcard_append_attribute (E_VCARD (contact), attr); ++ ++ e_vcard_attribute_add_param_with_value ( ++ attr, ++ e_vcard_attribute_param_new (EVC_TYPE), ++ "X509"); ++ ++ e_vcard_attribute_add_param_with_value ( ++ attr, ++ e_vcard_attribute_param_new (EVC_ENCODING), ++ "b"); ++ ++ e_vcard_attribute_add_param_with_value ( ++ attr, ++ e_vcard_attribute_param_new (X_EWS_CERT_KIND), ++ kind); ++ ++ e_vcard_attribute_add_value_decoded (attr, cert.data, cert.length); ++} ++ ++static void ++ebews_populate_user_cert (EBookBackendEws *bbews, ++ EContact *contact, ++ EEwsItem *item, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ebews_populate_cert (bbews, contact, item, E_EWS_CERT_KIND_USER, cancellable, error); ++} ++ ++static void ++ebews_populate_msex_cert (EBookBackendEws *bbews, ++ EContact *contact, ++ EEwsItem *item, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ebews_populate_cert (bbews, contact, item, E_EWS_CERT_KIND_MSEX, cancellable, error); ++} ++ ++static EVCardAttribute * ++ebews_find_cert_attribute (EContact *contact, ++ const gchar *kind, ++ gint fallback_index) ++{ ++ GList *link; ++ EVCardAttribute *fallback_attr = NULL; ++ ++ for (link = e_vcard_get_attributes (E_VCARD (contact)); link; link = g_list_next (link)) { ++ EVCardAttribute *attr = link->data; ++ const gchar *attr_name; ++ ++ attr_name = e_vcard_attribute_get_name (attr); ++ ++ if (attr_name && g_ascii_strcasecmp (attr_name, EVC_KEY) == 0) { ++ GList *values; ++ gboolean is_x509 = FALSE; ++ ++ for (values = e_vcard_attribute_get_param (attr, EVC_TYPE); values && !is_x509; values = g_list_next (values)) { ++ is_x509 = values->data && g_ascii_strcasecmp ((gchar *) values->data, "X509") == 0; ++ } ++ ++ if (!is_x509) ++ continue; ++ ++ if (!fallback_attr) { ++ if (!fallback_index) { ++ fallback_attr = attr; ++ fallback_index = -1; ++ } else if (fallback_index > 0) { ++ fallback_index--; ++ } ++ } ++ ++ for (values = e_vcard_attribute_get_param (attr, X_EWS_CERT_KIND); values; values = g_list_next (values)) { ++ if (values->data && g_ascii_strcasecmp ((gchar *) values->data, kind) == 0) ++ return attr; ++ } ++ } ++ } ++ ++ return fallback_attr; ++} ++ ++static const gchar * ++ebews_find_cert_base64_data (EContact *contact, ++ const gchar *kind, ++ gint fallback_index) ++{ ++ EVCardAttribute *attr; ++ GList *values; ++ const gchar *base64_data; ++ ++ attr = ebews_find_cert_attribute (contact, kind, fallback_index); ++ if (!attr) ++ return NULL; ++ ++ values = e_vcard_attribute_get_values (attr); ++ base64_data = values ? values->data : NULL; ++ ++ if (base64_data && *base64_data) ++ return base64_data; ++ ++ return NULL; ++} ++ ++static void ++ebews_set_cert (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact, ++ const gchar *kind, ++ gint fallback_index) ++{ ++ const gchar *base64_data; ++ ++ /* Support for certificates was added in Exchange 2010 SP2. */ ++ if (!e_ews_connection_satisfies_server_version (bbews->priv->cnc, E_EWS_EXCHANGE_2010_SP2)) ++ return; ++ ++ base64_data = ebews_find_cert_base64_data (contact, kind, fallback_index); ++ if (!base64_data) ++ return; ++ ++ e_soap_message_start_element (message, kind, NULL, NULL); ++ e_ews_message_write_string_parameter (message, "Base64Binary", NULL, base64_data); ++ e_soap_message_end_element (message); ++} ++ ++static void ++ebews_set_user_cert (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact) ++{ ++ ebews_set_cert (bbews, message, contact, E_EWS_CERT_KIND_USER, 0); ++} ++ ++ ++static void ++ebews_set_msex_cert (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact) ++{ ++ ebews_set_cert (bbews, message, contact, E_EWS_CERT_KIND_MSEX, 1); ++} ++ ++static void ++ebews_set_cert_changes (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *new, ++ EContact *old, ++ const gchar *kind, ++ gint fallback_index) ++{ ++ const gchar *new_base64_data, *old_base64_data; ++ ++ /* The first pass */ ++ if (!message) ++ return; ++ ++ /* Support for certificates was added in Exchange 2010 SP2. */ ++ if (!e_ews_connection_satisfies_server_version (bbews->priv->cnc, E_EWS_EXCHANGE_2010_SP2)) ++ return; ++ ++ /* Intentionally search by kind in the old contact, the new can have added cert, which would not have set the kind yet */ ++ new_base64_data = ebews_find_cert_base64_data (new, kind, fallback_index); ++ old_base64_data = ebews_find_cert_base64_data (old, kind, -1); ++ ++ if (g_strcmp0 (new_base64_data, old_base64_data) == 0) ++ return; ++ ++ if (new_base64_data) { ++ e_ews_message_start_set_item_field (message, kind, "contacts", "Contact"); ++ e_soap_message_start_element (message, kind, NULL, NULL); ++ e_ews_message_write_string_parameter (message, "Base64Binary", NULL, new_base64_data); ++ e_soap_message_end_element (message); ++ e_ews_message_end_set_item_field (message); ++ } else { ++ e_ews_message_add_delete_item_field (message, kind, "contacts"); ++ } ++} ++ ++static void ++ebews_set_user_cert_changes (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *new, ++ EContact *old, ++ gchar **out_new_change_key, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ebews_set_cert_changes (bbews, message, new, old, E_EWS_CERT_KIND_USER, 0); ++} ++ ++static void ++ebews_set_msex_cert_changes (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *new, ++ EContact *old, ++ gchar **out_new_change_key, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ebews_set_cert_changes (bbews, message, new, old, E_EWS_CERT_KIND_MSEX, 1); ++} ++ + static void + set_phone_number (EContact *contact, + EContactField field, +@@ -716,15 +964,17 @@ ebews_populate_emails (EBookBackendEws *bbews, + } + + static void +-ebews_set_item_id (ESoapMessage *message, +- EContact *contact) ++ebews_set_item_id (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact) + { + + } + + static void +-ebews_set_full_name (ESoapMessage *msg, +- EContact *contact) ++ebews_set_full_name (EBookBackendEws *bbews, ++ ESoapMessage *msg, ++ EContact *contact) + { + EContactName *name; + +@@ -765,22 +1015,25 @@ ebews_set_date_value (ESoapMessage *message, + } + + static void +-ebews_set_birth_date (ESoapMessage *message, +- EContact *contact) ++ebews_set_birth_date (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact) + { + ebews_set_date_value (message, contact, E_CONTACT_BIRTH_DATE, "Birthday"); + } + + static void +-ebews_set_anniversary (ESoapMessage *message, +- EContact *contact) ++ebews_set_anniversary (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact) + { + ebews_set_date_value (message, contact, E_CONTACT_ANNIVERSARY, "WeddingAnniversary"); + } + + static void +-ebews_set_photo (ESoapMessage *message, +- EContact *contact) ++ebews_set_photo (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact) + { + + } +@@ -811,8 +1064,9 @@ add_entry (ESoapMessage *msg, + } + + static void +-ebews_set_phone_numbers (ESoapMessage *msg, +- EContact *contact) ++ebews_set_phone_numbers (EBookBackendEws *bbews, ++ ESoapMessage *msg, ++ EContact *contact) + { + gint i; + const gchar *include_hdr = "PhoneNumbers"; +@@ -858,8 +1112,9 @@ add_physical_address (ESoapMessage *msg, + } + + static void +-ebews_set_address (ESoapMessage *msg, +- EContact *contact) ++ebews_set_address (EBookBackendEws *bbews, ++ ESoapMessage *msg, ++ EContact *contact) + { + gboolean include_hdr = TRUE; + +@@ -875,15 +1130,17 @@ ebews_set_address (ESoapMessage *msg, + } + + static void +-ebews_set_ims (ESoapMessage *message, +- EContact *contact) ++ebews_set_ims (EBookBackendEws *bbews, ++ ESoapMessage *message, ++ EContact *contact) + { + + } + + static void +-ebews_set_notes (ESoapMessage *msg, +- EContact *contact) ++ebews_set_notes (EBookBackendEws *bbews, ++ ESoapMessage *msg, ++ EContact *contact) + { + gchar *notes = e_contact_get (contact, E_CONTACT_NOTE); + if (!notes) +@@ -895,8 +1152,9 @@ ebews_set_notes (ESoapMessage *msg, + } + + static void +-ebews_set_emails (ESoapMessage *msg, +- EContact *contact) ++ebews_set_emails (EBookBackendEws *bbews, ++ ESoapMessage *msg, ++ EContact *contact) + { + const gchar *include_hdr = "EmailAddresses"; + +@@ -1470,7 +1728,8 @@ ebews_populate_givenname (EBookBackendEws *bbews, + } + + static void +-ebews_set_givenname (ESoapMessage *message, ++ebews_set_givenname (EBookBackendEws *bbews, ++ ESoapMessage *message, + EContact *contact) + { + /* Does nothing, the "GivenName" is filled by the "FullName" code */ +@@ -1507,7 +1766,7 @@ static const struct field_element_mapping { + /* set function for simple string type values */ + const gchar * (*get_simple_prop_func) (EEwsItem *item); + void (*populate_contact_func)(EBookBackendEws *bbews, EContact *contact, EEwsItem *item, GCancellable *cancellable, GError **error); +- void (*set_value_in_soap_message) (ESoapMessage *message, EContact *contact); ++ void (*set_value_in_soap_message) (EBookBackendEws *bbews, ESoapMessage *message, EContact *contact); + void (*set_changes) (EBookBackendEws *bbews, ESoapMessage *message, EContact *new, EContact *old, gchar **out_new_change_key, GCancellable *cancellable, GError **error); + + } mappings[] = { +@@ -1538,6 +1797,8 @@ static const struct field_element_mapping { + { E_CONTACT_GIVEN_NAME, ELEMENT_TYPE_COMPLEX, "GivenName", NULL, ebews_populate_givenname, ebews_set_givenname, ebews_set_givenname_changes}, + { E_CONTACT_ANNIVERSARY, ELEMENT_TYPE_COMPLEX, "WeddingAnniversary", NULL, ebews_populate_anniversary, ebews_set_anniversary, ebews_set_anniversary_changes }, + { E_CONTACT_PHOTO, ELEMENT_TYPE_COMPLEX, "Photo", NULL, ebews_populate_photo, ebews_set_photo, ebews_set_photo_changes }, ++ { E_CONTACT_X509_CERT, ELEMENT_TYPE_COMPLEX, "UserSMIMECertificate", NULL, ebews_populate_user_cert, ebews_set_user_cert, ebews_set_user_cert_changes }, ++ { E_CONTACT_X509_CERT, ELEMENT_TYPE_COMPLEX, "MSExchangeCertificate", NULL, ebews_populate_msex_cert, ebews_set_msex_cert, ebews_set_msex_cert_changes }, + + /* Should take of uid and changekey (REV) */ + { E_CONTACT_UID, ELEMENT_TYPE_COMPLEX, "ItemId", NULL, ebews_populate_uid, ebews_set_item_id}, +@@ -1578,12 +1839,19 @@ ebb_ews_write_dl_members (ESoapMessage *msg, + e_soap_message_end_element (msg); /* Members */ + } + ++typedef struct _CreateItemsData ++{ ++ EBookBackendEws *bbews; ++ EContact *contact; ++} CreateItemsData; ++ + static gboolean + ebb_ews_convert_dl_to_xml_cb (ESoapMessage *msg, + gpointer user_data, + GError **error) + { +- EContact *contact = user_data; ++ CreateItemsData *cid = user_data; ++ EContact *contact = cid->contact; + EVCardAttribute *attribute; + GList *values; + +@@ -1606,7 +1874,8 @@ ebb_ews_convert_contact_to_xml_cb (ESoapMessage *msg, + gpointer user_data, + GError **error) + { +- EContact *contact = user_data; ++ CreateItemsData *cid = user_data; ++ EContact *contact = cid->contact; + gint i, element_type; + + /* Prepare Contact node in the SOAP message */ +@@ -1627,7 +1896,7 @@ ebb_ews_convert_contact_to_xml_cb (ESoapMessage *msg, + e_ews_message_write_string_parameter (msg, mappings[i].element_name, NULL, val); + g_free (val); + } else +- mappings[i].set_value_in_soap_message (msg, contact); ++ mappings[i].set_value_in_soap_message (cid->bbews, msg, contact); + } + + /* end of "Contact" */ +@@ -2032,7 +2301,11 @@ ebb_ews_fetch_items_sync (EBookBackendEws *bbews, + if (contact_item_ids) { + EEwsAdditionalProps *add_props; + add_props = e_ews_additional_props_new (); +- add_props->field_uri = g_strdup (CONTACT_ITEM_PROPS); ++ ++ if (e_ews_connection_satisfies_server_version (bbews->priv->cnc, E_EWS_EXCHANGE_2010_SP2)) ++ add_props->field_uri = g_strdup (CONTACT_ITEM_PROPS_10SP2); ++ else ++ add_props->field_uri = g_strdup (CONTACT_ITEM_PROPS); + + ret = e_ews_connection_get_items_sync ( + bbews->priv->cnc, EWS_PRIORITY_MEDIUM, +@@ -3730,8 +4003,13 @@ ebb_ews_save_contact_sync (EBookMetaBackend *meta_backend, + g_clear_object (&old_contact); + g_clear_object (&book_cache); + } else { ++ CreateItemsData cid; ++ ++ cid.bbews = bbews; ++ cid.contact = contact; ++ + success = e_ews_connection_create_items_sync (bbews->priv->cnc, EWS_PRIORITY_MEDIUM, NULL, NULL, +- fid, is_dl ? ebb_ews_convert_dl_to_xml_cb : ebb_ews_convert_contact_to_xml_cb, contact, ++ fid, is_dl ? ebb_ews_convert_dl_to_xml_cb : ebb_ews_convert_contact_to_xml_cb, &cid, + &items, cancellable, error); + } + +@@ -3970,6 +4248,7 @@ ebb_ews_get_backend_property (EBookBackend *book_backend, + e_contact_field_name (E_CONTACT_BIRTH_DATE), + e_contact_field_name (E_CONTACT_NOTE), + e_contact_field_name (E_CONTACT_PHOTO), ++ e_contact_field_name (E_CONTACT_X509_CERT), + NULL); + + g_string_free (buffer, TRUE); +diff --git a/src/EWS/addressbook/ews-oab-decoder.c b/src/EWS/addressbook/ews-oab-decoder.c +index cc73401..3374440 100644 +--- a/src/EWS/addressbook/ews-oab-decoder.c ++++ b/src/EWS/addressbook/ews-oab-decoder.c +@@ -140,21 +140,61 @@ ews_populate_string_list (EContact *contact, + } + + static void +-ews_populate_cert (EContact *contact, +- EContactField field, +- gpointer value, +- gpointer user_data) ++ews_populate_cert_data (EContact *contact, ++ GBytes *bytes) + { +- GSList *list = value; +- GBytes *bytes = list->data; + EContactCert cert; + ++ if (!bytes || !g_bytes_get_size (bytes)) ++ return; ++ + cert.data = (gpointer) g_bytes_get_data (bytes, &cert.length); + cert.length = g_bytes_get_size (bytes); + + e_contact_set (contact, E_CONTACT_X509_CERT, &cert); + } + ++static void ++ews_populate_cert (EContact *contact, ++ EContactField field, ++ gpointer value, ++ gpointer user_data) ++{ ++ GSList *link; ++ ++ for (link = value; link; link = g_slist_next (link)) { ++ GBytes *bytes = link->data; ++ ++ ews_populate_cert_data (contact, bytes); ++ } ++} ++ ++static void ++ews_populate_user_cert (EContact *contact, ++ EContactField field, ++ gpointer value, ++ gpointer user_data) ++{ ++ GBytes *bytes = value; ++ ++ ews_populate_cert_data (contact, bytes); ++} ++ ++static void ++ews_populate_user_x509_cert (EContact *contact, ++ EContactField field, ++ gpointer value, ++ gpointer user_data) ++{ ++ GSList *link; ++ ++ for (link = value; link; link = g_slist_next (link)) { ++ GBytes *bytes = link->data; ++ ++ ews_populate_cert_data (contact, bytes); ++ } ++} ++ + static void + ews_populate_photo (EContact *contact, + EContactField field, +@@ -243,6 +283,8 @@ static const struct prop_field_mapping { + {EWS_PT_THUMBNAIL_PHOTO, E_CONTACT_PHOTO, ews_populate_photo}, + {EWS_PT_OFFICE_LOCATION, E_CONTACT_OFFICE, ews_populate_simple_string}, + {EWS_PT_X509_CERT, E_CONTACT_X509_CERT, ews_populate_cert}, ++ {EWS_PT_USER_CERTIFICATE, E_CONTACT_X509_CERT, ews_populate_user_cert}, ++ {EWS_PT_USER_X509_CERTIFICATE, E_CONTACT_X509_CERT, ews_populate_user_x509_cert}, + {EWS_PT_SEND_RICH_INFO, E_CONTACT_WANTS_HTML, ews_populate_simple_string}, + }; + +diff --git a/src/EWS/common/e-ews-connection.c b/src/EWS/common/e-ews-connection.c +index 1d31806..933d923 100644 +--- a/src/EWS/common/e-ews-connection.c ++++ b/src/EWS/common/e-ews-connection.c +@@ -6268,10 +6268,14 @@ e_ews_connection_resolve_names (EEwsConnection *cnc, + + e_soap_message_add_attribute (msg, "SearchScope", get_search_scope_str (scope), NULL, NULL); + +- if (fetch_contact_data) ++ if (fetch_contact_data) { + e_soap_message_add_attribute (msg, "ReturnFullContactData", "true", NULL, NULL); +- else ++ ++ if (e_ews_connection_satisfies_server_version (cnc, E_EWS_EXCHANGE_2010_SP2)) ++ e_soap_message_add_attribute (msg, "ContactDataShape", "AllProperties", NULL, NULL); ++ } else { + e_soap_message_add_attribute (msg, "ReturnFullContactData", "false", NULL, NULL); ++ } + + if (parent_folder_ids) { + e_soap_message_start_element (msg, "ParentFolderIds", "messages", NULL); +diff --git a/src/EWS/common/e-ews-item.c b/src/EWS/common/e-ews-item.c +index 73a82fd..ce8fa4d 100644 +--- a/src/EWS/common/e-ews-item.c ++++ b/src/EWS/common/e-ews-item.c +@@ -52,6 +52,12 @@ struct _EEwsContactFields { + gchar *givenname; + gchar *middlename; + gchar *notes; ++ ++ gsize msexchange_cert_len; ++ guchar *msexchange_cert; ++ ++ gsize user_cert_len; ++ guchar *user_cert; + }; + + struct _EEwsTaskFields { +@@ -337,6 +343,8 @@ ews_free_contact_fields (struct _EEwsContactFields *con_fields) + g_free (con_fields->givenname); + g_free (con_fields->middlename); + g_free (con_fields->notes); ++ g_free (con_fields->msexchange_cert); ++ g_free (con_fields->user_cert); + g_free (con_fields); + } + } +@@ -827,6 +835,37 @@ parse_contact_field (EEwsItem *item, + * with old servers (< 2010_SP2) we prefer use item:Body. + */ + priv->contact_fields->notes = e_soap_parameter_get_string_value (subparam); ++ } else if (!g_ascii_strcasecmp (name, "UserSMIMECertificate") || ++ !g_ascii_strcasecmp (name, "MSExchangeCertificate")) { ++ ESoapParameter *data_param; ++ guchar **out_bytes; ++ gsize *out_len; ++ ++ if (!g_ascii_strcasecmp (name, "UserSMIMECertificate")) { ++ out_bytes = &priv->contact_fields->user_cert; ++ out_len = &priv->contact_fields->user_cert_len; ++ } else { ++ out_bytes = &priv->contact_fields->msexchange_cert; ++ out_len = &priv->contact_fields->msexchange_cert_len; ++ } ++ ++ data_param = e_soap_parameter_get_first_child_by_name (subparam, "Base64Binary"); ++ if (data_param) { ++ gchar *base64_data; ++ ++ base64_data = e_soap_parameter_get_string_value (data_param); ++ if (base64_data && *base64_data) { ++ *out_bytes = g_base64_decode_inplace (base64_data, out_len); ++ if (!*out_len) { ++ g_free (*out_bytes); ++ ++ *out_len = 0; ++ *out_bytes = NULL; ++ } ++ } else { ++ g_free (base64_data); ++ } ++ } + } + } + +@@ -2698,6 +2737,32 @@ e_ews_item_get_notes (EEwsItem *item) + return item->priv->contact_fields->notes; + } + ++const guchar * ++e_ews_item_get_user_certificate (EEwsItem *item, ++ gsize *out_len) ++{ ++ g_return_val_if_fail (E_IS_EWS_ITEM (item), NULL); ++ g_return_val_if_fail (item->priv->contact_fields != NULL, NULL); ++ g_return_val_if_fail (out_len != NULL, NULL); ++ ++ *out_len = item->priv->contact_fields->user_cert_len; ++ ++ return item->priv->contact_fields->user_cert; ++} ++ ++const guchar * ++e_ews_item_get_msexchange_certificate (EEwsItem *item, ++ gsize *out_len) ++{ ++ g_return_val_if_fail (E_IS_EWS_ITEM (item), NULL); ++ g_return_val_if_fail (item->priv->contact_fields != NULL, NULL); ++ g_return_val_if_fail (out_len != NULL, NULL); ++ ++ *out_len = item->priv->contact_fields->msexchange_cert_len; ++ ++ return item->priv->contact_fields->msexchange_cert; ++} ++ + time_t + e_ews_item_get_birthday (EEwsItem *item) + { +diff --git a/src/EWS/common/e-ews-item.h b/src/EWS/common/e-ews-item.h +index fde4652..8a0dbbf 100644 +--- a/src/EWS/common/e-ews-item.h ++++ b/src/EWS/common/e-ews-item.h +@@ -419,6 +419,11 @@ const gchar * e_ews_item_get_surname (EEwsItem *item); + const gchar * e_ews_item_get_givenname (EEwsItem *item); + const gchar * e_ews_item_get_middlename (EEwsItem *item); + const gchar * e_ews_item_get_notes (EEwsItem *item); ++const guchar * e_ews_item_get_user_certificate (EEwsItem *item, ++ gsize *out_len); ++const guchar * e_ews_item_get_msexchange_certificate ++ (EEwsItem *item, ++ gsize *out_len); + + /*Task fields*/ + const gchar * e_ews_item_get_status (EEwsItem *item); diff -Nru evolution-ews-3.38.3/debian/patches/series evolution-ews-3.38.3/debian/patches/series --- evolution-ews-3.38.3/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ evolution-ews-3.38.3/debian/patches/series 2022-10-12 07:05:46.000000000 +0000 @@ -0,0 +1 @@ +Contacts-Retrieve-user-certificate.patch