Coverage Report

Created: 2025-07-01 07:09

/src/glib/gio/gtlsbackend.c
Line
Count
Source (jump to first uncovered line)
1
/* GIO - GLib Input, Output and Streaming Library
2
 *
3
 * Copyright © 2010 Red Hat, Inc
4
 * Copyright © 2015 Collabora, Ltd.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General
17
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
#include "config.h"
21
#include "glib.h"
22
23
#include "gtlsbackend.h"
24
#include "gtlsdatabase.h"
25
#include "gdummytlsbackend.h"
26
#include "gioenumtypes.h"
27
#include "giomodule-priv.h"
28
29
/**
30
 * SECTION:gtls
31
 * @title: TLS Overview
32
 * @short_description: TLS (aka SSL) support for GSocketConnection
33
 * @include: gio/gio.h
34
 *
35
 * #GTlsConnection and related classes provide TLS (Transport Layer
36
 * Security, previously known as SSL, Secure Sockets Layer) support for
37
 * gio-based network streams.
38
 *
39
 * #GDtlsConnection and related classes provide DTLS (Datagram TLS) support for
40
 * GIO-based network sockets, using the #GDatagramBased interface. The TLS and
41
 * DTLS APIs are almost identical, except TLS is stream-based and DTLS is
42
 * datagram-based. They share certificate and backend infrastructure.
43
 *
44
 * In the simplest case, for a client TLS connection, you can just set the
45
 * #GSocketClient:tls flag on a #GSocketClient, and then any
46
 * connections created by that client will have TLS negotiated
47
 * automatically, using appropriate default settings, and rejecting
48
 * any invalid or self-signed certificates (unless you change that
49
 * default by setting the #GSocketClient:tls-validation-flags
50
 * property). The returned object will be a #GTcpWrapperConnection,
51
 * which wraps the underlying #GTlsClientConnection.
52
 *
53
 * For greater control, you can create your own #GTlsClientConnection,
54
 * wrapping a #GSocketConnection (or an arbitrary #GIOStream with
55
 * pollable input and output streams) and then connect to its signals,
56
 * such as #GTlsConnection::accept-certificate, before starting the
57
 * handshake.
58
 *
59
 * Server-side TLS is similar, using #GTlsServerConnection. At the
60
 * moment, there is no support for automatically wrapping server-side
61
 * connections in the way #GSocketClient does for client-side
62
 * connections.
63
 */
64
65
/**
66
 * SECTION:gtlsbackend
67
 * @title: GTlsBackend
68
 * @short_description: TLS backend implementation
69
 * @include: gio/gio.h
70
 *
71
 * TLS (Transport Layer Security, aka SSL) and DTLS backend.
72
 *
73
 * Since: 2.28
74
 */
75
76
/**
77
 * GTlsBackend:
78
 *
79
 * TLS (Transport Layer Security, aka SSL) and DTLS backend. This is an
80
 * internal type used to coordinate the different classes implemented
81
 * by a TLS backend.
82
 *
83
 * Since: 2.28
84
 */
85
86
G_DEFINE_INTERFACE (GTlsBackend, g_tls_backend, G_TYPE_OBJECT)
87
88
static GTlsDatabase *default_database;
89
G_LOCK_DEFINE_STATIC (default_database_lock);
90
91
static void
92
g_tls_backend_default_init (GTlsBackendInterface *iface)
93
0
{
94
0
}
95
96
static GTlsBackend *tls_backend_default_singleton = NULL;  /* (owned) (atomic) */
97
98
/**
99
 * g_tls_backend_get_default:
100
 *
101
 * Gets the default #GTlsBackend for the system.
102
 *
103
 * Returns: (not nullable) (transfer none): a #GTlsBackend, which will be a
104
 *     dummy object if no TLS backend is available
105
 *
106
 * Since: 2.28
107
 */
108
GTlsBackend *
109
g_tls_backend_get_default (void)
110
0
{
111
0
  if (g_once_init_enter (&tls_backend_default_singleton))
112
0
    {
113
0
      GTlsBackend *singleton;
114
115
0
      singleton = _g_io_module_get_default (G_TLS_BACKEND_EXTENSION_POINT_NAME,
116
0
                                            "GIO_USE_TLS",
117
0
                                            NULL);
118
119
0
      g_once_init_leave (&tls_backend_default_singleton, singleton);
120
0
    }
121
122
0
  return tls_backend_default_singleton;
123
0
}
124
125
/**
126
 * g_tls_backend_supports_tls:
127
 * @backend: the #GTlsBackend
128
 *
129
 * Checks if TLS is supported; if this returns %FALSE for the default
130
 * #GTlsBackend, it means no "real" TLS backend is available.
131
 *
132
 * Returns: whether or not TLS is supported
133
 *
134
 * Since: 2.28
135
 */
136
gboolean
137
g_tls_backend_supports_tls (GTlsBackend *backend)
138
0
{
139
0
  if (G_TLS_BACKEND_GET_INTERFACE (backend)->supports_tls)
140
0
    return G_TLS_BACKEND_GET_INTERFACE (backend)->supports_tls (backend);
141
0
  else if (G_IS_DUMMY_TLS_BACKEND (backend))
142
0
    return FALSE;
143
0
  else
144
0
    return TRUE;
145
0
}
146
147
/**
148
 * g_tls_backend_supports_dtls:
149
 * @backend: the #GTlsBackend
150
 *
151
 * Checks if DTLS is supported. DTLS support may not be available even if TLS
152
 * support is available, and vice-versa.
153
 *
154
 * Returns: whether DTLS is supported
155
 *
156
 * Since: 2.48
157
 */
158
gboolean
159
g_tls_backend_supports_dtls (GTlsBackend *backend)
160
0
{
161
0
  if (G_TLS_BACKEND_GET_INTERFACE (backend)->supports_dtls)
162
0
    return G_TLS_BACKEND_GET_INTERFACE (backend)->supports_dtls (backend);
163
164
0
  return FALSE;
165
0
}
166
167
/**
168
 * g_tls_backend_get_default_database:
169
 * @backend: the #GTlsBackend
170
 *
171
 * Gets the default #GTlsDatabase used to verify TLS connections.
172
 *
173
 * Returns: (transfer full): the default database, which should be
174
 *               unreffed when done.
175
 *
176
 * Since: 2.30
177
 */
178
GTlsDatabase *
179
g_tls_backend_get_default_database (GTlsBackend *backend)
180
0
{
181
0
  GTlsDatabase *db;
182
183
0
  g_return_val_if_fail (G_IS_TLS_BACKEND (backend), NULL);
184
185
  /* This method was added later, so accept the (remote) possibility it can be NULL */
186
0
  if (!G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database)
187
0
    return NULL;
188
189
0
  G_LOCK (default_database_lock);
190
191
0
  if (!default_database)
192
0
    default_database = G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database (backend);
193
0
  db = default_database ? g_object_ref (default_database) : NULL;
194
0
  G_UNLOCK (default_database_lock);
195
196
0
  return db;
197
0
}
198
199
/**
200
 * g_tls_backend_set_default_database:
201
 * @backend: the #GTlsBackend
202
 * @database: (nullable): the #GTlsDatabase
203
 *
204
 * Set the default #GTlsDatabase used to verify TLS connections
205
 *
206
 * Any subsequent call to g_tls_backend_get_default_database() will return
207
 * the database set in this call.  Existing databases and connections are not
208
 * modified.
209
 *
210
 * Setting a %NULL default database will reset to using the system default
211
 * database as if g_tls_backend_set_default_database() had never been called.
212
 *
213
 * Since: 2.60
214
 */
215
void
216
g_tls_backend_set_default_database (GTlsBackend  *backend,
217
                                    GTlsDatabase *database)
218
0
{
219
0
  g_return_if_fail (G_IS_TLS_BACKEND (backend));
220
0
  g_return_if_fail (database == NULL || G_IS_TLS_DATABASE (database));
221
222
0
  G_LOCK (default_database_lock);
223
0
  g_set_object (&default_database, database);
224
0
  G_UNLOCK (default_database_lock);
225
0
}
226
227
/**
228
 * g_tls_backend_get_certificate_type:
229
 * @backend: the #GTlsBackend
230
 *
231
 * Gets the #GType of @backend's #GTlsCertificate implementation.
232
 *
233
 * Returns: the #GType of @backend's #GTlsCertificate
234
 *   implementation.
235
 *
236
 * Since: 2.28
237
 */
238
GType
239
g_tls_backend_get_certificate_type (GTlsBackend *backend)
240
0
{
241
0
  return G_TLS_BACKEND_GET_INTERFACE (backend)->get_certificate_type ();
242
0
}
243
244
/**
245
 * g_tls_backend_get_client_connection_type:
246
 * @backend: the #GTlsBackend
247
 *
248
 * Gets the #GType of @backend's #GTlsClientConnection implementation.
249
 *
250
 * Returns: the #GType of @backend's #GTlsClientConnection
251
 *   implementation.
252
 *
253
 * Since: 2.28
254
 */
255
GType
256
g_tls_backend_get_client_connection_type (GTlsBackend *backend)
257
0
{
258
0
  return G_TLS_BACKEND_GET_INTERFACE (backend)->get_client_connection_type ();
259
0
}
260
261
/**
262
 * g_tls_backend_get_server_connection_type:
263
 * @backend: the #GTlsBackend
264
 *
265
 * Gets the #GType of @backend's #GTlsServerConnection implementation.
266
 *
267
 * Returns: the #GType of @backend's #GTlsServerConnection
268
 *   implementation.
269
 *
270
 * Since: 2.28
271
 */
272
GType
273
g_tls_backend_get_server_connection_type (GTlsBackend *backend)
274
0
{
275
0
  return G_TLS_BACKEND_GET_INTERFACE (backend)->get_server_connection_type ();
276
0
}
277
278
/**
279
 * g_tls_backend_get_dtls_client_connection_type:
280
 * @backend: the #GTlsBackend
281
 *
282
 * Gets the #GType of @backend’s #GDtlsClientConnection implementation.
283
 *
284
 * Returns: the #GType of @backend’s #GDtlsClientConnection
285
 *   implementation, or %G_TYPE_INVALID if this backend doesn’t support DTLS.
286
 *
287
 * Since: 2.48
288
 */
289
GType
290
g_tls_backend_get_dtls_client_connection_type (GTlsBackend *backend)
291
0
{
292
0
  GTlsBackendInterface *iface;
293
294
0
  g_return_val_if_fail (G_IS_TLS_BACKEND (backend), G_TYPE_INVALID);
295
296
0
  iface = G_TLS_BACKEND_GET_INTERFACE (backend);
297
0
  if (iface->get_dtls_client_connection_type == NULL)
298
0
    return G_TYPE_INVALID;
299
300
0
  return iface->get_dtls_client_connection_type ();
301
0
}
302
303
/**
304
 * g_tls_backend_get_dtls_server_connection_type:
305
 * @backend: the #GTlsBackend
306
 *
307
 * Gets the #GType of @backend’s #GDtlsServerConnection implementation.
308
 *
309
 * Returns: the #GType of @backend’s #GDtlsServerConnection
310
 *   implementation, or %G_TYPE_INVALID if this backend doesn’t support DTLS.
311
 *
312
 * Since: 2.48
313
 */
314
GType
315
g_tls_backend_get_dtls_server_connection_type (GTlsBackend *backend)
316
0
{
317
0
  GTlsBackendInterface *iface;
318
319
0
  g_return_val_if_fail (G_IS_TLS_BACKEND (backend), G_TYPE_INVALID);
320
321
0
  iface = G_TLS_BACKEND_GET_INTERFACE (backend);
322
0
  if (iface->get_dtls_server_connection_type == NULL)
323
0
    return G_TYPE_INVALID;
324
325
0
  return iface->get_dtls_server_connection_type ();
326
0
}
327
328
/**
329
 * g_tls_backend_get_file_database_type:
330
 * @backend: the #GTlsBackend
331
 *
332
 * Gets the #GType of @backend's #GTlsFileDatabase implementation.
333
 *
334
 * Returns: the #GType of backend's #GTlsFileDatabase implementation.
335
 *
336
 * Since: 2.30
337
 */
338
GType
339
g_tls_backend_get_file_database_type (GTlsBackend *backend)
340
0
{
341
0
  g_return_val_if_fail (G_IS_TLS_BACKEND (backend), 0);
342
343
  /* This method was added later, so accept the (remote) possibility it can be NULL */
344
0
  if (!G_TLS_BACKEND_GET_INTERFACE (backend)->get_file_database_type)
345
0
    return 0;
346
347
0
  return G_TLS_BACKEND_GET_INTERFACE (backend)->get_file_database_type ();
348
0
}