mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-02 07:23:41 +02:00
Implement support for ALPN in GTlsConnection, GDtlsConnection
This commit is contained in:
@@ -54,7 +54,12 @@
|
||||
* Since: 2.28
|
||||
*/
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GTlsConnection, g_tls_connection, G_TYPE_IO_STREAM)
|
||||
struct _GTlsConnectionPrivate
|
||||
{
|
||||
gchar *negotiated_protocol;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GTlsConnection, g_tls_connection, G_TYPE_IO_STREAM)
|
||||
|
||||
static void g_tls_connection_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -64,6 +69,7 @@ static void g_tls_connection_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void g_tls_connection_finalize (GObject *object);
|
||||
|
||||
enum {
|
||||
ACCEPT_CERTIFICATE,
|
||||
@@ -83,7 +89,9 @@ enum {
|
||||
PROP_INTERACTION,
|
||||
PROP_CERTIFICATE,
|
||||
PROP_PEER_CERTIFICATE,
|
||||
PROP_PEER_CERTIFICATE_ERRORS
|
||||
PROP_PEER_CERTIFICATE_ERRORS,
|
||||
PROP_ADVERTISED_PROTOCOLS,
|
||||
PROP_NEGOTIATED_PROTOCOL,
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -93,6 +101,7 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
|
||||
|
||||
gobject_class->get_property = g_tls_connection_get_property;
|
||||
gobject_class->set_property = g_tls_connection_set_property;
|
||||
gobject_class->finalize = g_tls_connection_finalize;
|
||||
|
||||
/**
|
||||
* GTlsConnection:base-io-stream:
|
||||
@@ -251,6 +260,37 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
|
||||
0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
/**
|
||||
* GTlsConnection:advertised-protocols:
|
||||
*
|
||||
* The list of application-layer protocols that the connection
|
||||
* advertises that it is willing to speak. See
|
||||
* g_tls_connection_set_advertised_protocols().
|
||||
*
|
||||
* Since: 2.60
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_ADVERTISED_PROTOCOLS,
|
||||
g_param_spec_boxed ("advertised-protocols",
|
||||
P_("Advertised Protocols"),
|
||||
P_("Application-layer protocols available on this connection"),
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
/**
|
||||
* GTlsConnection:negotiated-protocol:
|
||||
*
|
||||
* The application-layer protocol negotiated during the TLS
|
||||
* handshake. See g_tls_connection_get_negotiated_protocol().
|
||||
*
|
||||
* Since: 2.60
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_NEGOTIATED_PROTOCOL,
|
||||
g_param_spec_string ("negotiated-protocol",
|
||||
P_("Negotiated Protocol"),
|
||||
P_("Application-layer protocol negotiated for this connection"),
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GTlsConnection::accept-certificate:
|
||||
@@ -334,6 +374,17 @@ g_tls_connection_set_property (GObject *object,
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
g_tls_connection_finalize (GObject *object)
|
||||
{
|
||||
GTlsConnection *conn = G_TLS_CONNECTION(object);
|
||||
GTlsConnectionPrivate *priv = g_tls_connection_get_instance_private (conn);
|
||||
|
||||
g_clear_pointer (&priv->negotiated_protocol, g_free);
|
||||
|
||||
G_OBJECT_CLASS (g_tls_connection_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tls_connection_set_use_system_certdb:
|
||||
* @conn: a #GTlsConnection
|
||||
@@ -742,6 +793,82 @@ g_tls_connection_get_rehandshake_mode (GTlsConnection *conn)
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tls_connection_set_advertised_protocols:
|
||||
* @conn: a #GTlsConnection
|
||||
* @protocols: (array zero-terminated=1) (nullable): a %NULL-terminated
|
||||
* array of ALPN protocol names (eg, "http/1.1", "h2"), or %NULL
|
||||
*
|
||||
* Sets the list of application-layer protocols to advertise that the
|
||||
* caller is willing to speak on this connection. The
|
||||
* Application-Layer Protocol Negotiation (ALPN) extension will be
|
||||
* used to negotiate a compatible protocol with the peer; use
|
||||
* g_tls_connection_get_negotiated_protocol() to find the negotiated
|
||||
* protocol after the handshake. Specifying %NULL for the the value
|
||||
* of @protocols will disable ALPN negotiation.
|
||||
*
|
||||
* See [IANA TLS ALPN Protocol IDs](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
|
||||
* for a list of registered protocol IDs.
|
||||
*
|
||||
* Since: 2.60
|
||||
*/
|
||||
void
|
||||
g_tls_connection_set_advertised_protocols (GTlsConnection *conn,
|
||||
const gchar * const *protocols)
|
||||
{
|
||||
g_return_if_fail (G_IS_TLS_CONNECTION (conn));
|
||||
|
||||
g_object_set (G_OBJECT (conn),
|
||||
"advertised-protocols", protocols,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tls_connection_get_negotiated_protocol:
|
||||
* @conn: a #GTlsConnection
|
||||
*
|
||||
* Gets the name of the application-layer protocol negotiated during
|
||||
* the handshake.
|
||||
*
|
||||
* If the peer did not use the ALPN extension, or did not advertise a
|
||||
* protocol that matched one of @conn's protocols, or the TLS backend
|
||||
* does not support ALPN, then this will be %NULL. See
|
||||
* g_tls_connection_set_advertised_protocols().
|
||||
*
|
||||
* Returns: (nullable): the negotiated protocol, or %NULL
|
||||
*
|
||||
* Since: 2.60
|
||||
*/
|
||||
const gchar *
|
||||
g_tls_connection_get_negotiated_protocol (GTlsConnection *conn)
|
||||
{
|
||||
GTlsConnectionPrivate *priv;
|
||||
gchar *protocol;
|
||||
|
||||
g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
|
||||
|
||||
g_object_get (G_OBJECT (conn),
|
||||
"negotiated-protocol", &protocol,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* Cache the property internally so we can return a `const` pointer
|
||||
* to the caller.
|
||||
*/
|
||||
priv = g_tls_connection_get_instance_private (conn);
|
||||
if (g_strcmp0 (priv->negotiated_protocol, protocol) != 0)
|
||||
{
|
||||
g_free (priv->negotiated_protocol);
|
||||
priv->negotiated_protocol = protocol;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (protocol);
|
||||
}
|
||||
|
||||
return priv->negotiated_protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tls_connection_handshake:
|
||||
* @conn: a #GTlsConnection
|
||||
|
Reference in New Issue
Block a user