<xi:include href="xml/gtlsclientconnection.xml"/>
<xi:include href="xml/gtlsserverconnection.xml"/>
<xi:include href="xml/gtlsbackend.xml"/>
+ <xi:include href="xml/gtlsdatabase.xml"/>
+ <xi:include href="xml/gtlsfiledatabase.xml"/>
+ <xi:include href="xml/gtlsinteraction.xml"/>
+ <xi:include href="xml/gtlspassword.xml"/>
</chapter>
<chapter id="resolver">
<title>DNS resolution</title>
GTlsBackendInterface
g_tls_backend_get_default
g_tls_backend_supports_tls
+g_tls_backend_get_default_database
g_tls_backend_get_certificate_type
g_tls_backend_get_client_connection_type
g_tls_backend_get_server_connection_type
+g_tls_backend_get_file_database_type
<SUBSECTION Standard>
G_IS_TLS_BACKEND
G_TLS_BACKEND
g_tls_connection_get_rehandshake_mode
g_tls_connection_set_use_system_certdb
g_tls_connection_get_use_system_certdb
+g_tls_connection_get_database
+g_tls_connection_set_database
+g_tls_connection_get_interaction
+g_tls_connection_set_interaction
<SUBSECTION>
g_tls_connection_handshake
g_tls_connection_handshake_async
</SECTION>
<SECTION>
+<FILE>gtlsdatabase</FILE>
+<TITLE>GTlsDatabase</TITLE>
+GTlsDatabase
+GTlsDatabaseVerifyFlags
+G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER
+G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT
+g_tls_database_verify_chain
+g_tls_database_verify_chain_async
+g_tls_database_verify_chain_finish
+GTlsDatabaseLookupFlags
+g_tls_database_lookup_certificate_issuer
+g_tls_database_lookup_certificate_issuer_async
+g_tls_database_lookup_certificate_issuer_finish
+g_tls_database_lookup_certificates_issued_by
+g_tls_database_lookup_certificates_issued_by_async
+g_tls_database_lookup_certificates_issued_by_finish
+g_tls_database_create_certificate_handle
+g_tls_database_lookup_certificate_for_handle
+g_tls_database_lookup_certificate_for_handle_async
+g_tls_database_lookup_certificate_for_handle_finish
+<SUBSECTION Standard>
+G_IS_TLS_DATABASE
+G_IS_TLS_DATABASE_CLASS
+G_TLS_DATABASE
+G_TLS_DATABASE_CLASS
+G_TLS_DATABASE_GET_CLASS
+G_TYPE_TLS_DATABASE
+G_TYPE_TLS_DATABASE_LOOKUP_FLAGS
+G_TYPE_TLS_DATABASE_VERIFY_FLAGS
+<SUBSECTION Private>
+g_tls_database_lookup_flags_get_type
+g_tls_database_verify_flags_get_type
+g_tls_database_get_type
+GTlsDatabasePrivate
+</SECTION>
+
+<SECTION>
+<FILE>gtlsfiledatabase</FILE>
+<TITLE>GTlsFileDatabase</TITLE>
+GTlsFileDatabase
+GTlsFileDatabaseInterface
+g_tls_file_database_new
+<SUBSECTION Standard>
+G_TLS_FILE_DATABASE
+G_TLS_FILE_DATABASE_GET_INTERFACE
+G_TYPE_TLS_FILE_DATABASE
+G_IS_TLS_FILE_DATABASE
+<SUBSECTION Private>
+g_tls_file_database_get_type
+</SECTION>
+
+<SECTION>
<FILE>gtlsserverconnection</FILE>
<TITLE>GTlsServerConnection</TITLE>
GTlsServerConnection
</SECTION>
<SECTION>
+<FILE>gtlspassword</FILE>
+<TITLE>GTlsPassword</TITLE>
+GTlsPassword
+GTlsPasswordInterface
+GTlsPasswordFlags
+g_tls_password_new
+g_tls_password_get_value
+g_tls_password_set_value
+g_tls_password_set_value_full
+g_tls_password_get_description
+g_tls_password_set_description
+g_tls_password_get_flags
+g_tls_password_set_flags
+g_tls_password_get_warning
+g_tls_password_set_warning
+<SUBSECTION Standard>
+g_tls_password_flags_get_type
+g_tls_password_get_type
+G_IS_TLS_PASSWORD
+G_TLS_PASSWORD
+G_TLS_PASSWORD_GET_INTERFACE
+G_TYPE_TLS_PASSWORD
+G_TYPE_TLS_PASSWORD_FLAGS
+</SECTION>
+
+<SECTION>
+<FILE>gtlsinteraction</FILE>
+<TITLE>GTlsInteraction</TITLE>
+GTlsInteraction
+GTlsInteractionResult
+g_tls_interaction_ask_password
+g_tls_interaction_ask_password_async
+g_tls_interaction_ask_password_finish
+<SUBSECTION Standard>
+GTlsInteractionClass
+G_IS_TLS_INTERACTION
+G_IS_TLS_INTERACTION_CLASS
+G_TYPE_TLS_INTERACTION
+G_TLS_INTERACTION
+G_TLS_INTERACTION_CLASS
+G_TLS_INTERACTION_GET_CLASS
+G_TYPE_TLS_INTERACTION_RESULT
+<SUBSECTION Private>
+GTlsInteractionPrivate
+g_tls_interaction_get_type
+g_tls_interaction_result_get_type
+GTlsConsoleInteraction
+GTlsConsoleInteractionClass
+G_IS_TLS_CONSOLE_INTERACTION
+G_IS_TLS_CONSOLE_INTERACTION_CLASS
+g_tls_console_interaction_new
+G_TLS_CONSOLE_INTERACTION
+G_TYPE_TLS_CONSOLE_INTERACTION
+G_TLS_CONSOLE_INTERACTION_CLASS
+G_TLS_CONSOLE_INTERACTION_GET_CLASS
+g_tls_console_interaction_get_type
+</SECTION>
+
+<SECTION>
<FILE>gtimezonemonitor</FILE>
<TITLE>GTimeZoneMonitor</TITLE>
GTimeZoneMonitor
g_tls_certificate_get_type
g_tls_client_connection_get_type
g_tls_connection_get_type
+g_tls_database_get_type
+g_tls_file_database_get_type
g_tls_server_connection_get_type
g_unix_connection_get_type
g_unix_fd_list_get_type
gtlscertificate.c \
gtlsclientconnection.c \
gtlsconnection.c \
+ gtlsdatabase.c \
+ gtlsfiledatabase.c \
+ gtlsinteraction.c \
+ gtlspassword.c \
gtlsserverconnection.c \
gunionvolumemonitor.c \
gunionvolumemonitor.h \
gtlscertificate.h \
gtlsclientconnection.h \
gtlsconnection.h \
+ gtlsdatabase.h \
+ gtlsfiledatabase.h \
+ gtlsinteraction.h \
+ gtlspassword.h \
gtlsserverconnection.h \
gvfs.h \
gvolume.h \
#include "gtlsbackend.h"
#include "gtlscertificate.h"
#include "gtlsclientconnection.h"
+#include "gtlsdatabase.h"
+#include "gtlsfiledatabase.h"
#include "gtlsserverconnection.h"
#include "gsimpleasyncresult.h"
static GType _g_dummy_tls_certificate_get_type (void);
static GType _g_dummy_tls_connection_get_type (void);
+static GType _g_dummy_tls_database_get_type (void);
struct _GDummyTlsBackend {
- GObject parent_instance;
+ GObject parent_instance;
+ GTlsDatabase *database;
};
static void g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface);
{
}
+static GTlsDatabase*
+g_dummy_tls_backend_get_default_database (GTlsBackend *backend)
+{
+ return g_object_new (_g_dummy_tls_database_get_type (), NULL);
+}
+
static void
g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface)
{
iface->get_certificate_type = _g_dummy_tls_certificate_get_type;
iface->get_client_connection_type = _g_dummy_tls_connection_get_type;
iface->get_server_connection_type = _g_dummy_tls_connection_get_type;
+ iface->get_file_database_type = _g_dummy_tls_database_get_type;
+ iface->get_default_database = g_dummy_tls_backend_get_default_database;
}
/* Dummy certificate type */
PROP_CONN_REQUIRE_CLOSE_NOTIFY,
PROP_CONN_REHANDSHAKE_MODE,
PROP_CONN_CERTIFICATE,
+ PROP_CONN_DATABASE,
PROP_CONN_PEER_CERTIFICATE,
PROP_CONN_PEER_CERTIFICATE_ERRORS,
PROP_CONN_VALIDATION_FLAGS,
g_object_class_override_property (gobject_class, PROP_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
g_object_class_override_property (gobject_class, PROP_CONN_REHANDSHAKE_MODE, "rehandshake-mode");
g_object_class_override_property (gobject_class, PROP_CONN_CERTIFICATE, "certificate");
+ g_object_class_override_property (gobject_class, PROP_CONN_DATABASE, "database");
g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE, "peer-certificate");
g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
g_object_class_override_property (gobject_class, PROP_CONN_VALIDATION_FLAGS, "validation-flags");
iface->init = g_dummy_tls_connection_initable_init;
}
+/* Dummy database type.
+ */
+
+typedef struct _GDummyTlsDatabase GDummyTlsDatabase;
+typedef struct _GDummyTlsDatabaseClass GDummyTlsDatabaseClass;
+
+struct _GDummyTlsDatabase {
+ GTlsDatabase parent_instance;
+};
+
+struct _GDummyTlsDatabaseClass {
+ GTlsDatabaseClass parent_class;
+};
+
+enum
+{
+ PROP_DATABASE_0,
+
+ PROP_ANCHORS,
+};
+
+static void g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface *iface);
+static void g_dummy_tls_database_initable_iface_init (GInitableIface *iface);
+
+#define g_dummy_tls_database_get_type _g_dummy_tls_database_get_type
+G_DEFINE_TYPE_WITH_CODE (GDummyTlsDatabase, g_dummy_tls_database, G_TYPE_TLS_DATABASE,
+ G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
+ g_dummy_tls_database_file_database_iface_init);
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ g_dummy_tls_database_initable_iface_init);)
+
+
+static void
+g_dummy_tls_database_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ /* We need to define this method to make GObject happy, but it will
+ * never be possible to construct a working GDummyTlsDatabase, so
+ * it doesn't have to do anything useful.
+ */
+}
+
+static void
+g_dummy_tls_database_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ /* Just ignore all attempts to set properties. */
+}
+
+static void
+g_dummy_tls_database_class_init (GDummyTlsDatabaseClass *database_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (database_class);
+
+ gobject_class->get_property = g_dummy_tls_database_get_property;
+ gobject_class->set_property = g_dummy_tls_database_set_property;
+
+ g_object_class_override_property (gobject_class, PROP_ANCHORS, "anchors");
+}
+
+static void
+g_dummy_tls_database_init (GDummyTlsDatabase *database)
+{
+}
+
+static void
+g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface *iface)
+{
+}
+
+static gboolean
+g_dummy_tls_database_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
+ _("TLS support is not available"));
+ return FALSE;
+}
+
+static void
+g_dummy_tls_database_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = g_dummy_tls_database_initable_init;
+}
#include <gio/gtlscertificate.h>
#include <gio/gtlsclientconnection.h>
#include <gio/gtlsconnection.h>
+#include <gio/gtlsdatabase.h>
+#include <gio/gtlsfiledatabase.h>
+#include <gio/gtlsinteraction.h>
#include <gio/gtlsserverconnection.h>
+#include <gio/gtlspassword.h>
#include <gio/gvfs.h>
#include <gio/gvolume.h>
#include <gio/gvolumemonitor.h>
g_tls_certificate_flags_get_type
g_tls_rehandshake_mode_get_type
g_emblemed_icon_get_type
+g_tls_database_verify_flags_get_type
g_emblemed_icon_new
g_emblemed_icon_get_icon
g_emblemed_icon_get_emblems
g_tls_certificate_verify
g_tls_connection_emit_accept_certificate
g_tls_connection_get_certificate
+g_tls_connection_get_interaction
g_tls_connection_get_peer_certificate
g_tls_connection_get_peer_certificate_errors
g_tls_connection_get_rehandshake_mode
g_tls_connection_handshake_async
g_tls_connection_handshake_finish
g_tls_connection_set_certificate
+g_tls_connection_set_interaction
g_tls_connection_set_rehandshake_mode
g_tls_connection_set_require_close_notify
g_tls_connection_set_use_system_certdb
g_tls_client_connection_set_validation_flags
g_tls_server_connection_get_type
g_tls_server_connection_new
+g_tls_database_get_type
+g_tls_database_lookup_issuer
+g_tls_database_lookup_issuer_async
+g_tls_database_lookup_issuer_finish
+g_tls_database_verify_chain
+g_tls_database_verify_chain_async
+g_tls_database_verify_chain_finish
+g_tls_file_database_get_type
+g_tls_file_database_new
+g_tls_interaction_get_type
+g_tls_interaction_ask_password
+g_tls_interaction_ask_password_finish
+g_tls_password_get_type
+g_tls_password_get_value
+g_tls_password_set_value
+g_tls_password_take_value
+g_tls_password_get_flags
+g_tls_password_get_description
g_time_zone_monitor_get_type
g_time_zone_monitor_get
g_dbus_interface_get_info
} GTlsRehandshakeMode;
/**
+ * GTlsPasswordFlags:
+ * @G_TLS_PASSWORD_NONE: No flags
+ * @G_TLS_PASSWORD_RETRY: The password was wrong, and the user should retry.
+ * @G_TLS_PASSWORD_MANY_TRIES: Hint to the user that the password has been
+ * wrong many times, and the user may not have many chances left.
+ * @G_TLS_PASSWORD_FINAL_TRY: Hint to the user that this is the last try to get
+ * this password right.
+ *
+ * Various flags for the password.
+ *
+ * Since: 2.30
+ */
+
+typedef enum _GTlsPasswordFlags
+{
+ G_TLS_PASSWORD_NONE = 0,
+ G_TLS_PASSWORD_RETRY = 1 << 1,
+ G_TLS_PASSWORD_MANY_TRIES = 1 << 2,
+ G_TLS_PASSWORD_FINAL_TRY = 1 << 3
+} GTlsPasswordFlags;
+
+/**
+ * GTlsInteractionResult:
+ * @G_TLS_INTERACTION_HANDLED: The interaction completed, and resulting data
+ * is available.
+ * @G_TLS_INTERACTION_ABORTED: The user cancelled the interaction, and requested
+ * the operation to be aborted.
+ * @G_TLS_INTERACTION_UNHANDLED: The interaction was unhandled (i.e. not
+ * implemented).
+ *
+ * #GTlsInteractionResult is returned by various functions in #GTlsInteraction
+ * when finishing an interaction request.
+ *
+ * Since: 2.30
+ */
+typedef enum {
+ G_TLS_INTERACTION_HANDLED,
+ G_TLS_INTERACTION_ABORTED,
+ G_TLS_INTERACTION_UNHANDLED
+} GTlsInteractionResult;
+
+/**
* GDBusInterfaceSkeletonFlags:
* @G_DBUS_INTERFACE_SKELETON_FLAGS_NONE: No flags set.
* @G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD: Each method invocation is handled in
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START = (1<<0)
} GDBusObjectManagerClientFlags;
+/**
+ * GTlsDatabaseVerifyFlags:
+ * @G_TLS_DATABASE_VERIFY_NONE: No verification flags
+ *
+ * Flags for g_tls_database_verify_chain().
+ *
+ * Since: 2.30
+ */
+typedef enum {
+ G_TLS_DATABASE_VERIFY_NONE = 0,
+} GTlsDatabaseVerifyFlags;
+
+/**
+ * GTlsDatabaseLookupFlags:
+ * @G_TLS_DATABASE_LOOKUP_NONE: No lookup flags
+ * @G_TLS_DATABASE_LOOKUP_KEYPAIR: Restrict lookup to certificates that have
+ * a private key.
+ *
+ * Flags for g_tls_database_lookup_handle(), g_tls_database_lookup_issuer(),
+ * and g_tls_database_lookup_issued().
+ *
+ * Since: 2.30
+ */
+typedef enum {
+ G_TLS_DATABASE_LOOKUP_NONE = 0,
+ G_TLS_DATABASE_LOOKUP_KEYPAIR = 1,
+} GTlsDatabaseLookupFlags;
+
G_END_DECLS
#endif /* __GIO_ENUMS_H__ */
typedef struct _GTlsCertificate GTlsCertificate;
typedef struct _GTlsClientConnection GTlsClientConnection; /* Dummy typedef */
typedef struct _GTlsConnection GTlsConnection;
+typedef struct _GTlsDatabase GTlsDatabase;
+typedef struct _GTlsFileDatabase GTlsFileDatabase;
+typedef struct _GTlsInteraction GTlsInteraction;
+typedef struct _GTlsPassword GTlsPassword;
typedef struct _GTlsServerConnection GTlsServerConnection; /* Dummy typedef */
typedef struct _GVfs GVfs; /* Dummy typedef */
}
/**
+ * g_tls_backend_get_default_database:
+ * @backend: the #GTlsBackend
+ *
+ * Gets the default #GTlsDatabase used to verify TLS connections.
+ *
+ * Return value: the default database, which should be unreffed when done.
+ *
+ * Since: 2.30
+ */
+GTlsDatabase *
+g_tls_backend_get_default_database (GTlsBackend *backend)
+{
+ g_return_val_if_fail (G_IS_TLS_BACKEND (backend), NULL);
+
+ /* This method was added later, so accept the (remote) possibility it can be NULL */
+ if (!G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database)
+ return NULL;
+
+ return G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database (backend);
+}
+
+/**
* g_tls_backend_get_certificate_type:
* @backend: the #GTlsBackend
*
{
return G_TLS_BACKEND_GET_INTERFACE (backend)->get_server_connection_type ();
}
+
+/**
+ * g_tls_backend_get_file_database_type:
+ * @backend: the #GTlsBackend
+ *
+ * Gets the #GTyep of @backend's #GTlsFileDatabase implementation.
+ *
+ * Return value: the #GType of backend's #GTlsFileDatabase implementation.
+ *
+ * Since: 2.30
+ */
+GType
+g_tls_backend_get_file_database_type (GTlsBackend *backend)
+{
+ g_return_val_if_fail (G_IS_TLS_BACKEND (backend), 0);
+
+ /* This method was added later, so accept the (remote) possibility it can be NULL */
+ if (!G_TLS_BACKEND_GET_INTERFACE (backend)->get_file_database_type)
+ return 0;
+
+ return G_TLS_BACKEND_GET_INTERFACE (backend)->get_file_database_type ();
+}
/**
* GTlsBackendInterface:
* @g_iface: The parent interface.
+ * @supports_tls: returns whether the backend supports TLS.
+ * @get_default_database: returns a default #GTlsDatabase instance.
* @get_certificate_type: returns the #GTlsCertificate implementation type
* @get_client_connection_type: returns the #GTlsClientConnection implementation type
* @get_server_connection_type: returns the #GTlsServerConnection implementation type
+ * @get_file_database_type: returns the #GTlsFileDatabase implementation type.
*
* Provides an interface for describing TLS-related types.
*
GTypeInterface g_iface;
/* methods */
- gboolean ( *supports_tls) (GTlsBackend *backend);
- GType ( *get_certificate_type) (void);
- GType ( *get_client_connection_type) (void);
- GType ( *get_server_connection_type) (void);
+ gboolean ( *supports_tls) (GTlsBackend *backend);
+ GType ( *get_certificate_type) (void);
+ GType ( *get_client_connection_type) (void);
+ GType ( *get_server_connection_type) (void);
+ GType ( *get_file_database_type) (void);
+ GTlsDatabase * ( *get_default_database) (GTlsBackend *backend);
};
-GType g_tls_backend_get_type (void) G_GNUC_CONST;
+GType g_tls_backend_get_type (void) G_GNUC_CONST;
-GTlsBackend *g_tls_backend_get_default (void);
+GTlsBackend * g_tls_backend_get_default (void);
-gboolean g_tls_backend_supports_tls (GTlsBackend *backend);
+GTlsDatabase * g_tls_backend_get_default_database (GTlsBackend *backend);
-GType g_tls_backend_get_certificate_type (GTlsBackend *backend);
-GType g_tls_backend_get_client_connection_type (GTlsBackend *backend);
-GType g_tls_backend_get_server_connection_type (GTlsBackend *backend);
+gboolean g_tls_backend_supports_tls (GTlsBackend *backend);
+
+GType g_tls_backend_get_certificate_type (GTlsBackend *backend);
+GType g_tls_backend_get_client_connection_type (GTlsBackend *backend);
+GType g_tls_backend_get_server_connection_type (GTlsBackend *backend);
+GType g_tls_backend_get_file_database_type (GTlsBackend *backend);
G_END_DECLS
#include "gtlsbackend.h"
#include "gtlscertificate.h"
#include "gtlsclientconnection.h"
+#include "gtlsdatabase.h"
+#include "gtlsinteraction.h"
#include "glibintl.h"
/**
PROP_REQUIRE_CLOSE_NOTIFY,
PROP_REHANDSHAKE_MODE,
PROP_USE_SYSTEM_CERTDB,
+ PROP_DATABASE,
+ PROP_INTERACTION,
PROP_CERTIFICATE,
PROP_PEER_CERTIFICATE,
PROP_PEER_CERTIFICATE_ERRORS
* verify peer certificates. See
* g_tls_connection_set_use_system_certdb().
*
- * Since: 2.28
+ * Deprecated: 2.30: Use GTlsConnection:database instead
*/
g_object_class_install_property (gobject_class, PROP_USE_SYSTEM_CERTDB,
g_param_spec_boolean ("use-system-certdb",
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
+ * GTlsConnection:database:
+ *
+ * The certificate database to use when verifying this TLS connection.
+ * If no cerificate database is set, then the default database will be
+ * used. See g_tls_backend_get_default_database().
+ *
+ * Since: 2.30
+ */
+ g_object_class_install_property (gobject_class, PROP_DATABASE,
+ g_param_spec_object ("database",
+ P_("Database"),
+ P_("Certificate database to use for looking up or verifying certificates"),
+ G_TYPE_TLS_DATABASE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ /**
+ * GTlsConnection:interaction:
+ *
+ * A #GTlsInteraction object to be used when the connection or certificate
+ * database need to interact with the user. This will be used to prompt the
+ * user for passwords where necessary.
+ *
+ * Since: 2.30
+ */
+ g_object_class_install_property (gobject_class, PROP_INTERACTION,
+ g_param_spec_object ("interaction",
+ P_("Interaction"),
+ P_("Optional object for user interaction"),
+ G_TYPE_TLS_INTERACTION,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ /**
* GTlsConnection:require-close-notify:
*
* Whether or not proper TLS close notification is required.
* client-side connections, unless that bit is not set in
* #GTlsClientConnection:validation-flags).
*
- * Since: 2.28
+ * Deprecated: 2.30: Use g_tls_connection_set_database() instead
*/
void
g_tls_connection_set_use_system_certdb (GTlsConnection *conn,
*
* Return value: whether @conn uses the system certificate database
*
- * Since: 2.28
+ * Deprecated: 2.30: Use g_tls_connection_get_database() instead
*/
gboolean
g_tls_connection_get_use_system_certdb (GTlsConnection *conn)
}
/**
+ * g_tls_connection_set_database:
+ * @conn: a #GTlsConnection
+ * @database: a #GTlsDatabase
+ *
+ * Sets the certificate database that is used to verify peer certificates.
+ * This is set to the default database by default. See
+ * g_tls_backend_get_default_database(). If set to %NULL, then
+ * peer certificate validation will always set the
+ * %G_TLS_CERTIFICATE_UNKNOWN_CA error (meaning
+ * #GTlsConnection::accept-certificate will always be emitted on
+ * client-side connections, unless that bit is not set in
+ * #GTlsClientConnection:validation-flags).
+ *
+ * Since: 2.30
+ */
+void
+g_tls_connection_set_database (GTlsConnection *conn,
+ GTlsDatabase *database)
+{
+ g_return_if_fail (G_IS_TLS_CONNECTION (conn));
+ g_return_if_fail (database == NULL || G_IS_TLS_DATABASE (database));
+
+ g_object_set (G_OBJECT (conn),
+ "database", database,
+ NULL);
+}
+
+/**
+ * g_tls_connection_get_database:
+ * @conn: a #GTlsConnection
+ *
+ * Gets the certificate database that @conn uses to verify
+ * peer certificates. See g_tls_connection_set_database().
+ *
+ * Return value: the certificate database that @conn uses or %NULL
+ *
+ * Since: 2.30
+ */
+GTlsDatabase*
+g_tls_connection_get_database (GTlsConnection *conn)
+{
+ GTlsDatabase *database = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
+
+ g_object_get (G_OBJECT (conn),
+ "database", &database,
+ NULL);
+ if (database)
+ g_object_unref (database);
+ return database;
+}
+
+/**
* g_tls_connection_set_certificate:
* @conn: a #GTlsConnection
* @certificate: the certificate to use for @conn
}
/**
+ * g_tls_connection_set_interaction:
+ * @conn: a connection
+ * @interaction: (allow-none): an interaction object, or %NULL
+ *
+ * Set the object that will be used to interact with the user. It will be used
+ * for things like prompting the user for passwords.
+ *
+ * The @interaction argument will normally be a derived subclass of
+ * #GTlsInteraction. %NULL can also be provided if no user interaction
+ * should occur for this connection.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_connection_set_interaction (GTlsConnection *conn,
+ GTlsInteraction *interaction)
+{
+ g_return_if_fail (G_IS_TLS_CONNECTION (conn));
+ g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+
+ g_object_set (G_OBJECT (conn), "interaction", interaction, NULL);
+}
+
+/**
+ * g_tls_connection_get_interaction:
+ * @conn: a connection
+ *
+ * Get the object that will be used to interact with the user. It will be used
+ * for things like prompting the user for passwords. If %NULL is returned, then
+ * no user interaction will occur for this connection.
+ *
+ * Returns: (transfer none): The interaction object.
+ *
+ * Since: 2.30
+ */
+GTlsInteraction *
+g_tls_connection_get_interaction (GTlsConnection *conn)
+{
+ GTlsInteraction *interaction = NULL;
+
+ g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
+
+ g_object_get (G_OBJECT (conn), "interaction", &interaction, NULL);
+ if (interaction)
+ g_object_unref (interaction);
+
+ return interaction;
+}
+
+/**
* g_tls_connection_get_peer_certificate:
* @conn: a #GTlsConnection
*
GType g_tls_connection_get_type (void) G_GNUC_CONST;
+#ifndef G_DISABLE_DEPRECATED
void g_tls_connection_set_use_system_certdb (GTlsConnection *conn,
gboolean use_system_certdb);
gboolean g_tls_connection_get_use_system_certdb (GTlsConnection *conn);
+#endif /* G_DISABLE_DEPRECATED */
+
+void g_tls_connection_set_database (GTlsConnection *conn,
+ GTlsDatabase *database);
+GTlsDatabase * g_tls_connection_get_database (GTlsConnection *conn);
void g_tls_connection_set_certificate (GTlsConnection *conn,
- GTlsCertificate *certificate);
+ GTlsCertificate *certificate);
GTlsCertificate *g_tls_connection_get_certificate (GTlsConnection *conn);
+void g_tls_connection_set_interaction (GTlsConnection *conn,
+ GTlsInteraction *interaction);
+GTlsInteraction * g_tls_connection_get_interaction (GTlsConnection *conn);
+
GTlsCertificate *g_tls_connection_get_peer_certificate (GTlsConnection *conn);
GTlsCertificateFlags g_tls_connection_get_peer_certificate_errors (GTlsConnection *conn);
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gtlsdatabase.h"
+
+#include "gasyncresult.h"
+#include "gcancellable.h"
+#include "glibintl.h"
+#include "gsimpleasyncresult.h"
+#include "gsocketconnectable.h"
+#include "gtlscertificate.h"
+#include "gtlsinteraction.h"
+
+/**
+ * SECTION:gtlsdatabase
+ * @short_description: TLS database type
+ * @include: gio/gio.h
+ *
+ * #GTlsDatabase is used to lookup certificates and other information
+ * from a certificate or key store. It is an abstract base class which
+ * TLS library specific subtypes override.
+ *
+ * Most common client applications will not directly interact with
+ * #GTlsDatabase. It is used internally by #GTlsConnection.
+ *
+ * Since: 2.30
+ */
+
+/**
+ * GTlsDatabase:
+ *
+ * Abstract base class for the backend-specific database types.
+ *
+ * Since: 2.30
+ */
+
+G_DEFINE_ABSTRACT_TYPE (GTlsDatabase, g_tls_database, G_TYPE_OBJECT);
+
+enum {
+ UNLOCK_REQUIRED,
+
+ LAST_SIGNAL
+};
+
+/**
+ * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER:
+ *
+ * The purpose used to verify the server certificate in a TLS connection. This
+ * is the most common purpose in use. Used by TLS clients.
+ */
+
+/**
+ * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT:
+ *
+ * The purpose used to verify the client certificate in a TLS connection.
+ * Used by TLS servers.
+ */
+
+static void
+g_tls_database_init (GTlsDatabase *cert)
+{
+
+}
+
+typedef struct _AsyncVerifyChain {
+ GTlsCertificate *chain;
+ gchar *purpose;
+ GSocketConnectable *identity;
+ GTlsInteraction *interaction;
+ GTlsDatabaseVerifyFlags flags;
+ GTlsCertificateFlags verify_result;
+} AsyncVerifyChain;
+
+static void
+async_verify_chain_free (gpointer data)
+{
+ AsyncVerifyChain *args = data;
+ g_clear_object (&args->chain);
+ g_free (args->purpose);
+ g_clear_object (&args->identity);
+ g_clear_object (&args->interaction);
+ g_slice_free (AsyncVerifyChain, args);
+}
+
+static void
+async_verify_chain_thread (GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncVerifyChain *args = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+
+ args->verify_result = g_tls_database_verify_chain (G_TLS_DATABASE (object),
+ args->chain,
+ args->purpose,
+ args->identity,
+ args->interaction,
+ args->flags,
+ cancellable,
+ &error);
+
+ if (error)
+ g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_verify_chain_async (GTlsDatabase *self,
+ GTlsCertificate *chain,
+ const gchar *purpose,
+ GSocketConnectable *identity,
+ GTlsInteraction *interaction,
+ GTlsDatabaseVerifyFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ AsyncVerifyChain *args;
+
+ args = g_slice_new0 (AsyncVerifyChain);
+ args->chain = g_object_ref (chain);
+ args->purpose = g_strdup (purpose);
+ args->identity = identity ? g_object_ref (identity) : NULL;
+ args->interaction = interaction ? g_object_ref (interaction) : NULL;
+ args->flags = flags;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ g_tls_database_real_verify_chain_async);
+ g_simple_async_result_set_op_res_gpointer (res, args, async_verify_chain_free);
+ g_simple_async_result_run_in_thread (res, async_verify_chain_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+ g_object_unref (res);
+}
+
+static GTlsCertificateFlags
+g_tls_database_real_verify_chain_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ AsyncVerifyChain *args;
+
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ g_tls_database_real_verify_chain_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return G_TLS_CERTIFICATE_GENERIC_ERROR;
+
+ args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ return args->verify_result;
+}
+
+typedef struct {
+ gchar *handle;
+ GTlsInteraction *interaction;
+ GTlsDatabaseLookupFlags flags;
+ GTlsCertificate *result;
+} AsyncLookupCertificateForHandle;
+
+static void
+async_lookup_certificate_for_handle_free (gpointer data)
+{
+ AsyncLookupCertificateForHandle *args = data;
+
+ g_free (args->handle);
+ g_clear_object (&args->interaction);
+ g_clear_object (&args->result);
+ g_slice_free (AsyncLookupCertificateForHandle, args);
+}
+
+static void
+async_lookup_certificate_for_handle_thread (GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncLookupCertificateForHandle *args = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+
+ args->result = g_tls_database_lookup_certificate_for_handle (G_TLS_DATABASE (object),
+ args->handle,
+ args->interaction,
+ args->flags,
+ cancellable,
+ &error);
+
+ if (error)
+ g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_lookup_certificate_for_handle_async (GTlsDatabase *self,
+ const gchar *handle,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ AsyncLookupCertificateForHandle *args;
+
+ g_return_if_fail (callback != NULL);
+
+ args = g_slice_new0 (AsyncLookupCertificateForHandle);
+ args->handle = g_strdup (handle);
+ args->interaction = interaction ? g_object_ref (interaction) : NULL;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ g_tls_database_real_lookup_certificate_for_handle_async);
+ g_simple_async_result_set_op_res_gpointer (res, args, async_lookup_certificate_for_handle_free);
+ g_simple_async_result_run_in_thread (res, async_lookup_certificate_for_handle_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+ g_object_unref (res);
+}
+
+static GTlsCertificate*
+g_tls_database_real_lookup_certificate_for_handle_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ AsyncLookupCertificateForHandle *args;
+ GTlsCertificate *certificate;
+
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ g_tls_database_real_lookup_certificate_for_handle_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+
+ args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ certificate = args->result;
+ args->result = NULL;
+ return certificate;
+}
+
+
+typedef struct {
+ GTlsCertificate *certificate;
+ GTlsInteraction *interaction;
+ GTlsDatabaseLookupFlags flags;
+ GTlsCertificate *issuer;
+} AsyncLookupCertificateIssuer;
+
+static void
+async_lookup_certificate_issuer_free (gpointer data)
+{
+ AsyncLookupCertificateIssuer *args = data;
+
+ g_clear_object (&args->certificate);
+ g_clear_object (&args->interaction);
+ g_clear_object (&args->issuer);
+ g_slice_free (AsyncLookupCertificateIssuer, args);
+}
+
+static void
+async_lookup_certificate_issuer_thread (GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncLookupCertificateIssuer *args = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+
+ args->issuer = g_tls_database_lookup_certificate_issuer (G_TLS_DATABASE (object),
+ args->certificate,
+ args->interaction,
+ args->flags,
+ cancellable,
+ &error);
+
+ if (error)
+ g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_lookup_certificate_issuer_async (GTlsDatabase *self,
+ GTlsCertificate *certificate,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ AsyncLookupCertificateIssuer *args;
+
+ g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate));
+ g_return_if_fail (callback != NULL);
+
+ args = g_slice_new0 (AsyncLookupCertificateIssuer);
+ args->certificate = g_object_ref (certificate);
+ args->flags = flags;
+ args->interaction = interaction ? g_object_ref (interaction) : NULL;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ g_tls_database_real_lookup_certificate_issuer_async);
+ g_simple_async_result_set_op_res_gpointer (res, args, async_lookup_certificate_issuer_free);
+ g_simple_async_result_run_in_thread (res, async_lookup_certificate_issuer_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+ g_object_unref (res);
+}
+
+static GTlsCertificate*
+g_tls_database_real_lookup_certificate_issuer_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ AsyncLookupCertificateIssuer *args;
+ GTlsCertificate *issuer;
+
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ g_tls_database_real_lookup_certificate_issuer_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+
+ args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ issuer = args->issuer;
+ args->issuer = NULL;
+ return issuer;
+}
+
+typedef struct {
+ GByteArray *issuer;
+ GTlsInteraction *interaction;
+ GTlsDatabaseLookupFlags flags;
+ GList *results;
+} AsyncLookupCertificatesIssuedBy;
+
+static void
+async_lookup_certificates_issued_by_free (gpointer data)
+{
+ AsyncLookupCertificatesIssuedBy *args = data;
+ GList *l;
+
+ g_byte_array_unref (args->issuer);
+ g_clear_object (&args->interaction);
+ for (l = args->results; l; l = g_list_next (l))
+ g_object_unref (l->data);
+ g_list_free (args->results);
+ g_slice_free (AsyncLookupCertificatesIssuedBy, args);
+}
+
+static void
+async_lookup_certificates_issued_by_thread (GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncLookupCertificatesIssuedBy *args = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+
+ args->results = g_tls_database_lookup_certificates_issued_by (G_TLS_DATABASE (object),
+ args->issuer,
+ args->interaction,
+ args->flags,
+ cancellable,
+ &error);
+
+ if (error)
+ g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_lookup_certificates_issued_by_async (GTlsDatabase *self,
+ GByteArray *issuer,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ AsyncLookupCertificatesIssuedBy *args;
+
+ g_return_if_fail (callback);
+
+ args = g_slice_new0 (AsyncLookupCertificatesIssuedBy);
+ args->issuer = g_byte_array_ref (issuer);
+ args->flags = flags;
+ args->interaction = interaction ? g_object_ref (interaction) : NULL;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ g_tls_database_real_lookup_certificates_issued_by_async);
+ g_simple_async_result_set_op_res_gpointer (res, args, async_lookup_certificates_issued_by_free);
+ g_simple_async_result_run_in_thread (res, async_lookup_certificates_issued_by_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+ g_object_unref (res);
+}
+
+static GList*
+g_tls_database_real_lookup_certificates_issued_by_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ AsyncLookupCertificatesIssuedBy *args;
+ GList *results;
+
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ g_tls_database_real_lookup_certificates_issued_by_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+
+ args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ results = args->results;
+ args->results = NULL;
+ return results;
+}
+
+static void
+g_tls_database_class_init (GTlsDatabaseClass *klass)
+{
+ klass->verify_chain_async = g_tls_database_real_verify_chain_async;
+ klass->verify_chain_finish = g_tls_database_real_verify_chain_finish;
+ klass->lookup_certificate_for_handle_async = g_tls_database_real_lookup_certificate_for_handle_async;
+ klass->lookup_certificate_for_handle_finish = g_tls_database_real_lookup_certificate_for_handle_finish;
+ klass->lookup_certificate_issuer_async = g_tls_database_real_lookup_certificate_issuer_async;
+ klass->lookup_certificate_issuer_finish = g_tls_database_real_lookup_certificate_issuer_finish;
+ klass->lookup_certificates_issued_by_async = g_tls_database_real_lookup_certificates_issued_by_async;
+ klass->lookup_certificates_issued_by_finish = g_tls_database_real_lookup_certificates_issued_by_finish;
+}
+
+/**
+ * g_tls_database_verify_chain:
+ * @self: a #GTlsDatabase
+ * @chain: a #GTlsCertificate chain
+ * @purpose: the purpose that this certificate chain will be used for.
+ * @identity: (allow-none): the expected peer identity
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: additional verify flags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Verify's a certificate chain after looking up and adding any missing
+ * certificates to the chain.
+ *
+ * @chain is a chain of #GTlsCertificate objects each pointing to the next
+ * certificate in the chain by its %issuer property. The chain may initially
+ * consist of one or more certificates. After the verification process is
+ * complete, @chain may be modified by adding missing certificates, or removing
+ * extra certificates. If a certificate anchor was found, then it is added to
+ * the @chain.
+ *
+ * @purpose describes the purpose (or usage) for which the certificate
+ * is being used. Typically @purpose will be set to #G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER
+ * which means that the certificate is being used to authenticate a server
+ * (and we are acting as the client).
+ *
+ * The @identity is used to check for pinned certificates (trust exceptions)
+ * in the database. These will override the normal verification process on a
+ * host by host basis.
+ *
+ * Currently there are no @flags, and %G_TLS_DATABASE_VERIFY_NONE should be
+ * used.
+ *
+ * This function can block, use g_tls_database_verify_chain_async() to perform
+ * the verification operation asynchronously.
+ *
+ * Return value: the appropriate #GTlsCertificateFlags which represents the
+ * result of verification.
+ *
+ * Since: 2.30
+ */
+GTlsCertificateFlags
+g_tls_database_verify_chain (GTlsDatabase *self,
+ GTlsCertificate *chain,
+ const gchar *purpose,
+ GSocketConnectable *identity,
+ GTlsInteraction *interaction,
+ GTlsDatabaseVerifyFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self),
+ G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (chain),
+ G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (purpose, G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction),
+ G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity),
+ G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR);
+
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain,
+ G_TLS_CERTIFICATE_GENERIC_ERROR);
+
+ return G_TLS_DATABASE_GET_CLASS (self)->verify_chain (self,
+ chain,
+ purpose,
+ identity,
+ interaction,
+ flags,
+ cancellable,
+ error);
+}
+
+/**
+ * g_tls_database_verify_chain_async:
+ * @self: a #GTlsDatabase
+ * @chain: a #GTlsCertificate chain
+ * @purpose: the purpose that this certificate chain will be used for.
+ * @identity: (allow-none): the expected peer identity
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: additional verify flags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously verify's a certificate chain after looking up and adding
+ * any missing certificates to the chain. See g_tls_database_verify_chain()
+ * for more information.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_verify_chain_async (GTlsDatabase *self,
+ GTlsCertificate *chain,
+ const gchar *purpose,
+ GSocketConnectable *identity,
+ GTlsInteraction *interaction,
+ GTlsDatabaseVerifyFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (G_IS_TLS_DATABASE (self));
+ g_return_if_fail (G_IS_TLS_CERTIFICATE (chain));
+ g_return_if_fail (purpose != NULL);
+ g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity));
+ g_return_if_fail (callback != NULL);
+
+ g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async);
+ G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async (self,
+ chain,
+ purpose,
+ identity,
+ interaction,
+ flags,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * g_tls_database_verify_chain_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous verify chain operation. See
+ * g_tls_database_verify_chain() for more information. *
+ * Return value: the appropriate #GTlsCertificateFlags which represents the
+ * result of verification.
+ *
+ * Since: 2.30
+ */
+GTlsCertificateFlags
+g_tls_database_verify_chain_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish,
+ G_TLS_CERTIFICATE_GENERIC_ERROR);
+ return G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish (self,
+ result,
+ error);
+}
+
+/**
+ * g_tls_database_create_certificate_handle:
+ * @self: a #GTlsDatabase
+ * @certificate: certificate for which to create a handle.
+ *
+ * Create a handle string for the certificate. The database will only be able
+ * to create a handle for certificates that originate from the database. In
+ * cases where the database cannot create a handle for a certificate, %NULL
+ * will be returned.
+ *
+ * This handle should be stable across various instances of the application,
+ * and between applications. If a certificate is modified in the database,
+ * then it is not guaranteed that this handle will continue to point to it.
+ *
+ * Returns: (allow-none): a newly allocated string containing the handle.
+ * Since: 2.30
+ */
+gchar*
+g_tls_database_create_certificate_handle (GTlsDatabase *self,
+ GTlsCertificate *certificate)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle, NULL);
+ return G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle (self,
+ certificate);
+}
+
+/**
+ * g_tls_database_lookup_certificate_for_handle:
+ * @self: a #GTlsDatabase
+ * @handle: a certificate handle
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Lookup a certificate by its handle.
+ *
+ * The handle should have been created by calling g_tls_database_create_handle()
+ * on a #GTlsDatabase object of the same TLS backend. The handle is designed
+ * to remain valid across instantiations of the database.
+ *
+ * If the handle is no longer valid, or does not point to a certificate in
+ * this database, then %NULL will be returned.
+ *
+ * This function can block, use g_tls_database_lookup_certificate_for_handle_async() to perform
+ * the lookup operation asynchronously.
+ *
+ * Return value: (transfer full) (allow-none): a newly allocated
+ * #GTlsCertificate, or %NULL. Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_for_handle (GTlsDatabase *self,
+ const gchar *handle,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+ g_return_val_if_fail (handle != NULL, NULL);
+ g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle, NULL);
+ return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle (self,
+ handle,
+ interaction,
+ flags,
+ cancellable,
+ error);
+}
+
+
+/**
+ * g_tls_database_lookup_certificate_for_handle_async:
+ * @self: a #GTlsDatabase
+ * @handle: a certificate handle
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously lookup a certificate by its handle in the database. See
+ * g_tls_database_lookup_handle() for more information.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase *self,
+ const gchar *handle,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (G_IS_TLS_DATABASE (self));
+ g_return_if_fail (handle != NULL);
+ g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async);
+ return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async (self,
+ handle,
+ interaction,
+ flags,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * g_tls_database_lookup_certificate_for_handle_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous lookup of a certificate by its handle. See
+ * g_tls_database_lookup_handle() for more information.
+ *
+ * If the handle is no longer valid, or does not point to a certificate in
+ * this database, then %NULL will be returned.
+ *
+ * Return value: (transfer full): a newly allocated #GTlsCertificate object.
+ * Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_for_handle_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish, NULL);
+ return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish (self,
+ result,
+ error);
+}
+
+/**
+ * g_tls_database_lookup_certificate_issuer:
+ * @self: a #GTlsDatabase
+ * @certificate: a #GTlsCertificate
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: flags which affect the lookup operation
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Lookup the issuer of @certificate in the database.
+ *
+ * The %issuer property
+ * of @certificate is not modified, and the two certificates are not hooked
+ * into a chain.
+ *
+ * This function can block, use g_tls_database_lookup_certificate_issuer_async() to perform
+ * the lookup operation asynchronously.
+ *
+ * Return value: (transfer full): a newly allocated issuer #GTlsCertificate,
+ * or %NULL. Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_issuer (GTlsDatabase *self,
+ GTlsCertificate *certificate,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+ g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
+ g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer, NULL);
+ return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer (self,
+ certificate,
+ interaction,
+ flags,
+ cancellable,
+ error);
+}
+
+/**
+ * g_tls_database_lookup_certificate_issuer_async:
+ * @self: a #GTlsDatabase
+ * @certificate: a #GTlsCertificate
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: flags which affect the lookup operation
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously lookup the issuer of @certificate in the database. See
+ * g_tls_database_lookup_certificate_issuer() for more information.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_lookup_certificate_issuer_async (GTlsDatabase *self,
+ GTlsCertificate *certificate,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (G_IS_TLS_DATABASE (self));
+ g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate));
+ g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async);
+ G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async (self,
+ certificate,
+ interaction,
+ flags,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * g_tls_database_lookup_certificate_issuer_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous lookup issuer operation. See
+ * g_tls_database_lookup_certificate_issuer() for more information.
+ *
+ * Return value: (transfer full): a newly allocated issuer #GTlsCertificate,
+ * or %NULL. Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_issuer_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish, NULL);
+ return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish (self,
+ result,
+ error);
+}
+
+/**
+ * g_tls_database_lookup_certificates_issued_by:
+ * @self: a #GTlsDatabase
+ * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN.
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup operation.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Lookup certificates issued by this issuer in the database.
+ *
+ * This function can block, use g_tls_database_lookup_certificates_issued_by_async() to perform
+ * the lookup operation asynchronously.
+ *
+ * Return value: (transfer full): a newly allocated list of #GTlsCertificate objects.
+ * Use g_object_unref() on each certificate, and g_list_free() on the release the list.
+ *
+ * Since: 2.30
+ */
+GList*
+g_tls_database_lookup_certificates_issued_by (GTlsDatabase *self,
+ GByteArray *issuer_raw_dn,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+ g_return_val_if_fail (issuer_raw_dn, NULL);
+ g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by, NULL);
+ return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by (self,
+ issuer_raw_dn,
+ interaction,
+ flags,
+ cancellable,
+ error);
+}
+
+/**
+ * g_tls_database_lookup_certificates_issued_by_async:
+ * @self: a #GTlsDatabase
+ * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN.
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup operation.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously lookup certificates issued by this issuer in the database. See
+ * g_tls_database_lookup_certificates_issued_by() for more information.
+ *
+ * The database may choose to hold a reference to the issuer byte array for the duration
+ * of of this asynchronous operation. The byte array should not be modified during
+ * this time.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_lookup_certificates_issued_by_async (GTlsDatabase *self,
+ GByteArray *issuer_raw_dn,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (G_IS_TLS_DATABASE (self));
+ g_return_if_fail (issuer_raw_dn != NULL);
+ g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async);
+ G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async (self,
+ issuer_raw_dn,
+ interaction,
+ flags,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * g_tls_database_lookup_certificates_issued_by_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous lookup of certificates. See
+ * g_tls_database_lookup_certificates_issued_by() for more information.
+ *
+ * Return value: (transfer full): a newly allocated list of #GTlsCertificate objects.
+ * Use g_object_unref() on each certificate, and g_list_free() on the release the list.
+ *
+ * Since: 2.30
+ */
+GList*
+g_tls_database_lookup_certificates_issued_by_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish, NULL);
+ return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish (self,
+ result,
+ error);
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_DATABASE_H__
+#define __G_TLS_DATABASE_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER "1.3.6.1.5.5.7.3.1"
+#define G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT "1.3.6.1.5.5.7.3.2"
+
+#define G_TYPE_TLS_DATABASE (g_tls_database_get_type ())
+#define G_TLS_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_DATABASE, GTlsDatabase))
+#define G_TLS_DATABASE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_TLS_DATABASE, GTlsDatabaseClass))
+#define G_IS_TLS_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_DATABASE))
+#define G_IS_TLS_DATABASE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_TLS_DATABASE))
+#define G_TLS_DATABASE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), G_TYPE_TLS_DATABASE, GTlsDatabaseClass))
+
+typedef struct _GTlsDatabaseClass GTlsDatabaseClass;
+typedef struct _GTlsDatabasePrivate GTlsDatabasePrivate;
+
+struct _GTlsDatabase
+{
+ GObject parent_instance;
+
+ GTlsDatabasePrivate *priv;
+};
+
+struct _GTlsDatabaseClass
+{
+ GObjectClass parent_class;
+
+ /* virtual methods */
+
+ GTlsCertificateFlags (*verify_chain) (GTlsDatabase *self,
+ GTlsCertificate *chain,
+ const gchar *purpose,
+ GSocketConnectable *identity,
+ GTlsInteraction *interaction,
+ GTlsDatabaseVerifyFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+ void (*verify_chain_async) (GTlsDatabase *self,
+ GTlsCertificate *chain,
+ const gchar *purpose,
+ GSocketConnectable *identity,
+ GTlsInteraction *interaction,
+ GTlsDatabaseVerifyFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ GTlsCertificateFlags (*verify_chain_finish) (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+ gchar* (*create_certificate_handle) (GTlsDatabase *self,
+ GTlsCertificate *certificate);
+
+ GTlsCertificate* (*lookup_certificate_for_handle) (GTlsDatabase *self,
+ const gchar *handle,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+ void (*lookup_certificate_for_handle_async) (GTlsDatabase *self,
+ const gchar *handle,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ GTlsCertificate* (*lookup_certificate_for_handle_finish) (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+ GTlsCertificate* (*lookup_certificate_issuer) (GTlsDatabase *self,
+ GTlsCertificate *certificate,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+ void (*lookup_certificate_issuer_async) (GTlsDatabase *self,
+ GTlsCertificate *certificate,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ GTlsCertificate* (*lookup_certificate_issuer_finish) (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+ GList* (*lookup_certificates_issued_by) (GTlsDatabase *self,
+ GByteArray *issuer_raw_dn,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+ void (*lookup_certificates_issued_by_async) (GTlsDatabase *self,
+ GByteArray *issuer_raw_dn,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ GList* (*lookup_certificates_issued_by_finish) (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ gpointer padding[16];
+};
+
+GType g_tls_database_get_type (void) G_GNUC_CONST;
+
+GTlsCertificateFlags g_tls_database_verify_chain (GTlsDatabase *self,
+ GTlsCertificate *chain,
+ const gchar *purpose,
+ GSocketConnectable *identity,
+ GTlsInteraction *interaction,
+ GTlsDatabaseVerifyFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+void g_tls_database_verify_chain_async (GTlsDatabase *self,
+ GTlsCertificate *chain,
+ const gchar *purpose,
+ GSocketConnectable *identity,
+ GTlsInteraction *interaction,
+ GTlsDatabaseVerifyFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GTlsCertificateFlags g_tls_database_verify_chain_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+gchar* g_tls_database_create_certificate_handle (GTlsDatabase *self,
+ GTlsCertificate *certificate);
+
+GTlsCertificate* g_tls_database_lookup_certificate_for_handle (GTlsDatabase *self,
+ const gchar *handle,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+void g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase *self,
+ const gchar *handle,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GTlsCertificate* g_tls_database_lookup_certificate_for_handle_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+GTlsCertificate* g_tls_database_lookup_certificate_issuer (GTlsDatabase *self,
+ GTlsCertificate *certificate,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+void g_tls_database_lookup_certificate_issuer_async (GTlsDatabase *self,
+ GTlsCertificate *certificate,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GTlsCertificate* g_tls_database_lookup_certificate_issuer_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+GList* g_tls_database_lookup_certificates_issued_by (GTlsDatabase *self,
+ GByteArray *issuer_raw_dn,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+void g_tls_database_lookup_certificates_issued_by_async (GTlsDatabase *self,
+ GByteArray *issuer_raw_dn,
+ GTlsInteraction *interaction,
+ GTlsDatabaseLookupFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GList* g_tls_database_lookup_certificates_issued_by_finish (GTlsDatabase *self,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __G_TLS_DATABASE_H__ */
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2010 Collabora, Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gtlsfiledatabase.h"
+
+#include "ginitable.h"
+#include "gtlsbackend.h"
+#include "gtlsdatabase.h"
+#include "glibintl.h"
+
+/**
+ * SECTION:gtlsfiledatabase
+ * @short_description: TLS file based database type
+ * @include: gio/gio.h
+ *
+ * #GTlsFileDatabase is implemented by #GTlsDatabase objects which load
+ * their certificate information from a file. It is in interface which
+ * TLS library specific subtypes implement.
+ *
+ * Since: 2.30
+ */
+
+/**
+ * GTlsFileDatabase:
+ *
+ * Implemented by a #GTlsDatabase which allows you to load certificates
+ * from a file.
+ *
+ * Since: 2.30
+ */
+G_DEFINE_INTERFACE (GTlsFileDatabase, g_tls_file_database, G_TYPE_TLS_DATABASE)
+
+static void
+g_tls_file_database_default_init (GTlsFileDatabaseInterface *iface)
+{
+ /**
+ * GTlsFileDatabase:anchors:
+ *
+ * The path to a file containing PEM encoded certificate authority
+ * root anchors. The certificates in this file will be treated as
+ * root authorities for the purpose of verifying other certificates
+ * via the g_tls_database_verify_chain() operation.
+ *
+ * Since: 2.30
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("anchors",
+ P_("Anchors"),
+ P_("The certificate authority anchor file"),
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * g_tls_file_database_new:
+ * @anchors: filename of anchor certificate authorities.
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Creates a new #GTlsFileDatabase which uses anchor certificate authorities
+ * in @anchors to verify certificate chains.
+ *
+ * The certificates in @anchors must be PEM encoded.
+ *
+ * Return value: the new #GTlsFileDatabase, or %NULL on error
+ *
+ * Since: 2.30
+ */
+GTlsDatabase*
+g_tls_file_database_new (const gchar *anchors,
+ GError **error)
+{
+ GObject *database;
+ GTlsBackend *backend;
+
+ backend = g_tls_backend_get_default ();
+ database = g_initable_new (g_tls_backend_get_file_database_type (backend),
+ NULL, error,
+ "anchors", anchors,
+ NULL);
+ return G_TLS_DATABASE (database);
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2010 Collabora, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the licence or (at
+ * your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_FILE_DATABASE_H__
+#define __G_TLS_FILE_DATABASE_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_FILE_DATABASE (g_tls_file_database_get_type ())
+#define G_TLS_FILE_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_FILE_DATABASE, GTlsFileDatabase))
+#define G_IS_TLS_FILE_DATABASE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_FILE_DATABASE))
+#define G_TLS_FILE_DATABASE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TLS_FILE_DATABASE, GTlsFileDatabaseInterface))
+
+typedef struct _GTlsFileDatabaseInterface GTlsFileDatabaseInterface;
+
+/**
+ * GTlsFileDatabaseInterface:
+ * @g_iface: The parent interface.
+ *
+ * Provides an interface for #GTlsFileDatabase implementations.
+ *
+ */
+struct _GTlsFileDatabaseInterface
+{
+ GTypeInterface g_iface;
+
+ /*< private >*/
+ /* Padding for future expansion */
+ gpointer padding[8];
+};
+
+GType g_tls_file_database_get_type (void) G_GNUC_CONST;
+
+GTlsDatabase* g_tls_file_database_new (const gchar *anchors,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __G_TLS_FILE_DATABASE_H___ */
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gtlsinteraction.h"
+#include "gtlspassword.h"
+#include "gasyncresult.h"
+#include "gsimpleasyncresult.h"
+#include "gioenumtypes.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gtlsinteraction
+ * @short_description: Interaction with the user during TLS operations.
+ * @include: gio/gio.h
+ *
+ * #GTlsInteraction provides a mechanism for the TLS connection and database
+ * code to interact with the user. It can be used to ask the user for passwords.
+ *
+ * To use a #GTlsInteraction with a TLS connection use
+ * g_tls_connection_set_interaction().
+ *
+ * Callers should instantiate a subclass of this that implements all the
+ * various callbacks to show the required dialogs, such as
+ * #GtkTlsInteraction. If no interaction is desired, usually %NULL can be
+ * passed, see each method taking a #GTlsInteraction for details.
+ */
+
+/**
+ * GTlsInteraction:
+ *
+ * An object representing interaction that the TLS connection and database
+ * might have with the user.
+ *
+ * Since: 2.30
+ */
+
+/**
+ * GTlsInteractionClass:
+ *
+ * The class for #GTlsInteraction.
+ *
+ * Since: 2.30
+ */
+
+G_DEFINE_TYPE (GTlsInteraction, g_tls_interaction, G_TYPE_OBJECT);
+
+GTlsInteractionResult
+g_tls_interaction_default_ask_password (GTlsInteraction *interaction,
+ GTlsPassword *password)
+{
+ return G_TLS_INTERACTION_UNHANDLED;
+}
+
+void
+g_tls_interaction_default_ask_password_async (GTlsInteraction *interaction,
+ GTlsPassword *password,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ res = g_simple_async_result_new (G_OBJECT (interaction), callback, user_data,
+ g_tls_interaction_default_ask_password);
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (res);
+}
+
+GTlsInteractionResult
+g_tls_interaction_default_ask_password_finish (GTlsInteraction *interaction,
+ GAsyncResult *result)
+{
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (interaction),
+ g_tls_interaction_default_ask_password), G_TLS_INTERACTION_UNHANDLED);
+ return G_TLS_INTERACTION_UNHANDLED;
+}
+
+static void
+g_tls_interaction_init (GTlsInteraction *interaction)
+{
+}
+
+static void
+g_tls_interaction_class_init (GTlsInteractionClass *klass)
+{
+ klass->ask_password = g_tls_interaction_default_ask_password;
+ klass->ask_password_async = g_tls_interaction_default_ask_password_async;
+ klass->ask_password_finish = g_tls_interaction_default_ask_password_finish;
+}
+
+/**
+ * g_tls_interaction_ask_password:
+ * @interaction: a #GTlsInteraction object
+ * @password: a #GTlsPassword object
+ *
+ * This function is normally called by #GTlsConnection or #GTlsDatabase to
+ * ask the user for a password.
+ *
+ * Derived subclasses usually implement a password prompt, although they may
+ * also choose to provide a password from elsewhere. The @password value will
+ * be filled in and then @callback will be called. Alternatively the user may
+ * abort this password request, which will usually abort the TLS connection.
+ *
+ * Returns: The status of the ask password interaction.
+ *
+ * Since: 2.30
+ */
+GTlsInteractionResult
+g_tls_interaction_ask_password (GTlsInteraction *interaction,
+ GTlsPassword *password)
+{
+ g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
+ g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED);
+ return G_TLS_INTERACTION_GET_CLASS (interaction)->ask_password (interaction, password);
+}
+
+/**
+ * g_tls_interaction_ask_password_async:
+ * @interaction: a #GTlsInteraction object
+ * @password: a #GTlsPassword object
+ * @callback: will be called when the interaction completes
+ * @user_data: (allow-none): data to pass to the @callback
+ *
+ * This function is normally called by #GTlsConnection or #GTlsDatabase to
+ * ask the user for a password.
+ *
+ * Derived subclasses usually implement a password prompt, although they may
+ * also choose to provide a password from elsewhere. The @password value will
+ * be filled in and then @callback will be called. Alternatively the user may
+ * abort this password request, which will usually abort the TLS connection.
+ *
+ * The @callback will be invoked on thread-default main context of the thread
+ * that called this function. The @callback should call
+ * g_tls_interaction_ask_password_finish() to get the status of the user
+ * interaction.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_interaction_ask_password_async (GTlsInteraction *interaction,
+ GTlsPassword *password,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (G_IS_TLS_INTERACTION (interaction));
+ g_return_if_fail (G_IS_TLS_PASSWORD (password));
+ g_return_if_fail (callback != NULL);
+ G_TLS_INTERACTION_GET_CLASS (interaction)->ask_password_async (interaction, password,
+ callback, user_data);
+}
+
+/**
+ * g_tls_interaction_ask_password_finish:
+ * @interaction: a #GTlsInteraction object
+ * @result: the result passed to the callback
+ *
+ * Complete an ask password user interaction request. This should be once
+ * the g_tls_interaction_ask_password() completion callback is called.
+ *
+ * If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsPassword passed
+ * to g_tls_interaction_ask_password() will have its password filled in.
+ *
+ * Returns: The status of the ask password interaction.
+ *
+ * Since: 2.30
+ */
+GTlsInteractionResult
+g_tls_interaction_ask_password_finish (GTlsInteraction *interaction,
+ GAsyncResult *result)
+{
+ g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_INTERACTION_UNHANDLED);
+ return G_TLS_INTERACTION_GET_CLASS (interaction)->ask_password_finish (interaction, result);
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_INTERACTION_H__
+#define __G_TLS_INTERACTION_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_INTERACTION (g_tls_interaction_get_type ())
+#define G_TLS_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_INTERACTION, GTlsInteraction))
+#define G_TLS_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_INTERACTION, GTlsInteractionClass))
+#define G_IS_TLS_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_INTERACTION))
+#define G_IS_TLS_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_INTERACTION))
+#define G_TLS_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_INTERACTION, GTlsInteractionClass))
+
+typedef struct _GTlsInteractionClass GTlsInteractionClass;
+typedef struct _GTlsInteractionPrivate GTlsInteractionPrivate;
+
+struct _GTlsInteraction
+{
+ GObject parent_instance;
+
+ GTlsInteractionPrivate *priv;
+};
+
+struct _GTlsInteractionClass
+{
+ GObjectClass parent_class;
+
+ /* virtual methods: */
+
+ GTlsInteractionResult (* ask_password) (GTlsInteraction *interaction,
+ GTlsPassword *password);
+
+ void (* ask_password_async) (GTlsInteraction *interaction,
+ GTlsPassword *password,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+ GTlsInteractionResult (* ask_password_finish) (GTlsInteraction *interaction,
+ GAsyncResult *result);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ gpointer padding[16];
+};
+
+GType g_tls_interaction_get_type (void) G_GNUC_CONST;
+
+GTlsInteractionResult g_tls_interaction_ask_password (GTlsInteraction *interaction,
+ GTlsPassword *password);
+
+void g_tls_interaction_ask_password_async (GTlsInteraction *interaction,
+ GTlsPassword *password,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GTlsInteractionResult g_tls_interaction_ask_password_finish (GTlsInteraction *interaction,
+ GAsyncResult *result);
+
+G_END_DECLS
+
+#endif /* __G_TLS_INTERACTION_H__ */
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+#include "glib.h"
+#include "glibintl.h"
+
+#include "gioenumtypes.h"
+#include "gtlspassword.h"
+
+#include <string.h>
+
+/**
+ * SECTION:gtlspassword
+ * @title: GTlsPassword
+ * @short_description: TLS Passwords for prompting
+ * @include: gio/gio.h
+ *
+ * Holds a password used in TLS.
+ */
+
+/**
+ * GTlsPassword:
+ *
+ * An abstract interface representing a password used in TLS. Often used in
+ * user interaction such as unlocking a key storage token.
+ *
+ * Since: 2.30
+ */
+
+enum
+{
+ PROP_0,
+ PROP_FLAGS,
+ PROP_DESCRIPTION,
+ PROP_WARNING
+};
+
+struct _GTlsPasswordPrivate
+{
+ guchar *value;
+ gsize length;
+ GDestroyNotify destroy;
+ GTlsPasswordFlags flags;
+ gchar *description;
+ gchar *warning;
+};
+
+G_DEFINE_TYPE (GTlsPassword, g_tls_password, G_TYPE_OBJECT);
+
+static void
+g_tls_password_init (GTlsPassword *password)
+{
+ password->priv = G_TYPE_INSTANCE_GET_PRIVATE (password, G_TYPE_TLS_PASSWORD,
+ GTlsPasswordPrivate);
+}
+
+static const guchar *
+g_tls_password_real_get_value (GTlsPassword *password,
+ gsize *length)
+{
+ if (length)
+ *length = password->priv->length;
+ return password->priv->value;
+}
+
+static void
+g_tls_password_real_set_value (GTlsPassword *password,
+ guchar *value,
+ gssize length,
+ GDestroyNotify destroy)
+{
+ if (password->priv->destroy)
+ (password->priv->destroy) (password->priv->value);
+ password->priv->destroy = NULL;
+ password->priv->value = NULL;
+ password->priv->length = 0;
+
+ if (length < 0)
+ length = strlen ((gchar*) value);
+
+ password->priv->value = value;
+ password->priv->length = length;
+ password->priv->destroy = destroy;
+}
+
+static const gchar*
+g_tls_password_real_get_default_warning (GTlsPassword *password)
+{
+ GTlsPasswordFlags flags;
+
+ flags = g_tls_password_get_flags (password);
+
+ if (flags & G_TLS_PASSWORD_FINAL_TRY)
+ return _("This is the last chance to ether the password correctly before your access is locked out.");
+ if (flags & G_TLS_PASSWORD_MANY_TRIES)
+ return _("Several password entered have been incorrect, and your access will be locked out after further failures.");
+ if (flags & G_TLS_PASSWORD_RETRY)
+ return _("The password entered is incorrect.");
+
+ return NULL;
+}
+
+static void
+g_tls_password_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GTlsPassword *password = G_TLS_PASSWORD (object);
+
+ switch (prop_id)
+ {
+ case PROP_FLAGS:
+ g_value_set_flags (value, g_tls_password_get_flags (password));
+ break;
+ case PROP_WARNING:
+ g_value_set_string (value, g_tls_password_get_warning (password));
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, g_tls_password_get_description (password));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_tls_password_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GTlsPassword *password = G_TLS_PASSWORD (object);
+
+ switch (prop_id)
+ {
+ case PROP_FLAGS:
+ g_tls_password_set_flags (password, g_value_get_flags (value));
+ break;
+ case PROP_WARNING:
+ g_tls_password_set_warning (password, g_value_get_string (value));
+ break;
+ case PROP_DESCRIPTION:
+ g_tls_password_set_description (password, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+g_tls_password_finalize (GObject *object)
+{
+ GTlsPassword *password = G_TLS_PASSWORD (object);
+
+ g_tls_password_real_set_value (password, NULL, 0, NULL);
+ g_free (password->priv->warning);
+ g_free (password->priv->description);
+
+ G_OBJECT_CLASS (g_tls_password_parent_class)->finalize (object);
+}
+
+static void
+g_tls_password_class_init (GTlsPasswordClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ klass->get_value = g_tls_password_real_get_value;
+ klass->set_value = g_tls_password_real_set_value;
+ klass->get_default_warning = g_tls_password_real_get_default_warning;
+
+ gobject_class->get_property = g_tls_password_get_property;
+ gobject_class->set_property = g_tls_password_set_property;
+ gobject_class->finalize = g_tls_password_finalize;
+
+ g_type_class_add_private (klass, sizeof (GTlsPasswordPrivate));
+
+ g_object_class_install_property (gobject_class, PROP_FLAGS,
+ g_param_spec_flags ("flags", "Flags", "Flags about the password",
+ G_TYPE_TLS_PASSWORD_FLAGS, G_TLS_PASSWORD_NONE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_DESCRIPTION,
+ g_param_spec_string ("description", "Description", "Description of what the password is for",
+ "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_WARNING,
+ g_param_spec_string ("warning", "Warning", "Warning about the password",
+ "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+}
+
+/**
+ * g_tls_password_new:
+ * @flags: the password flags
+ * @description: description of what the password is for
+ *
+ * Create a new #GTlsPassword object.
+ *
+ * Returns: (transfer full): The newly allocated password object
+ */
+GTlsPassword *
+g_tls_password_new (GTlsPasswordFlags flags,
+ const gchar *description)
+{
+ return g_object_new (G_TYPE_TLS_PASSWORD,
+ "flags", flags,
+ "description", description,
+ NULL);
+}
+
+/**
+ * g_tls_password_get_value:
+ * @password: a #GTlsPassword object
+ * @length: (allow-none): location to place the length of the password.
+ *
+ * Get the password value. If @length is not %NULL then it will be filled
+ * in with the length of the password value.
+ *
+ * Returns: The password value owned by the password object.
+ *
+ * Since: 2.30
+ */
+const guchar *
+g_tls_password_get_value (GTlsPassword *password,
+ gsize *length)
+{
+ g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
+ return G_TLS_PASSWORD_GET_CLASS (password)->get_value (password, length);
+}
+
+/**
+ * g_tls_password_set_value:
+ * @password: a #GTlsPassword object
+ * @value: the new password value
+ * @length: the length of the password, or -1
+ *
+ * Set the value for this password. The @value will be copied by the password
+ * object.
+ *
+ * Specify the @length, for a non-null-terminated password. Pass -1 as
+ * @length if using a null-terminated password, and @length will be calculated
+ * automatically.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_value (GTlsPassword *password,
+ const guchar *value,
+ gssize length)
+{
+ g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+ if (length < 0)
+ length = strlen ((gchar *)value);
+
+ g_tls_password_set_value_full (password, g_memdup (value, length), length, g_free);
+}
+
+/**
+ * g_tls_password_set_value_full:
+ * @password: a #GTlsPassword object
+ * @value: the value for the password
+ * @length: the length of the password, or -1
+ * @destroy: (allow-none): a function to use to free the password.
+ *
+ * Provide the value for this password.
+ *
+ * The @value will be owned by the password object, and later freed using
+ * the @destroy function callback.
+ *
+ * Specify the @length, for a non-null-terminated password. Pass -1 as
+ * @length if using a null-terminated password, and @length will be calculated
+ * automatically.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_value_full (GTlsPassword *password,
+ guchar *value,
+ gssize length,
+ GDestroyNotify destroy)
+{
+ g_return_if_fail (G_IS_TLS_PASSWORD (password));
+ G_TLS_PASSWORD_GET_CLASS (password)->set_value (password, value,
+ length, destroy);
+}
+
+/**
+ * g_tls_password_get_flags:
+ * @password: a #GTlsPassword object
+ *
+ * Get flags about the password.
+ *
+ * Return value: The flags about the password.
+ *
+ * Since: 2.30
+ */
+GTlsPasswordFlags
+g_tls_password_get_flags (GTlsPassword *password)
+{
+ g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_PASSWORD_NONE);
+ return password->priv->flags;
+}
+
+/**
+ * g_tls_password_set_flags:
+ * @password: a #GTlsPassword object
+ * @flags: The flags about the password
+ *
+ * Set flags about the password.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_flags (GTlsPassword *password,
+ GTlsPasswordFlags flags)
+{
+ g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+ password->priv->flags = flags;
+
+ g_object_notify (G_OBJECT (password), "flags");
+}
+
+/**
+ * g_tls_password_get_description:
+ * @password: a #GTlsPassword object
+ *
+ * Get a description string about what the password will be used for.
+ *
+ * Return value: The description of the password.
+ *
+ * Since: 2.30
+ */
+const gchar*
+g_tls_password_get_description (GTlsPassword *password)
+{
+ g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
+ return password->priv->description;
+}
+
+/**
+ * g_tls_password_set_description:
+ * @password: a #GTlsPassword object
+ * @flags: The description of the password
+ *
+ * Set a description string about what the password will be used for.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_description (GTlsPassword *password,
+ const gchar *description)
+{
+ gchar *copy;
+
+ g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+ copy = g_strdup (description);
+ g_free (password->priv->description);
+ password->priv->description = copy;
+
+ g_object_notify (G_OBJECT (password), "description");
+}
+
+/**
+ * g_tls_password_get_warning:
+ * @password: a #GTlsPassword object
+ *
+ * Get a user readable translated warning. Usually this warning is a
+ * representation of the password flags returned from
+ * g_tls_password_get_flags().
+ *
+ * Return value: The warning.
+ *
+ * Since: 2.30
+ */
+const gchar *
+g_tls_password_get_warning (GTlsPassword *password)
+{
+ g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
+
+ if (password->priv->warning == NULL)
+ return G_TLS_PASSWORD_GET_CLASS (password)->get_default_warning (password);
+
+ return password->priv->warning;
+}
+
+/**
+ * g_tls_password_set_warning:
+ * @password: a #GTlsPassword object
+ * @warning: The user readable warning
+ *
+ * Set a user readable translated warning. Usually this warning is a
+ * representation of the password flags returned from
+ * g_tls_password_get_flags().
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_warning (GTlsPassword *password,
+ const gchar *warning)
+{
+ gchar *copy;
+
+ g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+ copy = g_strdup (warning);
+ g_free (password->priv->warning);
+ password->priv->warning = copy;
+
+ g_object_notify (G_OBJECT (password), "warning");
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_PASSWORD_H__
+#define __G_TLS_PASSWORD_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_PASSWORD (g_tls_password_get_type ())
+#define G_TLS_PASSWORD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_PASSWORD, GTlsPassword))
+#define G_TLS_PASSWORD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_PASSWORD, GTlsPasswordClass))
+#define G_IS_TLS_PASSWORD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_PASSWORD))
+#define G_IS_TLS_PASSWORD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_PASSWORD))
+#define G_TLS_PASSWORD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_PASSWORD, GTlsPasswordClass))
+
+typedef struct _GTlsPasswordClass GTlsPasswordClass;
+typedef struct _GTlsPasswordPrivate GTlsPasswordPrivate;
+
+struct _GTlsPassword
+{
+ GObject parent_instance;
+
+ GTlsPasswordPrivate *priv;
+};
+
+struct _GTlsPasswordClass
+{
+ GObjectClass parent_class;
+
+ /* methods */
+
+ const guchar * ( *get_value) (GTlsPassword *password,
+ gsize *length);
+
+ void ( *set_value) (GTlsPassword *password,
+ guchar *value,
+ gssize length,
+ GDestroyNotify destroy);
+
+ const gchar* ( *get_default_warning) (GTlsPassword *password);
+
+ /*< private >*/
+ /* Padding for future expansion */
+ gpointer padding[4];
+};
+
+GType g_tls_password_get_type (void) G_GNUC_CONST;
+
+GTlsPassword * g_tls_password_new (GTlsPasswordFlags flags,
+ const gchar *description);
+
+const guchar * g_tls_password_get_value (GTlsPassword *password,
+ gsize *length);
+void g_tls_password_set_value (GTlsPassword *password,
+ const guchar *value,
+ gssize length);
+void g_tls_password_set_value_full (GTlsPassword *password,
+ guchar *value,
+ gssize length,
+ GDestroyNotify destroy);
+
+GTlsPasswordFlags g_tls_password_get_flags (GTlsPassword *password);
+void g_tls_password_set_flags (GTlsPassword *password,
+ GTlsPasswordFlags flags);
+
+const gchar* g_tls_password_get_description (GTlsPassword *password);
+void g_tls_password_set_description (GTlsPassword *password,
+ const gchar *description);
+
+const gchar * g_tls_password_get_warning (GTlsPassword *password);
+void g_tls_password_set_warning (GTlsPassword *password,
+ const gchar *warning);
+
+G_END_DECLS
+
+#endif /* __G_TLS_PASSWORD_H__ */
socket-server
srvtarget
test.mo
+tls
unix-fd
unix-streams
volumemonitor
socket_server_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
-socket_client_SOURCES = socket-client.c
+socket_client_SOURCES = socket-client.c \
+ gtlsconsoleinteraction.c \
+ gtlsconsoleinteraction.h
socket_client_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gtlsconsoleinteraction.h"
+
+/*
+ * WARNING: This is not the example you're looking for [slow hand wave]. This
+ * is not industrial strength, it's just for testing. It uses embarassing
+ * functions like getpass() and does lazy things with threads.
+ */
+
+G_DEFINE_TYPE (GTlsConsoleInteraction, g_tls_console_interaction, G_TYPE_TLS_INTERACTION);
+
+static GTlsInteractionResult
+g_tls_console_interaction_ask_password (GTlsInteraction *interaction,
+ GTlsPassword *password)
+{
+ const gchar *value;
+ gchar *prompt;
+
+ prompt = g_strdup_printf ("Password \"%s\"': ", g_tls_password_get_description (password));
+ value = getpass (prompt);
+ g_free (prompt);
+
+ g_tls_password_set_value (password, (guchar *)value, -1);
+ return G_TLS_INTERACTION_HANDLED;
+}
+
+static void
+ask_password_with_getpass (GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ GTlsPassword *password;
+
+ password = g_simple_async_result_get_op_res_gpointer (res);
+ g_tls_console_interaction_ask_password (G_TLS_INTERACTION (object), password);
+}
+
+void
+g_tls_console_interaction_ask_password_async (GTlsInteraction *interaction,
+ GTlsPassword *password,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ res = g_simple_async_result_new (G_OBJECT (interaction), callback, user_data,
+ g_tls_console_interaction_ask_password);
+ g_simple_async_result_set_op_res_gpointer (res, g_object_ref (password), g_object_unref);
+ g_simple_async_result_run_in_thread (res, ask_password_with_getpass,
+ G_PRIORITY_DEFAULT, NULL);
+ g_object_unref (res);
+}
+
+GTlsInteractionResult
+g_tls_console_interaction_ask_password_finish (GTlsInteraction *interaction,
+ GAsyncResult *result)
+{
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (interaction),
+ g_tls_console_interaction_ask_password), G_TLS_INTERACTION_ABORTED);
+ return G_TLS_INTERACTION_HANDLED;
+}
+
+static void
+g_tls_console_interaction_init (GTlsConsoleInteraction *interaction)
+{
+
+}
+
+static void
+g_tls_console_interaction_class_init (GTlsConsoleInteractionClass *klass)
+{
+ GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
+ interaction_class->ask_password = g_tls_console_interaction_ask_password;
+ interaction_class->ask_password_async = g_tls_console_interaction_ask_password_async;
+ interaction_class->ask_password_finish = g_tls_console_interaction_ask_password_finish;
+}
+
+GTlsInteraction *
+g_tls_console_interaction_new (void)
+{
+ return g_object_new (G_TYPE_TLS_CONSOLE_INTERACTION, NULL);
+}
--- /dev/null
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#ifndef __G_TLS_CONSOLE_INTERACTION_H__
+#define __G_TLS_CONSOLE_INTERACTION_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_CONSOLE_INTERACTION (g_tls_console_interaction_get_type ())
+#define G_TLS_CONSOLE_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteraction))
+#define G_TLS_CONSOLE_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteractionClass))
+#define G_IS_TLS_CONSOLE_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_CONSOLE_INTERACTION))
+#define G_IS_TLS_CONSOLE_INTERACTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_CONSOLE_INTERACTION))
+#define G_TLS_CONSOLE_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteractionClass))
+
+typedef struct _GTlsConsoleInteraction GTlsConsoleInteraction;
+typedef struct _GTlsConsoleInteractionClass GTlsConsoleInteractionClass;
+
+struct _GTlsConsoleInteraction
+{
+ GTlsInteraction parent_instance;
+};
+
+struct _GTlsConsoleInteractionClass
+{
+ GTlsInteractionClass parent_class;
+};
+
+GType g_tls_console_interaction_get_type (void) G_GNUC_CONST;
+
+GTlsInteraction * g_tls_console_interaction_new (void);
+
+G_END_DECLS
+
+#endif /* __G_TLS_CONSOLE_INTERACTION_H__ */
#include <stdio.h>
#include <string.h>
+#include "gtlsconsoleinteraction.h"
+
GMainLoop *loop;
gboolean verbose = FALSE;
return TRUE;
}
-int
-main (int argc,
- char *argv[])
+static GTlsCertificate *
+lookup_client_certificate (GTlsClientConnection *conn, GError **error)
{
- GSocket *socket;
- GSocketAddress *src_address;
- GSocketAddress *address;
- GSocketType socket_type;
- GSocketFamily socket_family;
- GError *error = NULL;
- GOptionContext *context;
- GCancellable *cancellable;
- GSocketAddressEnumerator *enumerator;
- GSocketConnectable *connectable;
- GIOStream *connection;
- GInputStream *istream;
- GOutputStream *ostream;
-
- g_thread_init (NULL);
-
- g_type_init ();
-
- context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff");
- g_option_context_add_main_entries (context, cmd_entries, NULL);
- if (!g_option_context_parse (context, &argc, &argv, &error))
+ GList *l, *accepted;
+ GList *c, *certificates;
+ GTlsDatabase *database;
+ GTlsCertificate *certificate = NULL;
+ GTlsConnection *base;
+
+ accepted = g_tls_client_connection_get_accepted_cas (conn);
+ for (l = accepted; l != NULL; l = g_list_next (l))
{
- g_printerr ("%s: %s\n", argv[0], error->message);
- return 1;
+ base = G_TLS_CONNECTION (conn);
+ database = g_tls_connection_get_database (base);
+ certificates = g_tls_database_lookup_certificates_issued_by (database, l->data,
+ g_tls_connection_get_interaction (base),
+ G_TLS_DATABASE_LOOKUP_KEYPAIR,
+ NULL, error);
+ if (error && *error)
+ break;
+
+ if (certificates)
+ certificate = g_object_ref (certificates->data);
+
+ for (c = certificates; c != NULL; c = g_list_next (c))
+ g_object_unref (c->data);
+ g_list_free (certificates);
}
- if (argc != 2)
- {
- g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name");
- return 1;
- }
+ for (l = accepted; l != NULL; l = g_list_next (l))
+ g_byte_array_unref (l->data);
+ g_list_free (accepted);
- if (use_udp && tls)
- {
- g_printerr ("DTLS (TLS over UDP) is not supported");
- return 1;
- }
-
- if (cancel_timeout)
- {
- cancellable = g_cancellable_new ();
- g_thread_create (cancel_thread, cancellable, FALSE, NULL);
- }
- else
- {
- cancellable = NULL;
- }
+ if (certificate == NULL && error && !*error)
+ g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
+ "Server requested a certificate, but could not find relevant certificate in database.");
+ return certificate;
+}
- loop = g_main_loop_new (NULL, FALSE);
+static gboolean
+make_connection (const char *argument, GTlsCertificate *certificate, GCancellable *cancellable,
+ GSocket **socket, GSocketAddress **address, GIOStream **connection,
+ GInputStream **istream, GOutputStream **ostream, GError **error)
+{
+ GSocketType socket_type;
+ GSocketFamily socket_family;
+ GSocketAddressEnumerator *enumerator;
+ GSocketConnectable *connectable;
+ GSocketAddress *src_address;
+ GTlsInteraction *interaction;
+ GError *err = NULL;
if (use_udp)
socket_type = G_SOCKET_TYPE_DATAGRAM;
else
socket_family = G_SOCKET_FAMILY_IPV4;
- socket = g_socket_new (socket_family, socket_type, 0, &error);
- if (socket == NULL)
- {
- g_printerr ("%s: %s\n", argv[0], error->message);
- return 1;
- }
+ *socket = g_socket_new (socket_family, socket_type, 0, error);
+ if (*socket == NULL)
+ return FALSE;
if (read_timeout)
- g_socket_set_timeout (socket, read_timeout);
+ g_socket_set_timeout (*socket, read_timeout);
if (unix_socket)
{
GSocketAddress *addr;
- addr = socket_address_from_string (argv[1]);
+ addr = socket_address_from_string (argument);
if (addr == NULL)
- {
- g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]);
- return 1;
- }
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Could not parse '%s' as unix socket name", argument);
+ return FALSE;
+ }
connectable = G_SOCKET_CONNECTABLE (addr);
}
else
{
- connectable = g_network_address_parse (argv[1], 7777, &error);
+ connectable = g_network_address_parse (argument, 7777, error);
if (connectable == NULL)
- {
- g_printerr ("%s: %s\n", argv[0], error->message);
- return 1;
- }
+ return FALSE;
}
enumerator = g_socket_connectable_enumerate (connectable);
while (TRUE)
{
- address = g_socket_address_enumerator_next (enumerator, cancellable, &error);
- if (address == NULL)
- {
- if (error == NULL)
- g_printerr ("%s: No more addresses to try\n", argv[0]);
- else
- g_printerr ("%s: %s\n", argv[0], error->message);
- return 1;
- }
-
- if (g_socket_connect (socket, address, cancellable, &error))
- break;
- g_printerr ("%s: Connection to %s failed: %s, trying next\n", argv[0], socket_address_to_string (address), error->message);
- g_error_free (error);
- error = NULL;
-
- g_object_unref (address);
+ *address = g_socket_address_enumerator_next (enumerator, cancellable, error);
+ if (*address == NULL)
+ {
+ if (error == NULL)
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No more addresses to try");
+ return FALSE;
+ }
+
+ if (g_socket_connect (*socket, *address, cancellable, &err))
+ break;
+ g_message ("Connection to %s failed: %s, trying next\n", socket_address_to_string (*address), err->message);
+ g_clear_error (&err);
+
+ g_object_unref (*address);
}
g_object_unref (enumerator);
g_print ("Connected to %s\n",
- socket_address_to_string (address));
+ socket_address_to_string (*address));
- src_address = g_socket_get_local_address (socket, &error);
+ src_address = g_socket_get_local_address (*socket, error);
if (!src_address)
{
- g_printerr ("Error getting local address: %s\n",
- error->message);
- return 1;
+ g_prefix_error (error, "Error getting local address: ");
+ return FALSE;
}
+
g_print ("local address: %s\n",
- socket_address_to_string (src_address));
+ socket_address_to_string (src_address));
g_object_unref (src_address);
if (use_udp)
{
- connection = NULL;
- istream = NULL;
- ostream = NULL;
+ *connection = NULL;
+ *istream = NULL;
+ *ostream = NULL;
}
else
- connection = G_IO_STREAM (g_socket_connection_factory_create_connection (socket));
+ *connection = G_IO_STREAM (g_socket_connection_factory_create_connection (*socket));
if (tls)
{
GIOStream *tls_conn;
- tls_conn = g_tls_client_connection_new (connection, connectable, &error);
+ tls_conn = g_tls_client_connection_new (*connection, connectable, error);
if (!tls_conn)
- {
- g_printerr ("Could not create TLS connection: %s\n",
- error->message);
- return 1;
- }
+ {
+ g_prefix_error (error, "Could not create TLS connection: ");
+ return FALSE;
+ }
g_signal_connect (tls_conn, "accept-certificate",
- G_CALLBACK (accept_certificate), NULL);
+ G_CALLBACK (accept_certificate), NULL);
- if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn),
- cancellable, &error))
- {
- g_printerr ("Error during TLS handshake: %s\n",
- error->message);
- return 1;
- }
+ interaction = g_tls_console_interaction_new ();
+ g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn), interaction);
+ g_object_unref (interaction);
- g_object_unref (connection);
- connection = G_IO_STREAM (tls_conn);
+ if (certificate)
+ g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn), certificate);
+
+ g_object_unref (*connection);
+ *connection = G_IO_STREAM (tls_conn);
+
+ if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn),
+ cancellable, error))
+ {
+ g_prefix_error (error, "Error during TLS handshake: ");
+ return FALSE;
+ }
}
g_object_unref (connectable);
- if (connection)
+ if (*connection)
{
- istream = g_io_stream_get_input_stream (connection);
- ostream = g_io_stream_get_output_stream (connection);
+ *istream = g_io_stream_get_input_stream (*connection);
+ *ostream = g_io_stream_get_output_stream (*connection);
+ }
+
+ return TRUE;
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ GSocket *socket;
+ GSocketAddress *address;
+ GError *error = NULL;
+ GOptionContext *context;
+ GCancellable *cancellable;
+ GIOStream *connection;
+ GInputStream *istream;
+ GOutputStream *ostream;
+ GSocketAddress *src_address;
+ GTlsCertificate *certificate = NULL;
+ gint i;
+
+ g_thread_init (NULL);
+
+ g_type_init ();
+
+ context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff");
+ g_option_context_add_main_entries (context, cmd_entries, NULL);
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_printerr ("%s: %s\n", argv[0], error->message);
+ return 1;
+ }
+
+ if (argc != 2)
+ {
+ g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name");
+ return 1;
+ }
+
+ if (use_udp && tls)
+ {
+ g_printerr ("DTLS (TLS over UDP) is not supported");
+ return 1;
+ }
+
+ if (cancel_timeout)
+ {
+ cancellable = g_cancellable_new ();
+ g_thread_create (cancel_thread, cancellable, FALSE, NULL);
+ }
+ else
+ {
+ cancellable = NULL;
+ }
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ for (i = 0; i < 2; i++)
+ {
+ if (make_connection (argv[1], certificate, cancellable, &socket, &address,
+ &connection, &istream, &ostream, &error))
+ break;
+
+ if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED))
+ {
+ g_clear_error (&error);
+ certificate = lookup_client_certificate (G_TLS_CLIENT_CONNECTION (connection), &error);
+ if (certificate != NULL)
+ continue;
+ }
+
+ g_printerr ("%s: %s", argv[0], error->message);
+ return 1;
}
/* TODO: Test non-blocking connect/handshake */