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