gio/auto/tls_connection.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4#![allow(deprecated)]
5
6#[cfg(feature = "v2_70")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
8use crate::TlsProtocolVersion;
9use crate::{
10 ffi, AsyncResult, Cancellable, IOStream, TlsCertificate, TlsCertificateFlags, TlsDatabase,
11 TlsInteraction, TlsRehandshakeMode,
12};
13use glib::{
14 object::ObjectType as _,
15 prelude::*,
16 signal::{connect_raw, SignalHandlerId},
17 translate::*,
18};
19use std::{boxed::Box as Box_, pin::Pin};
20
21glib::wrapper! {
22 /// `GTlsConnection` is the base TLS connection class type, which wraps
23 /// a [`IOStream`][crate::IOStream] and provides TLS encryption on top of it. Its
24 /// subclasses, [`TlsClientConnection`][crate::TlsClientConnection] and
25 /// [`TlsServerConnection`][crate::TlsServerConnection], implement client-side and server-side TLS,
26 /// respectively.
27 ///
28 /// For DTLS (Datagram TLS) support, see [`DtlsConnection`][crate::DtlsConnection].
29 ///
30 /// This is an Abstract Base Class, you cannot instantiate it.
31 ///
32 /// ## Properties
33 ///
34 ///
35 /// #### `advertised-protocols`
36 /// The list of application-layer protocols that the connection
37 /// advertises that it is willing to speak. See
38 /// g_tls_connection_set_advertised_protocols().
39 ///
40 /// Readable | Writeable
41 ///
42 ///
43 /// #### `base-io-stream`
44 /// The #GIOStream that the connection wraps. The connection holds a reference
45 /// to this stream, and may run operations on the stream from other threads
46 /// throughout its lifetime. Consequently, after the #GIOStream has been
47 /// constructed, application code may only run its own operations on this
48 /// stream when no #GIOStream operations are running.
49 ///
50 /// Readable | Writeable | Construct Only
51 ///
52 ///
53 /// #### `certificate`
54 /// The connection's certificate; see
55 /// g_tls_connection_set_certificate().
56 ///
57 /// Readable | Writeable
58 ///
59 ///
60 /// #### `ciphersuite-name`
61 /// The name of the TLS ciphersuite in use. See g_tls_connection_get_ciphersuite_name().
62 ///
63 /// Readable
64 ///
65 ///
66 /// #### `database`
67 /// The certificate database to use when verifying this TLS connection.
68 /// If no certificate database is set, then the default database will be
69 /// used. See g_tls_backend_get_default_database().
70 ///
71 /// When using a non-default database, #GTlsConnection must fall back to using
72 /// the #GTlsDatabase to perform certificate verification using
73 /// g_tls_database_verify_chain(), which means certificate verification will
74 /// not be able to make use of TLS session context. This may be less secure.
75 /// For example, if you create your own #GTlsDatabase that just wraps the
76 /// default #GTlsDatabase, you might expect that you have not changed anything,
77 /// but this is not true because you may have altered the behavior of
78 /// #GTlsConnection by causing it to use g_tls_database_verify_chain(). See the
79 /// documentation of g_tls_database_verify_chain() for more details on specific
80 /// security checks that may not be performed. Accordingly, setting a
81 /// non-default database is discouraged except for specialty applications with
82 /// unusual security requirements.
83 ///
84 /// Readable | Writeable
85 ///
86 ///
87 /// #### `interaction`
88 /// A #GTlsInteraction object to be used when the connection or certificate
89 /// database need to interact with the user. This will be used to prompt the
90 /// user for passwords where necessary.
91 ///
92 /// Readable | Writeable
93 ///
94 ///
95 /// #### `negotiated-protocol`
96 /// The application-layer protocol negotiated during the TLS
97 /// handshake. See g_tls_connection_get_negotiated_protocol().
98 ///
99 /// Readable
100 ///
101 ///
102 /// #### `peer-certificate`
103 /// The connection's peer's certificate, after the TLS handshake has
104 /// completed or failed. Note in particular that this is not yet set
105 /// during the emission of #GTlsConnection::accept-certificate.
106 ///
107 /// (You can watch for a #GObject::notify signal on this property to
108 /// detect when a handshake has occurred.)
109 ///
110 /// Readable
111 ///
112 ///
113 /// #### `peer-certificate-errors`
114 /// The errors noticed while verifying
115 /// #GTlsConnection:peer-certificate. Normally this should be 0, but
116 /// it may not be if #GTlsClientConnection:validation-flags is not
117 /// [`TlsCertificateFlags::VALIDATE_ALL`][crate::TlsCertificateFlags::VALIDATE_ALL], or if
118 /// #GTlsConnection::accept-certificate overrode the default
119 /// behavior.
120 ///
121 /// GLib guarantees that if certificate verification fails, at least
122 /// one error will be set, but it does not guarantee that all possible
123 /// errors will be set. Accordingly, you may not safely decide to
124 /// ignore any particular type of error. For example, it would be
125 /// incorrect to mask [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow
126 /// expired certificates, because this could potentially be the only
127 /// error flag set even if other problems exist with the certificate.
128 ///
129 /// Readable
130 ///
131 ///
132 /// #### `protocol-version`
133 /// The TLS protocol version in use. See g_tls_connection_get_protocol_version().
134 ///
135 /// Readable
136 ///
137 ///
138 /// #### `rehandshake-mode`
139 /// The rehandshaking mode. See
140 /// g_tls_connection_set_rehandshake_mode().
141 ///
142 /// Readable | Writeable | Construct
143 ///
144 ///
145 /// #### `require-close-notify`
146 /// Whether or not proper TLS close notification is required.
147 /// See g_tls_connection_set_require_close_notify().
148 ///
149 /// Readable | Writeable | Construct
150 ///
151 ///
152 /// #### `use-system-certdb`
153 /// Whether or not the system certificate database will be used to
154 /// verify peer certificates. See
155 /// g_tls_connection_set_use_system_certdb().
156 ///
157 /// Readable | Writeable | Construct
158 /// <details><summary><h4>IOStream</h4></summary>
159 ///
160 ///
161 /// #### `closed`
162 /// Whether the stream is closed.
163 ///
164 /// Readable
165 ///
166 ///
167 /// #### `input-stream`
168 /// The [`InputStream`][crate::InputStream] to read from.
169 ///
170 /// Readable
171 ///
172 ///
173 /// #### `output-stream`
174 /// The [`OutputStream`][crate::OutputStream] to write to.
175 ///
176 /// Readable
177 /// </details>
178 ///
179 /// ## Signals
180 ///
181 ///
182 /// #### `accept-certificate`
183 /// Emitted during the TLS handshake after the peer certificate has
184 /// been received. You can examine @peer_cert's certification path by
185 /// calling g_tls_certificate_get_issuer() on it.
186 ///
187 /// For a client-side connection, @peer_cert is the server's
188 /// certificate, and the signal will only be emitted if the
189 /// certificate was not acceptable according to @conn's
190 /// #GTlsClientConnection:validation_flags. If you would like the
191 /// certificate to be accepted despite @errors, return [`true`] from the
192 /// signal handler. Otherwise, if no handler accepts the certificate,
193 /// the handshake will fail with [`TlsError::BadCertificate`][crate::TlsError::BadCertificate].
194 ///
195 /// GLib guarantees that if certificate verification fails, this signal
196 /// will be emitted with at least one error will be set in @errors, but
197 /// it does not guarantee that all possible errors will be set.
198 /// Accordingly, you may not safely decide to ignore any particular
199 /// type of error. For example, it would be incorrect to ignore
200 /// [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow expired
201 /// certificates, because this could potentially be the only error flag
202 /// set even if other problems exist with the certificate.
203 ///
204 /// For a server-side connection, @peer_cert is the certificate
205 /// presented by the client, if this was requested via the server's
206 /// #GTlsServerConnection:authentication_mode. On the server side,
207 /// the signal is always emitted when the client presents a
208 /// certificate, and the certificate will only be accepted if a
209 /// handler returns [`true`].
210 ///
211 /// Note that if this signal is emitted as part of asynchronous I/O
212 /// in the main thread, then you should not attempt to interact with
213 /// the user before returning from the signal handler. If you want to
214 /// let the user decide whether or not to accept the certificate, you
215 /// would have to return [`false`] from the signal handler on the first
216 /// attempt, and then after the connection attempt returns a
217 /// [`TlsError::BadCertificate`][crate::TlsError::BadCertificate], you can interact with the user, and
218 /// if the user decides to accept the certificate, remember that fact,
219 /// create a new connection, and return [`true`] from the signal handler
220 /// the next time.
221 ///
222 /// If you are doing I/O in another thread, you do not
223 /// need to worry about this, and can simply block in the signal
224 /// handler until the UI thread returns an answer.
225 ///
226 ///
227 ///
228 /// # Implements
229 ///
230 /// [`TlsConnectionExt`][trait@crate::prelude::TlsConnectionExt], [`IOStreamExt`][trait@crate::prelude::IOStreamExt], [`trait@glib::ObjectExt`], [`TlsConnectionExtManual`][trait@crate::prelude::TlsConnectionExtManual], [`IOStreamExtManual`][trait@crate::prelude::IOStreamExtManual]
231 #[doc(alias = "GTlsConnection")]
232 pub struct TlsConnection(Object<ffi::GTlsConnection, ffi::GTlsConnectionClass>) @extends IOStream;
233
234 match fn {
235 type_ => || ffi::g_tls_connection_get_type(),
236 }
237}
238
239impl TlsConnection {
240 pub const NONE: Option<&'static TlsConnection> = None;
241}
242
243/// Trait containing all [`struct@TlsConnection`] methods.
244///
245/// # Implementors
246///
247/// [`TlsClientConnection`][struct@crate::TlsClientConnection], [`TlsConnection`][struct@crate::TlsConnection], [`TlsServerConnection`][struct@crate::TlsServerConnection]
248pub trait TlsConnectionExt: IsA<TlsConnection> + 'static {
249 /// Used by #GTlsConnection implementations to emit the
250 /// #GTlsConnection::accept-certificate signal.
251 /// ## `peer_cert`
252 /// the peer's #GTlsCertificate
253 /// ## `errors`
254 /// the problems with @peer_cert
255 ///
256 /// # Returns
257 ///
258 /// [`true`] if one of the signal handlers has returned
259 /// [`true`] to accept @peer_cert
260 #[doc(alias = "g_tls_connection_emit_accept_certificate")]
261 fn emit_accept_certificate(
262 &self,
263 peer_cert: &impl IsA<TlsCertificate>,
264 errors: TlsCertificateFlags,
265 ) -> bool {
266 unsafe {
267 from_glib(ffi::g_tls_connection_emit_accept_certificate(
268 self.as_ref().to_glib_none().0,
269 peer_cert.as_ref().to_glib_none().0,
270 errors.into_glib(),
271 ))
272 }
273 }
274
275 /// Gets @self's certificate, as set by
276 /// g_tls_connection_set_certificate().
277 ///
278 /// # Returns
279 ///
280 /// @self's certificate, or [`None`]
281 #[doc(alias = "g_tls_connection_get_certificate")]
282 #[doc(alias = "get_certificate")]
283 fn certificate(&self) -> Option<TlsCertificate> {
284 unsafe {
285 from_glib_none(ffi::g_tls_connection_get_certificate(
286 self.as_ref().to_glib_none().0,
287 ))
288 }
289 }
290
291 /// Returns the name of the current TLS ciphersuite, or [`None`] if the
292 /// connection has not handshaked or has been closed. Beware that the TLS
293 /// backend may use any of multiple different naming conventions, because
294 /// OpenSSL and GnuTLS have their own ciphersuite naming conventions that
295 /// are different from each other and different from the standard, IANA-
296 /// registered ciphersuite names. The ciphersuite name is intended to be
297 /// displayed to the user for informative purposes only, and parsing it
298 /// is not recommended.
299 ///
300 /// # Returns
301 ///
302 /// The name of the current TLS ciphersuite, or [`None`]
303 #[cfg(feature = "v2_70")]
304 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
305 #[doc(alias = "g_tls_connection_get_ciphersuite_name")]
306 #[doc(alias = "get_ciphersuite_name")]
307 #[doc(alias = "ciphersuite-name")]
308 fn ciphersuite_name(&self) -> Option<glib::GString> {
309 unsafe {
310 from_glib_full(ffi::g_tls_connection_get_ciphersuite_name(
311 self.as_ref().to_glib_none().0,
312 ))
313 }
314 }
315
316 /// Gets the certificate database that @self uses to verify
317 /// peer certificates. See g_tls_connection_set_database().
318 ///
319 /// # Returns
320 ///
321 /// the certificate database that @self uses or [`None`]
322 #[doc(alias = "g_tls_connection_get_database")]
323 #[doc(alias = "get_database")]
324 fn database(&self) -> Option<TlsDatabase> {
325 unsafe {
326 from_glib_none(ffi::g_tls_connection_get_database(
327 self.as_ref().to_glib_none().0,
328 ))
329 }
330 }
331
332 /// Get the object that will be used to interact with the user. It will be used
333 /// for things like prompting the user for passwords. If [`None`] is returned, then
334 /// no user interaction will occur for this connection.
335 ///
336 /// # Returns
337 ///
338 /// The interaction object.
339 #[doc(alias = "g_tls_connection_get_interaction")]
340 #[doc(alias = "get_interaction")]
341 fn interaction(&self) -> Option<TlsInteraction> {
342 unsafe {
343 from_glib_none(ffi::g_tls_connection_get_interaction(
344 self.as_ref().to_glib_none().0,
345 ))
346 }
347 }
348
349 /// Gets the name of the application-layer protocol negotiated during
350 /// the handshake.
351 ///
352 /// If the peer did not use the ALPN extension, or did not advertise a
353 /// protocol that matched one of @self's protocols, or the TLS backend
354 /// does not support ALPN, then this will be [`None`]. See
355 /// g_tls_connection_set_advertised_protocols().
356 ///
357 /// # Returns
358 ///
359 /// the negotiated protocol, or [`None`]
360 #[cfg(feature = "v2_60")]
361 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
362 #[doc(alias = "g_tls_connection_get_negotiated_protocol")]
363 #[doc(alias = "get_negotiated_protocol")]
364 #[doc(alias = "negotiated-protocol")]
365 fn negotiated_protocol(&self) -> Option<glib::GString> {
366 unsafe {
367 from_glib_none(ffi::g_tls_connection_get_negotiated_protocol(
368 self.as_ref().to_glib_none().0,
369 ))
370 }
371 }
372
373 /// Gets @self's peer's certificate after the handshake has completed
374 /// or failed. (It is not set during the emission of
375 /// #GTlsConnection::accept-certificate.)
376 ///
377 /// # Returns
378 ///
379 /// @self's peer's certificate, or [`None`]
380 #[doc(alias = "g_tls_connection_get_peer_certificate")]
381 #[doc(alias = "get_peer_certificate")]
382 #[doc(alias = "peer-certificate")]
383 fn peer_certificate(&self) -> Option<TlsCertificate> {
384 unsafe {
385 from_glib_none(ffi::g_tls_connection_get_peer_certificate(
386 self.as_ref().to_glib_none().0,
387 ))
388 }
389 }
390
391 /// Gets the errors associated with validating @self's peer's
392 /// certificate, after the handshake has completed or failed. (It is
393 /// not set during the emission of #GTlsConnection::accept-certificate.)
394 ///
395 /// See #GTlsConnection:peer-certificate-errors for more information.
396 ///
397 /// # Returns
398 ///
399 /// @self's peer's certificate errors
400 #[doc(alias = "g_tls_connection_get_peer_certificate_errors")]
401 #[doc(alias = "get_peer_certificate_errors")]
402 #[doc(alias = "peer-certificate-errors")]
403 fn peer_certificate_errors(&self) -> TlsCertificateFlags {
404 unsafe {
405 from_glib(ffi::g_tls_connection_get_peer_certificate_errors(
406 self.as_ref().to_glib_none().0,
407 ))
408 }
409 }
410
411 /// Returns the current TLS protocol version, which may be
412 /// [`TlsProtocolVersion::Unknown`][crate::TlsProtocolVersion::Unknown] if the connection has not handshaked, or
413 /// has been closed, or if the TLS backend has implemented a protocol version
414 /// that is not a recognized #GTlsProtocolVersion.
415 ///
416 /// # Returns
417 ///
418 /// The current TLS protocol version
419 #[cfg(feature = "v2_70")]
420 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
421 #[doc(alias = "g_tls_connection_get_protocol_version")]
422 #[doc(alias = "get_protocol_version")]
423 #[doc(alias = "protocol-version")]
424 fn protocol_version(&self) -> TlsProtocolVersion {
425 unsafe {
426 from_glib(ffi::g_tls_connection_get_protocol_version(
427 self.as_ref().to_glib_none().0,
428 ))
429 }
430 }
431
432 /// Gets @self rehandshaking mode. See
433 /// g_tls_connection_set_rehandshake_mode() for details.
434 ///
435 /// # Deprecated since 2.60
436 ///
437 /// Changing the rehandshake mode is no longer
438 /// required for compatibility. Also, rehandshaking has been removed
439 /// from the TLS protocol in TLS 1.3.
440 ///
441 /// # Returns
442 ///
443 /// [`TlsRehandshakeMode::Safely`][crate::TlsRehandshakeMode::Safely]
444 #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
445 #[allow(deprecated)]
446 #[doc(alias = "g_tls_connection_get_rehandshake_mode")]
447 #[doc(alias = "get_rehandshake_mode")]
448 #[doc(alias = "rehandshake-mode")]
449 fn rehandshake_mode(&self) -> TlsRehandshakeMode {
450 unsafe {
451 from_glib(ffi::g_tls_connection_get_rehandshake_mode(
452 self.as_ref().to_glib_none().0,
453 ))
454 }
455 }
456
457 /// Tests whether or not @self expects a proper TLS close notification
458 /// when the connection is closed. See
459 /// g_tls_connection_set_require_close_notify() for details.
460 ///
461 /// # Returns
462 ///
463 /// [`true`] if @self requires a proper TLS close
464 /// notification.
465 #[doc(alias = "g_tls_connection_get_require_close_notify")]
466 #[doc(alias = "get_require_close_notify")]
467 #[doc(alias = "require-close-notify")]
468 fn requires_close_notify(&self) -> bool {
469 unsafe {
470 from_glib(ffi::g_tls_connection_get_require_close_notify(
471 self.as_ref().to_glib_none().0,
472 ))
473 }
474 }
475
476 /// Attempts a TLS handshake on @self.
477 ///
478 /// On the client side, it is never necessary to call this method;
479 /// although the connection needs to perform a handshake after
480 /// connecting (or after sending a "STARTTLS"-type command),
481 /// #GTlsConnection will handle this for you automatically when you try
482 /// to send or receive data on the connection. You can call
483 /// g_tls_connection_handshake() manually if you want to know whether
484 /// the initial handshake succeeded or failed (as opposed to just
485 /// immediately trying to use @self to read or write, in which case,
486 /// if it fails, it may not be possible to tell if it failed before or
487 /// after completing the handshake), but beware that servers may reject
488 /// client authentication after the handshake has completed, so a
489 /// successful handshake does not indicate the connection will be usable.
490 ///
491 /// Likewise, on the server side, although a handshake is necessary at
492 /// the beginning of the communication, you do not need to call this
493 /// function explicitly unless you want clearer error reporting.
494 ///
495 /// Previously, calling g_tls_connection_handshake() after the initial
496 /// handshake would trigger a rehandshake; however, this usage was
497 /// deprecated in GLib 2.60 because rehandshaking was removed from the
498 /// TLS protocol in TLS 1.3. Since GLib 2.64, calling this function after
499 /// the initial handshake will no longer do anything.
500 ///
501 /// When using a #GTlsConnection created by #GSocketClient, the
502 /// #GSocketClient performs the initial handshake, so calling this
503 /// function manually is not recommended.
504 ///
505 /// #GTlsConnection::accept_certificate may be emitted during the
506 /// handshake.
507 /// ## `cancellable`
508 /// a #GCancellable, or [`None`]
509 ///
510 /// # Returns
511 ///
512 /// success or failure
513 #[doc(alias = "g_tls_connection_handshake")]
514 fn handshake(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
515 unsafe {
516 let mut error = std::ptr::null_mut();
517 let is_ok = ffi::g_tls_connection_handshake(
518 self.as_ref().to_glib_none().0,
519 cancellable.map(|p| p.as_ref()).to_glib_none().0,
520 &mut error,
521 );
522 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
523 if error.is_null() {
524 Ok(())
525 } else {
526 Err(from_glib_full(error))
527 }
528 }
529 }
530
531 /// Asynchronously performs a TLS handshake on @self. See
532 /// g_tls_connection_handshake() for more information.
533 /// ## `io_priority`
534 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
535 /// ## `cancellable`
536 /// a #GCancellable, or [`None`]
537 /// ## `callback`
538 /// callback to call when the handshake is complete
539 #[doc(alias = "g_tls_connection_handshake_async")]
540 fn handshake_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
541 &self,
542 io_priority: glib::Priority,
543 cancellable: Option<&impl IsA<Cancellable>>,
544 callback: P,
545 ) {
546 let main_context = glib::MainContext::ref_thread_default();
547 let is_main_context_owner = main_context.is_owner();
548 let has_acquired_main_context = (!is_main_context_owner)
549 .then(|| main_context.acquire().ok())
550 .flatten();
551 assert!(
552 is_main_context_owner || has_acquired_main_context.is_some(),
553 "Async operations only allowed if the thread is owning the MainContext"
554 );
555
556 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
557 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
558 unsafe extern "C" fn handshake_async_trampoline<
559 P: FnOnce(Result<(), glib::Error>) + 'static,
560 >(
561 _source_object: *mut glib::gobject_ffi::GObject,
562 res: *mut crate::ffi::GAsyncResult,
563 user_data: glib::ffi::gpointer,
564 ) {
565 let mut error = std::ptr::null_mut();
566 ffi::g_tls_connection_handshake_finish(_source_object as *mut _, res, &mut error);
567 let result = if error.is_null() {
568 Ok(())
569 } else {
570 Err(from_glib_full(error))
571 };
572 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
573 Box_::from_raw(user_data as *mut _);
574 let callback: P = callback.into_inner();
575 callback(result);
576 }
577 let callback = handshake_async_trampoline::<P>;
578 unsafe {
579 ffi::g_tls_connection_handshake_async(
580 self.as_ref().to_glib_none().0,
581 io_priority.into_glib(),
582 cancellable.map(|p| p.as_ref()).to_glib_none().0,
583 Some(callback),
584 Box_::into_raw(user_data) as *mut _,
585 );
586 }
587 }
588
589 fn handshake_future(
590 &self,
591 io_priority: glib::Priority,
592 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
593 Box_::pin(crate::GioFuture::new(
594 self,
595 move |obj, cancellable, send| {
596 obj.handshake_async(io_priority, Some(cancellable), move |res| {
597 send.resolve(res);
598 });
599 },
600 ))
601 }
602
603 /// This sets the certificate that @self will present to its peer
604 /// during the TLS handshake. For a #GTlsServerConnection, it is
605 /// mandatory to set this, and that will normally be done at construct
606 /// time.
607 ///
608 /// For a #GTlsClientConnection, this is optional. If a handshake fails
609 /// with [`TlsError::CertificateRequired`][crate::TlsError::CertificateRequired], that means that the server
610 /// requires a certificate, and if you try connecting again, you should
611 /// call this method first. You can call
612 /// g_tls_client_connection_get_accepted_cas() on the failed connection
613 /// to get a list of Certificate Authorities that the server will
614 /// accept certificates from.
615 ///
616 /// (It is also possible that a server will allow the connection with
617 /// or without a certificate; in that case, if you don't provide a
618 /// certificate, you can tell that the server requested one by the fact
619 /// that g_tls_client_connection_get_accepted_cas() will return
620 /// non-[`None`].)
621 /// ## `certificate`
622 /// the certificate to use for @self
623 #[doc(alias = "g_tls_connection_set_certificate")]
624 #[doc(alias = "certificate")]
625 fn set_certificate(&self, certificate: &impl IsA<TlsCertificate>) {
626 unsafe {
627 ffi::g_tls_connection_set_certificate(
628 self.as_ref().to_glib_none().0,
629 certificate.as_ref().to_glib_none().0,
630 );
631 }
632 }
633
634 /// Sets the certificate database that is used to verify peer certificates.
635 /// This is set to the default database by default. See
636 /// g_tls_backend_get_default_database(). If set to [`None`], then
637 /// peer certificate validation will always set the
638 /// [`TlsCertificateFlags::UNKNOWN_CA`][crate::TlsCertificateFlags::UNKNOWN_CA] error (meaning
639 /// #GTlsConnection::accept-certificate will always be emitted on
640 /// client-side connections, unless that bit is not set in
641 /// #GTlsClientConnection:validation-flags).
642 ///
643 /// There are nonintuitive security implications when using a non-default
644 /// database. See #GTlsConnection:database for details.
645 /// ## `database`
646 /// a #GTlsDatabase
647 #[doc(alias = "g_tls_connection_set_database")]
648 #[doc(alias = "database")]
649 fn set_database(&self, database: Option<&impl IsA<TlsDatabase>>) {
650 unsafe {
651 ffi::g_tls_connection_set_database(
652 self.as_ref().to_glib_none().0,
653 database.map(|p| p.as_ref()).to_glib_none().0,
654 );
655 }
656 }
657
658 /// Set the object that will be used to interact with the user. It will be used
659 /// for things like prompting the user for passwords.
660 ///
661 /// The @interaction argument will normally be a derived subclass of
662 /// #GTlsInteraction. [`None`] can also be provided if no user interaction
663 /// should occur for this connection.
664 /// ## `interaction`
665 /// an interaction object, or [`None`]
666 #[doc(alias = "g_tls_connection_set_interaction")]
667 #[doc(alias = "interaction")]
668 fn set_interaction(&self, interaction: Option<&impl IsA<TlsInteraction>>) {
669 unsafe {
670 ffi::g_tls_connection_set_interaction(
671 self.as_ref().to_glib_none().0,
672 interaction.map(|p| p.as_ref()).to_glib_none().0,
673 );
674 }
675 }
676
677 /// Since GLib 2.64, changing the rehandshake mode is no longer supported
678 /// and will have no effect. With TLS 1.3, rehandshaking has been removed from
679 /// the TLS protocol, replaced by separate post-handshake authentication and
680 /// rekey operations.
681 ///
682 /// # Deprecated since 2.60
683 ///
684 /// Changing the rehandshake mode is no longer
685 /// required for compatibility. Also, rehandshaking has been removed
686 /// from the TLS protocol in TLS 1.3.
687 /// ## `mode`
688 /// the rehandshaking mode
689 #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
690 #[allow(deprecated)]
691 #[doc(alias = "g_tls_connection_set_rehandshake_mode")]
692 #[doc(alias = "rehandshake-mode")]
693 fn set_rehandshake_mode(&self, mode: TlsRehandshakeMode) {
694 unsafe {
695 ffi::g_tls_connection_set_rehandshake_mode(
696 self.as_ref().to_glib_none().0,
697 mode.into_glib(),
698 );
699 }
700 }
701
702 /// Sets whether or not @self expects a proper TLS close notification
703 /// before the connection is closed. If this is [`true`] (the default),
704 /// then @self will expect to receive a TLS close notification from its
705 /// peer before the connection is closed, and will return a
706 /// [`TlsError::Eof`][crate::TlsError::Eof] error if the connection is closed without proper
707 /// notification (since this may indicate a network error, or
708 /// man-in-the-middle attack).
709 ///
710 /// In some protocols, the application will know whether or not the
711 /// connection was closed cleanly based on application-level data
712 /// (because the application-level data includes a length field, or is
713 /// somehow self-delimiting); in this case, the close notify is
714 /// redundant and sometimes omitted. (TLS 1.1 explicitly allows this;
715 /// in TLS 1.0 it is technically an error, but often done anyway.) You
716 /// can use g_tls_connection_set_require_close_notify() to tell @self
717 /// to allow an "unannounced" connection close, in which case the close
718 /// will show up as a 0-length read, as in a non-TLS
719 /// #GSocketConnection, and it is up to the application to check that
720 /// the data has been fully received.
721 ///
722 /// Note that this only affects the behavior when the peer closes the
723 /// connection; when the application calls g_io_stream_close() itself
724 /// on @self, this will send a close notification regardless of the
725 /// setting of this property. If you explicitly want to do an unclean
726 /// close, you can close @self's #GTlsConnection:base-io-stream rather
727 /// than closing @self itself, but note that this may only be done when no other
728 /// operations are pending on @self or the base I/O stream.
729 /// ## `require_close_notify`
730 /// whether or not to require close notification
731 #[doc(alias = "g_tls_connection_set_require_close_notify")]
732 #[doc(alias = "require-close-notify")]
733 fn set_require_close_notify(&self, require_close_notify: bool) {
734 unsafe {
735 ffi::g_tls_connection_set_require_close_notify(
736 self.as_ref().to_glib_none().0,
737 require_close_notify.into_glib(),
738 );
739 }
740 }
741
742 /// The list of application-layer protocols that the connection
743 /// advertises that it is willing to speak. See
744 /// g_tls_connection_set_advertised_protocols().
745 #[cfg(feature = "v2_60")]
746 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
747 #[doc(alias = "advertised-protocols")]
748 fn advertised_protocols(&self) -> Vec<glib::GString> {
749 ObjectExt::property(self.as_ref(), "advertised-protocols")
750 }
751
752 /// The #GIOStream that the connection wraps. The connection holds a reference
753 /// to this stream, and may run operations on the stream from other threads
754 /// throughout its lifetime. Consequently, after the #GIOStream has been
755 /// constructed, application code may only run its own operations on this
756 /// stream when no #GIOStream operations are running.
757 #[doc(alias = "base-io-stream")]
758 fn base_io_stream(&self) -> Option<IOStream> {
759 ObjectExt::property(self.as_ref(), "base-io-stream")
760 }
761
762 /// Emitted during the TLS handshake after the peer certificate has
763 /// been received. You can examine @peer_cert's certification path by
764 /// calling g_tls_certificate_get_issuer() on it.
765 ///
766 /// For a client-side connection, @peer_cert is the server's
767 /// certificate, and the signal will only be emitted if the
768 /// certificate was not acceptable according to @conn's
769 /// #GTlsClientConnection:validation_flags. If you would like the
770 /// certificate to be accepted despite @errors, return [`true`] from the
771 /// signal handler. Otherwise, if no handler accepts the certificate,
772 /// the handshake will fail with [`TlsError::BadCertificate`][crate::TlsError::BadCertificate].
773 ///
774 /// GLib guarantees that if certificate verification fails, this signal
775 /// will be emitted with at least one error will be set in @errors, but
776 /// it does not guarantee that all possible errors will be set.
777 /// Accordingly, you may not safely decide to ignore any particular
778 /// type of error. For example, it would be incorrect to ignore
779 /// [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow expired
780 /// certificates, because this could potentially be the only error flag
781 /// set even if other problems exist with the certificate.
782 ///
783 /// For a server-side connection, @peer_cert is the certificate
784 /// presented by the client, if this was requested via the server's
785 /// #GTlsServerConnection:authentication_mode. On the server side,
786 /// the signal is always emitted when the client presents a
787 /// certificate, and the certificate will only be accepted if a
788 /// handler returns [`true`].
789 ///
790 /// Note that if this signal is emitted as part of asynchronous I/O
791 /// in the main thread, then you should not attempt to interact with
792 /// the user before returning from the signal handler. If you want to
793 /// let the user decide whether or not to accept the certificate, you
794 /// would have to return [`false`] from the signal handler on the first
795 /// attempt, and then after the connection attempt returns a
796 /// [`TlsError::BadCertificate`][crate::TlsError::BadCertificate], you can interact with the user, and
797 /// if the user decides to accept the certificate, remember that fact,
798 /// create a new connection, and return [`true`] from the signal handler
799 /// the next time.
800 ///
801 /// If you are doing I/O in another thread, you do not
802 /// need to worry about this, and can simply block in the signal
803 /// handler until the UI thread returns an answer.
804 /// ## `peer_cert`
805 /// the peer's #GTlsCertificate
806 /// ## `errors`
807 /// the problems with @peer_cert.
808 ///
809 /// # Returns
810 ///
811 /// [`true`] to accept @peer_cert (which will also
812 /// immediately end the signal emission). [`false`] to allow the signal
813 /// emission to continue, which will cause the handshake to fail if
814 /// no one else overrides it.
815 #[doc(alias = "accept-certificate")]
816 fn connect_accept_certificate<
817 F: Fn(&Self, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
818 >(
819 &self,
820 f: F,
821 ) -> SignalHandlerId {
822 unsafe extern "C" fn accept_certificate_trampoline<
823 P: IsA<TlsConnection>,
824 F: Fn(&P, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
825 >(
826 this: *mut ffi::GTlsConnection,
827 peer_cert: *mut ffi::GTlsCertificate,
828 errors: ffi::GTlsCertificateFlags,
829 f: glib::ffi::gpointer,
830 ) -> glib::ffi::gboolean {
831 let f: &F = &*(f as *const F);
832 f(
833 TlsConnection::from_glib_borrow(this).unsafe_cast_ref(),
834 &from_glib_borrow(peer_cert),
835 from_glib(errors),
836 )
837 .into_glib()
838 }
839 unsafe {
840 let f: Box_<F> = Box_::new(f);
841 connect_raw(
842 self.as_ptr() as *mut _,
843 c"accept-certificate".as_ptr() as *const _,
844 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
845 accept_certificate_trampoline::<Self, F> as *const (),
846 )),
847 Box_::into_raw(f),
848 )
849 }
850 }
851
852 #[cfg(feature = "v2_60")]
853 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
854 #[doc(alias = "advertised-protocols")]
855 fn connect_advertised_protocols_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
856 unsafe extern "C" fn notify_advertised_protocols_trampoline<
857 P: IsA<TlsConnection>,
858 F: Fn(&P) + 'static,
859 >(
860 this: *mut ffi::GTlsConnection,
861 _param_spec: glib::ffi::gpointer,
862 f: glib::ffi::gpointer,
863 ) {
864 let f: &F = &*(f as *const F);
865 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
866 }
867 unsafe {
868 let f: Box_<F> = Box_::new(f);
869 connect_raw(
870 self.as_ptr() as *mut _,
871 c"notify::advertised-protocols".as_ptr() as *const _,
872 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
873 notify_advertised_protocols_trampoline::<Self, F> as *const (),
874 )),
875 Box_::into_raw(f),
876 )
877 }
878 }
879
880 #[doc(alias = "certificate")]
881 fn connect_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
882 unsafe extern "C" fn notify_certificate_trampoline<
883 P: IsA<TlsConnection>,
884 F: Fn(&P) + 'static,
885 >(
886 this: *mut ffi::GTlsConnection,
887 _param_spec: glib::ffi::gpointer,
888 f: glib::ffi::gpointer,
889 ) {
890 let f: &F = &*(f as *const F);
891 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
892 }
893 unsafe {
894 let f: Box_<F> = Box_::new(f);
895 connect_raw(
896 self.as_ptr() as *mut _,
897 c"notify::certificate".as_ptr() as *const _,
898 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
899 notify_certificate_trampoline::<Self, F> as *const (),
900 )),
901 Box_::into_raw(f),
902 )
903 }
904 }
905
906 #[cfg(feature = "v2_70")]
907 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
908 #[doc(alias = "ciphersuite-name")]
909 fn connect_ciphersuite_name_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
910 unsafe extern "C" fn notify_ciphersuite_name_trampoline<
911 P: IsA<TlsConnection>,
912 F: Fn(&P) + 'static,
913 >(
914 this: *mut ffi::GTlsConnection,
915 _param_spec: glib::ffi::gpointer,
916 f: glib::ffi::gpointer,
917 ) {
918 let f: &F = &*(f as *const F);
919 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
920 }
921 unsafe {
922 let f: Box_<F> = Box_::new(f);
923 connect_raw(
924 self.as_ptr() as *mut _,
925 c"notify::ciphersuite-name".as_ptr() as *const _,
926 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
927 notify_ciphersuite_name_trampoline::<Self, F> as *const (),
928 )),
929 Box_::into_raw(f),
930 )
931 }
932 }
933
934 #[doc(alias = "database")]
935 fn connect_database_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
936 unsafe extern "C" fn notify_database_trampoline<
937 P: IsA<TlsConnection>,
938 F: Fn(&P) + 'static,
939 >(
940 this: *mut ffi::GTlsConnection,
941 _param_spec: glib::ffi::gpointer,
942 f: glib::ffi::gpointer,
943 ) {
944 let f: &F = &*(f as *const F);
945 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
946 }
947 unsafe {
948 let f: Box_<F> = Box_::new(f);
949 connect_raw(
950 self.as_ptr() as *mut _,
951 c"notify::database".as_ptr() as *const _,
952 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
953 notify_database_trampoline::<Self, F> as *const (),
954 )),
955 Box_::into_raw(f),
956 )
957 }
958 }
959
960 #[doc(alias = "interaction")]
961 fn connect_interaction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
962 unsafe extern "C" fn notify_interaction_trampoline<
963 P: IsA<TlsConnection>,
964 F: Fn(&P) + 'static,
965 >(
966 this: *mut ffi::GTlsConnection,
967 _param_spec: glib::ffi::gpointer,
968 f: glib::ffi::gpointer,
969 ) {
970 let f: &F = &*(f as *const F);
971 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
972 }
973 unsafe {
974 let f: Box_<F> = Box_::new(f);
975 connect_raw(
976 self.as_ptr() as *mut _,
977 c"notify::interaction".as_ptr() as *const _,
978 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
979 notify_interaction_trampoline::<Self, F> as *const (),
980 )),
981 Box_::into_raw(f),
982 )
983 }
984 }
985
986 #[cfg(feature = "v2_60")]
987 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
988 #[doc(alias = "negotiated-protocol")]
989 fn connect_negotiated_protocol_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
990 unsafe extern "C" fn notify_negotiated_protocol_trampoline<
991 P: IsA<TlsConnection>,
992 F: Fn(&P) + 'static,
993 >(
994 this: *mut ffi::GTlsConnection,
995 _param_spec: glib::ffi::gpointer,
996 f: glib::ffi::gpointer,
997 ) {
998 let f: &F = &*(f as *const F);
999 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1000 }
1001 unsafe {
1002 let f: Box_<F> = Box_::new(f);
1003 connect_raw(
1004 self.as_ptr() as *mut _,
1005 c"notify::negotiated-protocol".as_ptr() as *const _,
1006 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1007 notify_negotiated_protocol_trampoline::<Self, F> as *const (),
1008 )),
1009 Box_::into_raw(f),
1010 )
1011 }
1012 }
1013
1014 #[doc(alias = "peer-certificate")]
1015 fn connect_peer_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1016 unsafe extern "C" fn notify_peer_certificate_trampoline<
1017 P: IsA<TlsConnection>,
1018 F: Fn(&P) + 'static,
1019 >(
1020 this: *mut ffi::GTlsConnection,
1021 _param_spec: glib::ffi::gpointer,
1022 f: glib::ffi::gpointer,
1023 ) {
1024 let f: &F = &*(f as *const F);
1025 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1026 }
1027 unsafe {
1028 let f: Box_<F> = Box_::new(f);
1029 connect_raw(
1030 self.as_ptr() as *mut _,
1031 c"notify::peer-certificate".as_ptr() as *const _,
1032 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1033 notify_peer_certificate_trampoline::<Self, F> as *const (),
1034 )),
1035 Box_::into_raw(f),
1036 )
1037 }
1038 }
1039
1040 #[doc(alias = "peer-certificate-errors")]
1041 fn connect_peer_certificate_errors_notify<F: Fn(&Self) + 'static>(
1042 &self,
1043 f: F,
1044 ) -> SignalHandlerId {
1045 unsafe extern "C" fn notify_peer_certificate_errors_trampoline<
1046 P: IsA<TlsConnection>,
1047 F: Fn(&P) + 'static,
1048 >(
1049 this: *mut ffi::GTlsConnection,
1050 _param_spec: glib::ffi::gpointer,
1051 f: glib::ffi::gpointer,
1052 ) {
1053 let f: &F = &*(f as *const F);
1054 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1055 }
1056 unsafe {
1057 let f: Box_<F> = Box_::new(f);
1058 connect_raw(
1059 self.as_ptr() as *mut _,
1060 c"notify::peer-certificate-errors".as_ptr() as *const _,
1061 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1062 notify_peer_certificate_errors_trampoline::<Self, F> as *const (),
1063 )),
1064 Box_::into_raw(f),
1065 )
1066 }
1067 }
1068
1069 #[cfg(feature = "v2_70")]
1070 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
1071 #[doc(alias = "protocol-version")]
1072 fn connect_protocol_version_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1073 unsafe extern "C" fn notify_protocol_version_trampoline<
1074 P: IsA<TlsConnection>,
1075 F: Fn(&P) + 'static,
1076 >(
1077 this: *mut ffi::GTlsConnection,
1078 _param_spec: glib::ffi::gpointer,
1079 f: glib::ffi::gpointer,
1080 ) {
1081 let f: &F = &*(f as *const F);
1082 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1083 }
1084 unsafe {
1085 let f: Box_<F> = Box_::new(f);
1086 connect_raw(
1087 self.as_ptr() as *mut _,
1088 c"notify::protocol-version".as_ptr() as *const _,
1089 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1090 notify_protocol_version_trampoline::<Self, F> as *const (),
1091 )),
1092 Box_::into_raw(f),
1093 )
1094 }
1095 }
1096
1097 #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
1098 #[doc(alias = "rehandshake-mode")]
1099 fn connect_rehandshake_mode_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1100 unsafe extern "C" fn notify_rehandshake_mode_trampoline<
1101 P: IsA<TlsConnection>,
1102 F: Fn(&P) + 'static,
1103 >(
1104 this: *mut ffi::GTlsConnection,
1105 _param_spec: glib::ffi::gpointer,
1106 f: glib::ffi::gpointer,
1107 ) {
1108 let f: &F = &*(f as *const F);
1109 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1110 }
1111 unsafe {
1112 let f: Box_<F> = Box_::new(f);
1113 connect_raw(
1114 self.as_ptr() as *mut _,
1115 c"notify::rehandshake-mode".as_ptr() as *const _,
1116 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1117 notify_rehandshake_mode_trampoline::<Self, F> as *const (),
1118 )),
1119 Box_::into_raw(f),
1120 )
1121 }
1122 }
1123
1124 #[doc(alias = "require-close-notify")]
1125 fn connect_require_close_notify_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1126 unsafe extern "C" fn notify_require_close_notify_trampoline<
1127 P: IsA<TlsConnection>,
1128 F: Fn(&P) + 'static,
1129 >(
1130 this: *mut ffi::GTlsConnection,
1131 _param_spec: glib::ffi::gpointer,
1132 f: glib::ffi::gpointer,
1133 ) {
1134 let f: &F = &*(f as *const F);
1135 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1136 }
1137 unsafe {
1138 let f: Box_<F> = Box_::new(f);
1139 connect_raw(
1140 self.as_ptr() as *mut _,
1141 c"notify::require-close-notify".as_ptr() as *const _,
1142 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1143 notify_require_close_notify_trampoline::<Self, F> as *const (),
1144 )),
1145 Box_::into_raw(f),
1146 )
1147 }
1148 }
1149}
1150
1151impl<O: IsA<TlsConnection>> TlsConnectionExt for O {}