summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2010-12-15 13:00:00 +0000
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2012-05-09 12:14:09 +0200
commitc39eff9d8fdbb0de2235440d159d2d6923d0f674 (patch)
tree248f307592423147eb19aefddaec47327c6620e2
parent43978342cf1925fac3eca5cb2e4d235334228a76 (diff)
TpTLSCertificate: track the signalled rejection reason(s)
-rw-r--r--docs/reference/telepathy-glib-sections.txt2
-rw-r--r--telepathy-glib/tls-certificate.c162
-rw-r--r--telepathy-glib/tls-certificate.h10
3 files changed, 173 insertions, 1 deletions
diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index 69cdec90a..d5b4b6a52 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -7331,6 +7331,8 @@ TpTLSCertificate
tp_tls_certificate_init_known_interfaces
tp_tls_certificate_new
TP_TLS_CERTIFICATE_FEATURE_CORE
+tp_tls_certificate_get_rejection
+tp_tls_certificate_get_nth_rejection
tp_tls_certificate_accept_async
tp_tls_certificate_accept_finish
tp_tls_certificate_reject_async
diff --git a/telepathy-glib/tls-certificate.c b/telepathy-glib/tls-certificate.c
index 1041baa0d..901a097a1 100644
--- a/telepathy-glib/tls-certificate.c
+++ b/telepathy-glib/tls-certificate.c
@@ -81,6 +81,8 @@ struct _TpTLSCertificatePrivate {
gchar *cert_type;
GPtrArray *cert_data;
TpTLSCertificateState state;
+ /* array of SignalledRejection */
+ GArray *rejections;
};
G_DEFINE_TYPE (TpTLSCertificate, tp_tls_certificate,
@@ -113,11 +115,40 @@ tp_tls_certificate_get_feature_quark_core (void)
return g_quark_from_static_string ("tp-tls-certificate-feature-core");
}
+typedef struct {
+ GError *error /* NULL-initialized later */ ;
+ TpTLSCertificateRejectReason reason;
+ gchar *dbus_error;
+ GHashTable *details;
+} SignalledRejection;
+
+static void
+tp_tls_certificate_clear_rejections (TpTLSCertificate *self)
+{
+ if (self->priv->rejections != NULL)
+ {
+ guint i;
+
+ for (i = 0; i < self->priv->rejections->len; i++)
+ {
+ SignalledRejection *sr = &g_array_index (self->priv->rejections,
+ SignalledRejection, i);
+
+ g_clear_error (&sr->error);
+ tp_clear_pointer (&sr->dbus_error, g_free);
+ tp_clear_pointer (&sr->details, g_hash_table_unref);
+ }
+ }
+
+ tp_clear_pointer (&self->priv->rejections, g_array_unref);
+}
+
static void
tp_tls_certificate_accepted_cb (TpTLSCertificate *self,
gpointer unused G_GNUC_UNUSED,
GObject *unused_object G_GNUC_UNUSED)
{
+ tp_tls_certificate_clear_rejections (self);
self->priv->state = TP_TLS_CERTIFICATE_STATE_ACCEPTED;
g_object_notify ((GObject *) self, "state");
}
@@ -129,6 +160,56 @@ tp_tls_certificate_rejected_cb (TpTLSCertificate *self,
GObject *unused_object G_GNUC_UNUSED)
{
self->priv->state = TP_TLS_CERTIFICATE_STATE_REJECTED;
+
+ tp_tls_certificate_clear_rejections (self);
+
+ if (rejections == NULL || rejections->len == 0)
+ {
+ SignalledRejection sr = {
+ g_error_new_literal (TP_ERROR, TP_ERROR_CERT_INVALID,
+ "Rejected, no reason given"),
+ TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN,
+ g_strdup (TP_ERROR_STR_CERT_INVALID),
+ tp_asv_new (NULL, NULL) };
+
+ self->priv->rejections = g_array_sized_new (FALSE, FALSE,
+ sizeof (SignalledRejection), 1);
+ g_array_append_val (self->priv->rejections, sr);
+ }
+ else
+ {
+ guint i;
+
+ self->priv->rejections = g_array_sized_new (FALSE, FALSE,
+ sizeof (SignalledRejection), rejections->len);
+
+ for (i = 0; i < rejections->len; i++)
+ {
+ SignalledRejection sr = { NULL };
+ GValueArray *va = g_ptr_array_index (rejections, i);
+ const gchar *error_name;
+ const GHashTable *details;
+
+ tp_value_array_unpack (va, 3,
+ &sr.reason,
+ &error_name,
+ &details);
+
+ tp_proxy_dbus_error_to_gerror (self, error_name,
+ tp_asv_get_string (details, "debug-message"), &sr.error);
+
+ sr.details = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) tp_g_value_slice_free);
+ tp_g_hash_table_update (sr.details, (GHashTable *) details,
+ (GBoxedCopyFunc) g_strdup,
+ (GBoxedCopyFunc) tp_g_value_slice_dup);
+
+ sr.dbus_error = g_strdup (error_name);
+
+ g_array_append_val (self->priv->rejections, sr);
+ }
+ }
+
g_object_notify ((GObject *) self, "state");
}
@@ -248,6 +329,7 @@ tp_tls_certificate_finalize (GObject *object)
DEBUG ("%p", object);
+ tp_tls_certificate_clear_rejections (self);
g_free (priv->cert_type);
tp_clear_boxed (TP_ARRAY_TYPE_UCHAR_ARRAY_LIST, &priv->cert_data);
@@ -624,7 +706,7 @@ tp_tls_certificate_reject_async (TpTLSCertificate *self,
DEBUG ("Rejecting TLS certificate with reason %u", reason);
- rejections = build_rejections_array (reason, details);
+ rejections = build_rejections_array (reason, dbus_error, details);
reject_result = g_simple_async_result_new (G_OBJECT (self),
callback, user_data, tp_tls_certificate_reject_async);
@@ -685,3 +767,81 @@ tp_tls_certificate_init_known_interfaces (void)
g_once_init_leave (&once, 1);
}
}
+
+/**
+ * tp_tls_certificate_get_rejection:
+ * @self: a TLS certificate
+ * @reason: (out) (allow-none): optionally used to return the reason code
+ * @dbus_error: (out) (type utf8) (allow-none) (transfer none): optionally
+ * used to return the D-Bus error name
+ * @details: (out) (allow-none) (transfer none) (element-type utf8 GObject.Value):
+ * optionally used to return a map from string to #GValue, which must not be
+ * modified or destroyed by the caller
+ *
+ * If this certificate has been rejected, return a #GError (likely to be in
+ * the %TP_ERROR domain) indicating the first rejection reason (by convention,
+ * the most important).
+ *
+ * If you want to list all the things that are wrong with the certificate
+ * (for instance, it might be self-signed and also have expired)
+ * you can call tp_tls_certificate_get_nth_rejection(), increasing @n until
+ * it returns %NULL.
+ *
+ * Returns: (transfer none) (allow-none): a #GError, or %NULL
+ */
+const GError *
+tp_tls_certificate_get_rejection (TpTLSCertificate *self,
+ TpTLSCertificateRejectReason *reason,
+ const gchar **dbus_error,
+ const GHashTable **details)
+{
+ return tp_tls_certificate_get_nth_rejection (self, 0, reason, dbus_error,
+ details);
+}
+
+/**
+ * tp_tls_certificate_get_nth_rejection:
+ * @self: a TLS certificate
+ * @n: the rejection reason to return; if 0, return the same thing as
+ * tp_tls_certificate_get_detailed_rejection()
+ * @reason: (out) (allow-none): optionally used to return the reason code
+ * @dbus_error: (out) (type utf8) (allow-none) (transfer none): optionally
+ * used to return the D-Bus error name
+ * @details: (out) (allow-none) (transfer none) (element-type utf8 GObject.Value):
+ * optionally used to return a map from string to #GValue, which must not be
+ * modified or destroyed by the caller
+ *
+ * If this certificate has been rejected and @n is less than the number of
+ * rejection reasons, return a #GError representing the @n<!---->th rejection
+ * reason (starting from 0), with additional information returned via the
+ * 'out' parameters.
+ *
+ * With @n == 0 this is equivalent to tp_tls_certificate_get_rejection().
+ *
+ * Returns: (transfer none) (allow-none): a #GError, or %NULL
+ */
+const GError *
+tp_tls_certificate_get_nth_rejection (TpTLSCertificate *self,
+ guint n,
+ TpTLSCertificateRejectReason *reason,
+ const gchar **dbus_error,
+ const GHashTable **details)
+{
+ const SignalledRejection *rej;
+
+ if (self->priv->rejections == NULL || n >= self->priv->rejections->len)
+ return NULL;
+
+ rej = &g_array_index (self->priv->rejections, SignalledRejection, n);
+
+ if (reason != NULL)
+ *reason = rej->reason;
+
+ if (dbus_error != NULL)
+ *dbus_error = rej->dbus_error;
+
+ if (details != NULL)
+ *details = rej->details;
+
+ return rej->error;
+}
diff --git a/telepathy-glib/tls-certificate.h b/telepathy-glib/tls-certificate.h
index 300a9aea3..8b97e884a 100644
--- a/telepathy-glib/tls-certificate.h
+++ b/telepathy-glib/tls-certificate.h
@@ -76,6 +76,16 @@ TpTLSCertificate *tp_tls_certificate_new (TpProxy *conn_or_chan,
const gchar *object_path,
GError **error);
+const GError *tp_tls_certificate_get_rejection (TpTLSCertificate *self,
+ TpTLSCertificateRejectReason *reason,
+ const gchar **dbus_error,
+ const GHashTable **details);
+const GError *tp_tls_certificate_get_nth_rejection (TpTLSCertificate *self,
+ guint n,
+ TpTLSCertificateRejectReason *reason,
+ const gchar **dbus_error,
+ const GHashTable **details);
+
void tp_tls_certificate_accept_async (TpTLSCertificate *self,
GAsyncReadyCallback callback,
gpointer user_data);