Change LGPL-2.1+ to LGPL-2.1-or-later
[platform/upstream/glib.git] / gio / gdummytlsbackend.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2010 Red Hat, Inc.
4  * Copyright © 2015 Collabora, Ltd.
5  *
6  * SPDX-License-Identifier: LGPL-2.1-or-later
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General
19  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "config.h"
23
24 #include "gdummytlsbackend.h"
25
26 #include <glib.h>
27
28 #include "gasyncresult.h"
29 #include "gcancellable.h"
30 #include "ginitable.h"
31 #include "gdtlsclientconnection.h"
32 #include "gdtlsconnection.h"
33 #include "gdtlsserverconnection.h"
34 #include "gtlsbackend.h"
35 #include "gtlscertificate.h"
36 #include "gtlsclientconnection.h"
37 #include "gtlsdatabase.h"
38 #include "gtlsfiledatabase.h"
39 #include "gtlsserverconnection.h"
40
41 #include "giomodule.h"
42 #include "giomodule-priv.h"
43
44 #include "glibintl.h"
45
46 static GType _g_dummy_tls_certificate_get_type (void);
47 static GType _g_dummy_tls_connection_get_type (void);
48 static GType _g_dummy_dtls_connection_get_type (void);
49 static GType _g_dummy_tls_database_get_type (void);
50
51 struct _GDummyTlsBackend {
52   GObject       parent_instance;
53   GTlsDatabase *database;
54 };
55
56 static void g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface);
57
58 #define g_dummy_tls_backend_get_type _g_dummy_tls_backend_get_type
59 G_DEFINE_TYPE_WITH_CODE (GDummyTlsBackend, g_dummy_tls_backend, G_TYPE_OBJECT,
60                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_BACKEND,
61                                                 g_dummy_tls_backend_iface_init)
62                          _g_io_modules_ensure_extension_points_registered ();
63                          g_io_extension_point_implement (G_TLS_BACKEND_EXTENSION_POINT_NAME,
64                                                          g_define_type_id,
65                                                          "dummy",
66                                                          -100);)
67
68 static void
69 g_dummy_tls_backend_init (GDummyTlsBackend *dummy)
70 {
71 }
72
73 static void
74 g_dummy_tls_backend_finalize (GObject *object)
75 {
76   GDummyTlsBackend *dummy = G_DUMMY_TLS_BACKEND (object);
77
78   g_clear_object (&dummy->database);
79
80   G_OBJECT_CLASS (g_dummy_tls_backend_parent_class)->finalize (object);
81 }
82
83 static void
84 g_dummy_tls_backend_class_init (GDummyTlsBackendClass *backend_class)
85 {
86   GObjectClass *object_class = G_OBJECT_CLASS (backend_class);
87
88   object_class->finalize = g_dummy_tls_backend_finalize;
89 }
90
91 static GTlsDatabase *
92 g_dummy_tls_backend_get_default_database (GTlsBackend *backend)
93 {
94   GDummyTlsBackend *dummy = G_DUMMY_TLS_BACKEND (backend);
95
96   if (g_once_init_enter (&dummy->database))
97     {
98       GTlsDatabase *tlsdb;
99
100       tlsdb = g_object_new (_g_dummy_tls_database_get_type (), NULL);
101       g_once_init_leave (&dummy->database, tlsdb);
102     }
103
104   return g_object_ref (dummy->database);
105 }
106
107 static void
108 g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface)
109 {
110   iface->get_certificate_type = _g_dummy_tls_certificate_get_type;
111   iface->get_client_connection_type = _g_dummy_tls_connection_get_type;
112   iface->get_server_connection_type = _g_dummy_tls_connection_get_type;
113   iface->get_dtls_client_connection_type = _g_dummy_dtls_connection_get_type;
114   iface->get_dtls_server_connection_type = _g_dummy_dtls_connection_get_type;
115   iface->get_file_database_type = _g_dummy_tls_database_get_type;
116   iface->get_default_database = g_dummy_tls_backend_get_default_database;
117 }
118
119 /* Dummy certificate type */
120
121 typedef struct _GDummyTlsCertificate      GDummyTlsCertificate;
122 typedef struct _GDummyTlsCertificateClass GDummyTlsCertificateClass;
123
124 struct _GDummyTlsCertificate {
125   GTlsCertificate parent_instance;
126 };
127
128 struct _GDummyTlsCertificateClass {
129   GTlsCertificateClass parent_class;
130 };
131
132 enum
133 {
134   PROP_CERTIFICATE_0,
135
136   PROP_CERT_CERTIFICATE,
137   PROP_CERT_CERTIFICATE_PEM,
138   PROP_CERT_PRIVATE_KEY,
139   PROP_CERT_PRIVATE_KEY_PEM,
140   PROP_CERT_ISSUER
141 };
142
143 static void g_dummy_tls_certificate_initable_iface_init (GInitableIface *iface);
144
145 #define g_dummy_tls_certificate_get_type _g_dummy_tls_certificate_get_type
146 G_DEFINE_TYPE_WITH_CODE (GDummyTlsCertificate, g_dummy_tls_certificate, G_TYPE_TLS_CERTIFICATE,
147                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
148                                                 g_dummy_tls_certificate_initable_iface_init))
149
150 static void
151 g_dummy_tls_certificate_get_property (GObject    *object,
152                                       guint       prop_id,
153                                       GValue     *value,
154                                       GParamSpec *pspec)
155 {
156   /* We need to define this method to make GObject happy, but it will
157    * never be possible to construct a working GDummyTlsCertificate, so
158    * it doesn't have to do anything useful.
159    */
160 }
161
162 static void
163 g_dummy_tls_certificate_set_property (GObject      *object,
164                                       guint         prop_id,
165                                       const GValue *value,
166                                       GParamSpec   *pspec)
167 {
168   /* Just ignore all attempts to set properties. */
169 }
170
171 static void
172 g_dummy_tls_certificate_class_init (GDummyTlsCertificateClass *certificate_class)
173 {
174   GObjectClass *gobject_class = G_OBJECT_CLASS (certificate_class);
175
176   gobject_class->get_property = g_dummy_tls_certificate_get_property;
177   gobject_class->set_property = g_dummy_tls_certificate_set_property;
178
179   g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE, "certificate");
180   g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE_PEM, "certificate-pem");
181   g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY, "private-key");
182   g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PEM, "private-key-pem");
183   g_object_class_override_property (gobject_class, PROP_CERT_ISSUER, "issuer");
184 }
185
186 static void
187 g_dummy_tls_certificate_init (GDummyTlsCertificate *certificate)
188 {
189 }
190
191 static gboolean
192 g_dummy_tls_certificate_initable_init (GInitable       *initable,
193                                        GCancellable    *cancellable,
194                                        GError         **error)
195 {
196   g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
197                        _("TLS support is not available"));
198   return FALSE;
199 }
200
201 static void
202 g_dummy_tls_certificate_initable_iface_init (GInitableIface  *iface)
203 {
204   iface->init = g_dummy_tls_certificate_initable_init;
205 }
206
207 /* Dummy connection type; since GTlsClientConnection and
208  * GTlsServerConnection are just interfaces, we can implement them
209  * both on a single object.
210  */
211
212 typedef struct _GDummyTlsConnection      GDummyTlsConnection;
213 typedef struct _GDummyTlsConnectionClass GDummyTlsConnectionClass;
214
215 struct _GDummyTlsConnection {
216   GTlsConnection parent_instance;
217 };
218
219 struct _GDummyTlsConnectionClass {
220   GTlsConnectionClass parent_class;
221 };
222
223 enum
224 {
225   PROP_CONNECTION_0,
226
227   PROP_CONN_BASE_IO_STREAM,
228   PROP_CONN_USE_SYSTEM_CERTDB,
229   PROP_CONN_REQUIRE_CLOSE_NOTIFY,
230   PROP_CONN_REHANDSHAKE_MODE,
231   PROP_CONN_CERTIFICATE,
232   PROP_CONN_DATABASE,
233   PROP_CONN_INTERACTION,
234   PROP_CONN_PEER_CERTIFICATE,
235   PROP_CONN_PEER_CERTIFICATE_ERRORS,
236   PROP_CONN_VALIDATION_FLAGS,
237   PROP_CONN_SERVER_IDENTITY,
238   PROP_CONN_USE_SSL3,
239   PROP_CONN_ACCEPTED_CAS,
240   PROP_CONN_AUTHENTICATION_MODE,
241   PROP_CONN_ADVERTISED_PROTOCOLS,
242   PROP_CONN_NEGOTIATED_PROTOCOL,
243 };
244
245 static void g_dummy_tls_connection_initable_iface_init (GInitableIface *iface);
246
247 #define g_dummy_tls_connection_get_type _g_dummy_tls_connection_get_type
248 G_DEFINE_TYPE_WITH_CODE (GDummyTlsConnection, g_dummy_tls_connection, G_TYPE_TLS_CONNECTION,
249                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_CLIENT_CONNECTION, NULL)
250                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION, NULL)
251                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
252                                                 g_dummy_tls_connection_initable_iface_init))
253
254 static void
255 g_dummy_tls_connection_get_property (GObject    *object,
256                                      guint       prop_id,
257                                      GValue     *value,
258                                      GParamSpec *pspec)
259 {
260 }
261
262 static void
263 g_dummy_tls_connection_set_property (GObject      *object,
264                                      guint         prop_id,
265                                      const GValue *value,
266                                      GParamSpec   *pspec)
267 {
268 }
269
270 static gboolean
271 g_dummy_tls_connection_close (GIOStream     *stream,
272                               GCancellable  *cancellable,
273                               GError       **error)
274 {
275   return TRUE;
276 }
277
278 static void
279 g_dummy_tls_connection_class_init (GDummyTlsConnectionClass *connection_class)
280 {
281   GObjectClass *gobject_class = G_OBJECT_CLASS (connection_class);
282   GIOStreamClass *io_stream_class = G_IO_STREAM_CLASS (connection_class);
283
284   gobject_class->get_property = g_dummy_tls_connection_get_property;
285   gobject_class->set_property = g_dummy_tls_connection_set_property;
286
287   /* Need to override this because when initable_init fails it will
288    * dispose the connection, which will close it, which would
289    * otherwise try to close its input/output streams, which don't
290    * exist.
291    */
292   io_stream_class->close_fn = g_dummy_tls_connection_close;
293
294   g_object_class_override_property (gobject_class, PROP_CONN_BASE_IO_STREAM, "base-io-stream");
295   g_object_class_override_property (gobject_class, PROP_CONN_USE_SYSTEM_CERTDB, "use-system-certdb");
296   g_object_class_override_property (gobject_class, PROP_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
297   g_object_class_override_property (gobject_class, PROP_CONN_REHANDSHAKE_MODE, "rehandshake-mode");
298   g_object_class_override_property (gobject_class, PROP_CONN_CERTIFICATE, "certificate");
299   g_object_class_override_property (gobject_class, PROP_CONN_DATABASE, "database");
300   g_object_class_override_property (gobject_class, PROP_CONN_INTERACTION, "interaction");
301   g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE, "peer-certificate");
302   g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
303   g_object_class_override_property (gobject_class, PROP_CONN_VALIDATION_FLAGS, "validation-flags");
304   g_object_class_override_property (gobject_class, PROP_CONN_SERVER_IDENTITY, "server-identity");
305   g_object_class_override_property (gobject_class, PROP_CONN_USE_SSL3, "use-ssl3");
306   g_object_class_override_property (gobject_class, PROP_CONN_ACCEPTED_CAS, "accepted-cas");
307   g_object_class_override_property (gobject_class, PROP_CONN_AUTHENTICATION_MODE, "authentication-mode");
308   g_object_class_override_property (gobject_class, PROP_CONN_ADVERTISED_PROTOCOLS, "advertised-protocols");
309   g_object_class_override_property (gobject_class, PROP_CONN_NEGOTIATED_PROTOCOL, "negotiated-protocol");
310 }
311
312 static void
313 g_dummy_tls_connection_init (GDummyTlsConnection *connection)
314 {
315 }
316
317 static gboolean
318 g_dummy_tls_connection_initable_init (GInitable       *initable,
319                                       GCancellable    *cancellable,
320                                       GError         **error)
321 {
322   g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
323                        _("TLS support is not available"));
324   return FALSE;
325 }
326
327 static void
328 g_dummy_tls_connection_initable_iface_init (GInitableIface  *iface)
329 {
330   iface->init = g_dummy_tls_connection_initable_init;
331 }
332
333 /* Dummy DTLS connection type; since GDtlsClientConnection and
334  * GDtlsServerConnection are just interfaces, we can implement them
335  * both on a single object.
336  */
337
338 typedef struct _GDummyDtlsConnection      GDummyDtlsConnection;
339 typedef struct _GDummyDtlsConnectionClass GDummyDtlsConnectionClass;
340
341 struct _GDummyDtlsConnection {
342   GObject parent_instance;
343 };
344
345 struct _GDummyDtlsConnectionClass {
346   GObjectClass parent_class;
347 };
348
349 enum
350 {
351   PROP_DTLS_CONN_BASE_SOCKET = 1,
352   PROP_DTLS_CONN_REQUIRE_CLOSE_NOTIFY,
353   PROP_DTLS_CONN_REHANDSHAKE_MODE,
354   PROP_DTLS_CONN_CERTIFICATE,
355   PROP_DTLS_CONN_DATABASE,
356   PROP_DTLS_CONN_INTERACTION,
357   PROP_DTLS_CONN_PEER_CERTIFICATE,
358   PROP_DTLS_CONN_PEER_CERTIFICATE_ERRORS,
359   PROP_DTLS_CONN_VALIDATION_FLAGS,
360   PROP_DTLS_CONN_SERVER_IDENTITY,
361   PROP_DTLS_CONN_ENABLE_NEGOTIATION,
362   PROP_DTLS_CONN_ACCEPTED_CAS,
363   PROP_DTLS_CONN_AUTHENTICATION_MODE,
364 };
365
366 static void g_dummy_dtls_connection_initable_iface_init (GInitableIface *iface);
367
368 #define g_dummy_dtls_connection_get_type _g_dummy_dtls_connection_get_type
369 G_DEFINE_TYPE_WITH_CODE (GDummyDtlsConnection, g_dummy_dtls_connection, G_TYPE_OBJECT,
370                          G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CONNECTION, NULL);
371                          G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CLIENT_CONNECTION, NULL);
372                          G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_SERVER_CONNECTION, NULL);
373                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
374                                                 g_dummy_dtls_connection_initable_iface_init);)
375
376 static void
377 g_dummy_dtls_connection_get_property (GObject    *object,
378                                       guint       prop_id,
379                                       GValue     *value,
380                                       GParamSpec *pspec)
381 {
382 }
383
384 static void
385 g_dummy_dtls_connection_set_property (GObject      *object,
386                                       guint         prop_id,
387                                       const GValue *value,
388                                       GParamSpec   *pspec)
389 {
390 }
391
392 static void
393 g_dummy_dtls_connection_class_init (GDummyDtlsConnectionClass *connection_class)
394 {
395   GObjectClass *gobject_class = G_OBJECT_CLASS (connection_class);
396
397   gobject_class->get_property = g_dummy_dtls_connection_get_property;
398   gobject_class->set_property = g_dummy_dtls_connection_set_property;
399
400   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_BASE_SOCKET, "base-socket");
401   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
402   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_REHANDSHAKE_MODE, "rehandshake-mode");
403   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_CERTIFICATE, "certificate");
404   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_DATABASE, "database");
405   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_INTERACTION, "interaction");
406   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_PEER_CERTIFICATE, "peer-certificate");
407   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
408   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_VALIDATION_FLAGS, "validation-flags");
409   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_SERVER_IDENTITY, "server-identity");
410   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_ACCEPTED_CAS, "accepted-cas");
411   g_object_class_override_property (gobject_class, PROP_DTLS_CONN_AUTHENTICATION_MODE, "authentication-mode");
412 }
413
414 static void
415 g_dummy_dtls_connection_init (GDummyDtlsConnection *connection)
416 {
417 }
418
419 static gboolean
420 g_dummy_dtls_connection_initable_init (GInitable       *initable,
421                                        GCancellable    *cancellable,
422                                        GError         **error)
423 {
424   g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
425                        _("DTLS support is not available"));
426   return FALSE;
427 }
428
429 static void
430 g_dummy_dtls_connection_initable_iface_init (GInitableIface  *iface)
431 {
432   iface->init = g_dummy_dtls_connection_initable_init;
433 }
434
435 /* Dummy database type.
436  */
437
438 typedef struct _GDummyTlsDatabase      GDummyTlsDatabase;
439 typedef struct _GDummyTlsDatabaseClass GDummyTlsDatabaseClass;
440
441 struct _GDummyTlsDatabase {
442   GTlsDatabase parent_instance;
443 };
444
445 struct _GDummyTlsDatabaseClass {
446   GTlsDatabaseClass parent_class;
447 };
448
449 enum
450 {
451   PROP_DATABASE_0,
452
453   PROP_ANCHORS,
454 };
455
456 static void g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface *iface);
457 static void g_dummy_tls_database_initable_iface_init (GInitableIface *iface);
458
459 #define g_dummy_tls_database_get_type _g_dummy_tls_database_get_type
460 G_DEFINE_TYPE_WITH_CODE (GDummyTlsDatabase, g_dummy_tls_database, G_TYPE_TLS_DATABASE,
461                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
462                                                 g_dummy_tls_database_file_database_iface_init)
463                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
464                                                 g_dummy_tls_database_initable_iface_init))
465
466
467 static void
468 g_dummy_tls_database_get_property (GObject    *object,
469                                    guint       prop_id,
470                                    GValue     *value,
471                                    GParamSpec *pspec)
472 {
473   /* We need to define this method to make GObject happy, but it will
474    * never be possible to construct a working GDummyTlsDatabase, so
475    * it doesn't have to do anything useful.
476    */
477 }
478
479 static void
480 g_dummy_tls_database_set_property (GObject      *object,
481                                    guint         prop_id,
482                                    const GValue *value,
483                                    GParamSpec   *pspec)
484 {
485   /* Just ignore all attempts to set properties. */
486 }
487
488 static void
489 g_dummy_tls_database_class_init (GDummyTlsDatabaseClass *database_class)
490 {
491   GObjectClass *gobject_class = G_OBJECT_CLASS (database_class);
492
493   gobject_class->get_property = g_dummy_tls_database_get_property;
494   gobject_class->set_property = g_dummy_tls_database_set_property;
495
496   g_object_class_override_property (gobject_class, PROP_ANCHORS, "anchors");
497 }
498
499 static void
500 g_dummy_tls_database_init (GDummyTlsDatabase *database)
501 {
502 }
503
504 static void
505 g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface  *iface)
506 {
507 }
508
509 static gboolean
510 g_dummy_tls_database_initable_init (GInitable       *initable,
511                                     GCancellable    *cancellable,
512                                     GError         **error)
513 {
514   g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
515                        _("TLS support is not available"));
516   return FALSE;
517 }
518
519 static void
520 g_dummy_tls_database_initable_iface_init (GInitableIface  *iface)
521 {
522   iface->init = g_dummy_tls_database_initable_init;
523 }