const gchar * cockpit_stream_problem (GError *error, const gchar *name, const gchar *summary, GIOStream *io) { const gchar *problem = NULL; gchar *details = NULL; if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) problem = "access-denied"; else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND) || g_error_matches (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND)) problem = "not-found"; else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED) || g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_EOF)) problem = "disconnected"; #if !GLIB_CHECK_VERSION(2,43,2) else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED) && strstr (error->message, g_strerror (ECONNRESET))) problem = "disconnected"; #endif else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) problem = "timeout"; else if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS) || g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_MISC)) problem = "protocol-error"; else if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE)) { problem = "unknown-hostkey"; if (io != NULL) details = describe_certificate_errors (io); } if (problem) { g_message ("%s: %s: %s%s%s", name, summary, error->message, details ? ": " : "", details ? details : ""); } else { g_warning ("%s: %s: %s", name, summary, error->message); problem = "internal-error"; } g_free (details); return problem; }
static void set_problem_from_error (CockpitStream *self, const gchar *summary, GError *error) { const gchar *problem = NULL; gchar *details = NULL; if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) problem = "access-denied"; else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND)) problem = "not-found"; else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED) || g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_EOF) || (self->priv->received && g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_MISC))) problem = "disconnected"; else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) problem = "timeout"; else if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS) || (!self->priv->received && g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_MISC))) problem = "protocol-error"; else if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE)) { problem = "unknown-hostkey"; details = describe_certificate_errors (self); } g_free (self->priv->problem); if (problem) { g_message ("%s: %s: %s%s%s", self->priv->name, summary, error->message, details ? ": " : "", details ? details : ""); self->priv->problem = g_strdup (problem); } else { g_warning ("%s: %s: %s", self->priv->name, summary, error->message); self->priv->problem = g_strdup ("internal-error"); } g_free (details); }
static gboolean on_rejected_certificate (GTlsConnection *conn, GTlsCertificate *peer_cert, GTlsCertificateFlags errors, gpointer user_data) { CockpitStream *self = (CockpitStream *)user_data; gchar *details = describe_certificate_errors (errors); gchar *pem_data = NULL; g_return_val_if_fail (peer_cert != NULL, FALSE); g_message ("%s: Unacceptable TLS certificate: %s", self->priv->name, details); g_object_get (peer_cert, "certificate-pem", &pem_data, NULL); g_signal_emit (self, cockpit_stream_sig_rejected_cert, 0, pem_data); g_free (details); g_free (pem_data); return FALSE; }