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 ffi::g_tls_connection_handshake_finish(_source_object as *mut _, res, &mut error);
572 let result = if error.is_null() {
573 Ok(())
574 } else {
575 Err(from_glib_full(error))
576 };
577 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
578 Box_::from_raw(user_data as *mut _);
579 let callback: P = callback.into_inner();
580 callback(result);
581 }
582 let callback = handshake_async_trampoline::<P>;
583 unsafe {
584 ffi::g_tls_connection_handshake_async(
585 self.as_ref().to_glib_none().0,
586 io_priority.into_glib(),
587 cancellable.map(|p| p.as_ref()).to_glib_none().0,
588 Some(callback),
589 Box_::into_raw(user_data) as *mut _,
590 );
591 }
592 }
593
594 fn handshake_future(
595 &self,
596 io_priority: glib::Priority,
597 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
598 Box_::pin(crate::GioFuture::new(
599 self,
600 move |obj, cancellable, send| {
601 obj.handshake_async(io_priority, Some(cancellable), move |res| {
602 send.resolve(res);
603 });
604 },
605 ))
606 }
607
608 /// This sets the certificate that @self will present to its peer
609 /// during the TLS handshake. For a #GTlsServerConnection, it is
610 /// mandatory to set this, and that will normally be done at construct
611 /// time.
612 ///
613 /// For a #GTlsClientConnection, this is optional. If a handshake fails
614 /// with [`TlsError::CertificateRequired`][crate::TlsError::CertificateRequired], that means that the server
615 /// requires a certificate, and if you try connecting again, you should
616 /// call this method first. You can call
617 /// g_tls_client_connection_get_accepted_cas() on the failed connection
618 /// to get a list of Certificate Authorities that the server will
619 /// accept certificates from.
620 ///
621 /// (It is also possible that a server will allow the connection with
622 /// or without a certificate; in that case, if you don't provide a
623 /// certificate, you can tell that the server requested one by the fact
624 /// that g_tls_client_connection_get_accepted_cas() will return
625 /// non-[`None`].)
626 /// ## `certificate`
627 /// the certificate to use for @self
628 #[doc(alias = "g_tls_connection_set_certificate")]
629 #[doc(alias = "certificate")]
630 fn set_certificate(&self, certificate: &impl IsA<TlsCertificate>) {
631 unsafe {
632 ffi::g_tls_connection_set_certificate(
633 self.as_ref().to_glib_none().0,
634 certificate.as_ref().to_glib_none().0,
635 );
636 }
637 }
638
639 /// Sets the certificate database that is used to verify peer certificates.
640 /// This is set to the default database by default. See
641 /// g_tls_backend_get_default_database(). If set to [`None`], then
642 /// peer certificate validation will always set the
643 /// [`TlsCertificateFlags::UNKNOWN_CA`][crate::TlsCertificateFlags::UNKNOWN_CA] error (meaning
644 /// #GTlsConnection::accept-certificate will always be emitted on
645 /// client-side connections, unless that bit is not set in
646 /// #GTlsClientConnection:validation-flags).
647 ///
648 /// There are nonintuitive security implications when using a non-default
649 /// database. See #GTlsConnection:database for details.
650 /// ## `database`
651 /// a #GTlsDatabase
652 #[doc(alias = "g_tls_connection_set_database")]
653 #[doc(alias = "database")]
654 fn set_database(&self, database: Option<&impl IsA<TlsDatabase>>) {
655 unsafe {
656 ffi::g_tls_connection_set_database(
657 self.as_ref().to_glib_none().0,
658 database.map(|p| p.as_ref()).to_glib_none().0,
659 );
660 }
661 }
662
663 /// Set the object that will be used to interact with the user. It will be used
664 /// for things like prompting the user for passwords.
665 ///
666 /// The @interaction argument will normally be a derived subclass of
667 /// #GTlsInteraction. [`None`] can also be provided if no user interaction
668 /// should occur for this connection.
669 /// ## `interaction`
670 /// an interaction object, or [`None`]
671 #[doc(alias = "g_tls_connection_set_interaction")]
672 #[doc(alias = "interaction")]
673 fn set_interaction(&self, interaction: Option<&impl IsA<TlsInteraction>>) {
674 unsafe {
675 ffi::g_tls_connection_set_interaction(
676 self.as_ref().to_glib_none().0,
677 interaction.map(|p| p.as_ref()).to_glib_none().0,
678 );
679 }
680 }
681
682 /// Since GLib 2.64, changing the rehandshake mode is no longer supported
683 /// and will have no effect. With TLS 1.3, rehandshaking has been removed from
684 /// the TLS protocol, replaced by separate post-handshake authentication and
685 /// rekey operations.
686 ///
687 /// # Deprecated since 2.60
688 ///
689 /// Changing the rehandshake mode is no longer
690 /// required for compatibility. Also, rehandshaking has been removed
691 /// from the TLS protocol in TLS 1.3.
692 /// ## `mode`
693 /// the rehandshaking mode
694 #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
695 #[allow(deprecated)]
696 #[doc(alias = "g_tls_connection_set_rehandshake_mode")]
697 #[doc(alias = "rehandshake-mode")]
698 fn set_rehandshake_mode(&self, mode: TlsRehandshakeMode) {
699 unsafe {
700 ffi::g_tls_connection_set_rehandshake_mode(
701 self.as_ref().to_glib_none().0,
702 mode.into_glib(),
703 );
704 }
705 }
706
707 /// Sets whether or not @self expects a proper TLS close notification
708 /// before the connection is closed. If this is [`true`] (the default),
709 /// then @self will expect to receive a TLS close notification from its
710 /// peer before the connection is closed, and will return a
711 /// [`TlsError::Eof`][crate::TlsError::Eof] error if the connection is closed without proper
712 /// notification (since this may indicate a network error, or
713 /// man-in-the-middle attack).
714 ///
715 /// In some protocols, the application will know whether or not the
716 /// connection was closed cleanly based on application-level data
717 /// (because the application-level data includes a length field, or is
718 /// somehow self-delimiting); in this case, the close notify is
719 /// redundant and sometimes omitted. (TLS 1.1 explicitly allows this;
720 /// in TLS 1.0 it is technically an error, but often done anyway.) You
721 /// can use g_tls_connection_set_require_close_notify() to tell @self
722 /// to allow an "unannounced" connection close, in which case the close
723 /// will show up as a 0-length read, as in a non-TLS
724 /// #GSocketConnection, and it is up to the application to check that
725 /// the data has been fully received.
726 ///
727 /// Note that this only affects the behavior when the peer closes the
728 /// connection; when the application calls g_io_stream_close() itself
729 /// on @self, this will send a close notification regardless of the
730 /// setting of this property. If you explicitly want to do an unclean
731 /// close, you can close @self's #GTlsConnection:base-io-stream rather
732 /// than closing @self itself, but note that this may only be done when no other
733 /// operations are pending on @self or the base I/O stream.
734 /// ## `require_close_notify`
735 /// whether or not to require close notification
736 #[doc(alias = "g_tls_connection_set_require_close_notify")]
737 #[doc(alias = "require-close-notify")]
738 fn set_require_close_notify(&self, require_close_notify: bool) {
739 unsafe {
740 ffi::g_tls_connection_set_require_close_notify(
741 self.as_ref().to_glib_none().0,
742 require_close_notify.into_glib(),
743 );
744 }
745 }
746
747 /// The list of application-layer protocols that the connection
748 /// advertises that it is willing to speak. See
749 /// g_tls_connection_set_advertised_protocols().
750 #[cfg(feature = "v2_60")]
751 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
752 #[doc(alias = "advertised-protocols")]
753 fn advertised_protocols(&self) -> Vec<glib::GString> {
754 ObjectExt::property(self.as_ref(), "advertised-protocols")
755 }
756
757 /// The #GIOStream that the connection wraps. The connection holds a reference
758 /// to this stream, and may run operations on the stream from other threads
759 /// throughout its lifetime. Consequently, after the #GIOStream has been
760 /// constructed, application code may only run its own operations on this
761 /// stream when no #GIOStream operations are running.
762 #[doc(alias = "base-io-stream")]
763 fn base_io_stream(&self) -> Option<IOStream> {
764 ObjectExt::property(self.as_ref(), "base-io-stream")
765 }
766
767 /// Emitted during the TLS handshake after the peer certificate has
768 /// been received. You can examine @peer_cert's certification path by
769 /// calling g_tls_certificate_get_issuer() on it.
770 ///
771 /// For a client-side connection, @peer_cert is the server's
772 /// certificate, and the signal will only be emitted if the
773 /// certificate was not acceptable according to @conn's
774 /// #GTlsClientConnection:validation_flags. If you would like the
775 /// certificate to be accepted despite @errors, return [`true`] from the
776 /// signal handler. Otherwise, if no handler accepts the certificate,
777 /// the handshake will fail with [`TlsError::BadCertificate`][crate::TlsError::BadCertificate].
778 ///
779 /// GLib guarantees that if certificate verification fails, this signal
780 /// will be emitted with at least one error will be set in @errors, but
781 /// it does not guarantee that all possible errors will be set.
782 /// Accordingly, you may not safely decide to ignore any particular
783 /// type of error. For example, it would be incorrect to ignore
784 /// [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow expired
785 /// certificates, because this could potentially be the only error flag
786 /// set even if other problems exist with the certificate.
787 ///
788 /// For a server-side connection, @peer_cert is the certificate
789 /// presented by the client, if this was requested via the server's
790 /// #GTlsServerConnection:authentication_mode. On the server side,
791 /// the signal is always emitted when the client presents a
792 /// certificate, and the certificate will only be accepted if a
793 /// handler returns [`true`].
794 ///
795 /// Note that if this signal is emitted as part of asynchronous I/O
796 /// in the main thread, then you should not attempt to interact with
797 /// the user before returning from the signal handler. If you want to
798 /// let the user decide whether or not to accept the certificate, you
799 /// would have to return [`false`] from the signal handler on the first
800 /// attempt, and then after the connection attempt returns a
801 /// [`TlsError::BadCertificate`][crate::TlsError::BadCertificate], you can interact with the user, and
802 /// if the user decides to accept the certificate, remember that fact,
803 /// create a new connection, and return [`true`] from the signal handler
804 /// the next time.
805 ///
806 /// If you are doing I/O in another thread, you do not
807 /// need to worry about this, and can simply block in the signal
808 /// handler until the UI thread returns an answer.
809 /// ## `peer_cert`
810 /// the peer's #GTlsCertificate
811 /// ## `errors`
812 /// the problems with @peer_cert.
813 ///
814 /// # Returns
815 ///
816 /// [`true`] to accept @peer_cert (which will also
817 /// immediately end the signal emission). [`false`] to allow the signal
818 /// emission to continue, which will cause the handshake to fail if
819 /// no one else overrides it.
820 #[doc(alias = "accept-certificate")]
821 fn connect_accept_certificate<
822 F: Fn(&Self, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
823 >(
824 &self,
825 f: F,
826 ) -> SignalHandlerId {
827 unsafe extern "C" fn accept_certificate_trampoline<
828 P: IsA<TlsConnection>,
829 F: Fn(&P, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
830 >(
831 this: *mut ffi::GTlsConnection,
832 peer_cert: *mut ffi::GTlsCertificate,
833 errors: ffi::GTlsCertificateFlags,
834 f: glib::ffi::gpointer,
835 ) -> glib::ffi::gboolean {
836 let f: &F = &*(f as *const F);
837 f(
838 TlsConnection::from_glib_borrow(this).unsafe_cast_ref(),
839 &from_glib_borrow(peer_cert),
840 from_glib(errors),
841 )
842 .into_glib()
843 }
844 unsafe {
845 let f: Box_<F> = Box_::new(f);
846 connect_raw(
847 self.as_ptr() as *mut _,
848 b"accept-certificate\0".as_ptr() as *const _,
849 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
850 accept_certificate_trampoline::<Self, F> as *const (),
851 )),
852 Box_::into_raw(f),
853 )
854 }
855 }
856
857 #[cfg(feature = "v2_60")]
858 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
859 #[doc(alias = "advertised-protocols")]
860 fn connect_advertised_protocols_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
861 unsafe extern "C" fn notify_advertised_protocols_trampoline<
862 P: IsA<TlsConnection>,
863 F: Fn(&P) + 'static,
864 >(
865 this: *mut ffi::GTlsConnection,
866 _param_spec: glib::ffi::gpointer,
867 f: glib::ffi::gpointer,
868 ) {
869 let f: &F = &*(f as *const F);
870 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
871 }
872 unsafe {
873 let f: Box_<F> = Box_::new(f);
874 connect_raw(
875 self.as_ptr() as *mut _,
876 b"notify::advertised-protocols\0".as_ptr() as *const _,
877 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
878 notify_advertised_protocols_trampoline::<Self, F> as *const (),
879 )),
880 Box_::into_raw(f),
881 )
882 }
883 }
884
885 #[doc(alias = "certificate")]
886 fn connect_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
887 unsafe extern "C" fn notify_certificate_trampoline<
888 P: IsA<TlsConnection>,
889 F: Fn(&P) + 'static,
890 >(
891 this: *mut ffi::GTlsConnection,
892 _param_spec: glib::ffi::gpointer,
893 f: glib::ffi::gpointer,
894 ) {
895 let f: &F = &*(f as *const F);
896 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
897 }
898 unsafe {
899 let f: Box_<F> = Box_::new(f);
900 connect_raw(
901 self.as_ptr() as *mut _,
902 b"notify::certificate\0".as_ptr() as *const _,
903 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
904 notify_certificate_trampoline::<Self, F> as *const (),
905 )),
906 Box_::into_raw(f),
907 )
908 }
909 }
910
911 #[cfg(feature = "v2_70")]
912 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
913 #[doc(alias = "ciphersuite-name")]
914 fn connect_ciphersuite_name_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
915 unsafe extern "C" fn notify_ciphersuite_name_trampoline<
916 P: IsA<TlsConnection>,
917 F: Fn(&P) + 'static,
918 >(
919 this: *mut ffi::GTlsConnection,
920 _param_spec: glib::ffi::gpointer,
921 f: glib::ffi::gpointer,
922 ) {
923 let f: &F = &*(f as *const F);
924 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
925 }
926 unsafe {
927 let f: Box_<F> = Box_::new(f);
928 connect_raw(
929 self.as_ptr() as *mut _,
930 b"notify::ciphersuite-name\0".as_ptr() as *const _,
931 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
932 notify_ciphersuite_name_trampoline::<Self, F> as *const (),
933 )),
934 Box_::into_raw(f),
935 )
936 }
937 }
938
939 #[doc(alias = "database")]
940 fn connect_database_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
941 unsafe extern "C" fn notify_database_trampoline<
942 P: IsA<TlsConnection>,
943 F: Fn(&P) + 'static,
944 >(
945 this: *mut ffi::GTlsConnection,
946 _param_spec: glib::ffi::gpointer,
947 f: glib::ffi::gpointer,
948 ) {
949 let f: &F = &*(f as *const F);
950 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
951 }
952 unsafe {
953 let f: Box_<F> = Box_::new(f);
954 connect_raw(
955 self.as_ptr() as *mut _,
956 b"notify::database\0".as_ptr() as *const _,
957 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
958 notify_database_trampoline::<Self, F> as *const (),
959 )),
960 Box_::into_raw(f),
961 )
962 }
963 }
964
965 #[doc(alias = "interaction")]
966 fn connect_interaction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
967 unsafe extern "C" fn notify_interaction_trampoline<
968 P: IsA<TlsConnection>,
969 F: Fn(&P) + 'static,
970 >(
971 this: *mut ffi::GTlsConnection,
972 _param_spec: glib::ffi::gpointer,
973 f: glib::ffi::gpointer,
974 ) {
975 let f: &F = &*(f as *const F);
976 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
977 }
978 unsafe {
979 let f: Box_<F> = Box_::new(f);
980 connect_raw(
981 self.as_ptr() as *mut _,
982 b"notify::interaction\0".as_ptr() as *const _,
983 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
984 notify_interaction_trampoline::<Self, F> as *const (),
985 )),
986 Box_::into_raw(f),
987 )
988 }
989 }
990
991 #[cfg(feature = "v2_60")]
992 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
993 #[doc(alias = "negotiated-protocol")]
994 fn connect_negotiated_protocol_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
995 unsafe extern "C" fn notify_negotiated_protocol_trampoline<
996 P: IsA<TlsConnection>,
997 F: Fn(&P) + 'static,
998 >(
999 this: *mut ffi::GTlsConnection,
1000 _param_spec: glib::ffi::gpointer,
1001 f: glib::ffi::gpointer,
1002 ) {
1003 let f: &F = &*(f as *const F);
1004 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1005 }
1006 unsafe {
1007 let f: Box_<F> = Box_::new(f);
1008 connect_raw(
1009 self.as_ptr() as *mut _,
1010 b"notify::negotiated-protocol\0".as_ptr() as *const _,
1011 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1012 notify_negotiated_protocol_trampoline::<Self, F> as *const (),
1013 )),
1014 Box_::into_raw(f),
1015 )
1016 }
1017 }
1018
1019 #[doc(alias = "peer-certificate")]
1020 fn connect_peer_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1021 unsafe extern "C" fn notify_peer_certificate_trampoline<
1022 P: IsA<TlsConnection>,
1023 F: Fn(&P) + 'static,
1024 >(
1025 this: *mut ffi::GTlsConnection,
1026 _param_spec: glib::ffi::gpointer,
1027 f: glib::ffi::gpointer,
1028 ) {
1029 let f: &F = &*(f as *const F);
1030 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1031 }
1032 unsafe {
1033 let f: Box_<F> = Box_::new(f);
1034 connect_raw(
1035 self.as_ptr() as *mut _,
1036 b"notify::peer-certificate\0".as_ptr() as *const _,
1037 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1038 notify_peer_certificate_trampoline::<Self, F> as *const (),
1039 )),
1040 Box_::into_raw(f),
1041 )
1042 }
1043 }
1044
1045 #[doc(alias = "peer-certificate-errors")]
1046 fn connect_peer_certificate_errors_notify<F: Fn(&Self) + 'static>(
1047 &self,
1048 f: F,
1049 ) -> SignalHandlerId {
1050 unsafe extern "C" fn notify_peer_certificate_errors_trampoline<
1051 P: IsA<TlsConnection>,
1052 F: Fn(&P) + 'static,
1053 >(
1054 this: *mut ffi::GTlsConnection,
1055 _param_spec: glib::ffi::gpointer,
1056 f: glib::ffi::gpointer,
1057 ) {
1058 let f: &F = &*(f as *const F);
1059 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1060 }
1061 unsafe {
1062 let f: Box_<F> = Box_::new(f);
1063 connect_raw(
1064 self.as_ptr() as *mut _,
1065 b"notify::peer-certificate-errors\0".as_ptr() as *const _,
1066 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1067 notify_peer_certificate_errors_trampoline::<Self, F> as *const (),
1068 )),
1069 Box_::into_raw(f),
1070 )
1071 }
1072 }
1073
1074 #[cfg(feature = "v2_70")]
1075 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
1076 #[doc(alias = "protocol-version")]
1077 fn connect_protocol_version_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1078 unsafe extern "C" fn notify_protocol_version_trampoline<
1079 P: IsA<TlsConnection>,
1080 F: Fn(&P) + 'static,
1081 >(
1082 this: *mut ffi::GTlsConnection,
1083 _param_spec: glib::ffi::gpointer,
1084 f: glib::ffi::gpointer,
1085 ) {
1086 let f: &F = &*(f as *const F);
1087 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1088 }
1089 unsafe {
1090 let f: Box_<F> = Box_::new(f);
1091 connect_raw(
1092 self.as_ptr() as *mut _,
1093 b"notify::protocol-version\0".as_ptr() as *const _,
1094 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1095 notify_protocol_version_trampoline::<Self, F> as *const (),
1096 )),
1097 Box_::into_raw(f),
1098 )
1099 }
1100 }
1101
1102 #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
1103 #[doc(alias = "rehandshake-mode")]
1104 fn connect_rehandshake_mode_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1105 unsafe extern "C" fn notify_rehandshake_mode_trampoline<
1106 P: IsA<TlsConnection>,
1107 F: Fn(&P) + 'static,
1108 >(
1109 this: *mut ffi::GTlsConnection,
1110 _param_spec: glib::ffi::gpointer,
1111 f: glib::ffi::gpointer,
1112 ) {
1113 let f: &F = &*(f as *const F);
1114 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1115 }
1116 unsafe {
1117 let f: Box_<F> = Box_::new(f);
1118 connect_raw(
1119 self.as_ptr() as *mut _,
1120 b"notify::rehandshake-mode\0".as_ptr() as *const _,
1121 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1122 notify_rehandshake_mode_trampoline::<Self, F> as *const (),
1123 )),
1124 Box_::into_raw(f),
1125 )
1126 }
1127 }
1128
1129 #[doc(alias = "require-close-notify")]
1130 fn connect_require_close_notify_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1131 unsafe extern "C" fn notify_require_close_notify_trampoline<
1132 P: IsA<TlsConnection>,
1133 F: Fn(&P) + 'static,
1134 >(
1135 this: *mut ffi::GTlsConnection,
1136 _param_spec: glib::ffi::gpointer,
1137 f: glib::ffi::gpointer,
1138 ) {
1139 let f: &F = &*(f as *const F);
1140 f(TlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1141 }
1142 unsafe {
1143 let f: Box_<F> = Box_::new(f);
1144 connect_raw(
1145 self.as_ptr() as *mut _,
1146 b"notify::require-close-notify\0".as_ptr() as *const _,
1147 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1148 notify_require_close_notify_trampoline::<Self, F> as *const (),
1149 )),
1150 Box_::into_raw(f),
1151 )
1152 }
1153 }
1154}
1155
1156impl<O: IsA<TlsConnection>> TlsConnectionExt for O {}