1#[cfg(feature = "futures")]
6use futures::future;
7use gio_sys;
8use glib;
9use glib::object::Cast;
10use glib::object::IsA;
11use glib::signal::connect_raw;
12use glib::signal::SignalHandlerId;
13use glib::translate::*;
14use glib::StaticType;
15use glib::Value;
16use glib_sys;
17use gobject_sys;
18use std::boxed::Box as Box_;
19use std::fmt;
20use std::mem::transmute;
21use std::ptr;
22use Cancellable;
23use Error;
24use IOStream;
25use TlsCertificate;
26use TlsCertificateFlags;
27use TlsDatabase;
28use TlsInteraction;
29use TlsRehandshakeMode;
30
31glib_wrapper! {
32 pub struct TlsConnection(Object<gio_sys::GTlsConnection, gio_sys::GTlsConnectionClass, TlsConnectionClass>) @extends IOStream;
33
34 match fn {
35 get_type => || gio_sys::g_tls_connection_get_type(),
36 }
37}
38
39pub const NONE_TLS_CONNECTION: Option<&TlsConnection> = None;
40
41pub trait TlsConnectionExt: 'static {
42 fn emit_accept_certificate<P: IsA<TlsCertificate>>(
43 &self,
44 peer_cert: &P,
45 errors: TlsCertificateFlags,
46 ) -> bool;
47
48 fn get_certificate(&self) -> Option<TlsCertificate>;
49
50 fn get_database(&self) -> Option<TlsDatabase>;
51
52 fn get_interaction(&self) -> Option<TlsInteraction>;
53
54 fn get_peer_certificate(&self) -> Option<TlsCertificate>;
55
56 fn get_peer_certificate_errors(&self) -> TlsCertificateFlags;
57
58 fn get_rehandshake_mode(&self) -> TlsRehandshakeMode;
59
60 fn get_require_close_notify(&self) -> bool;
61
62 fn handshake<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error>;
63
64 fn handshake_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
65 &self,
66 io_priority: glib::Priority,
67 cancellable: Option<&P>,
68 callback: Q,
69 );
70
71 #[cfg(feature = "futures")]
72 fn handshake_async_future(
73 &self,
74 io_priority: glib::Priority,
75 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
76
77 fn set_certificate<P: IsA<TlsCertificate>>(&self, certificate: &P);
78
79 fn set_database<P: IsA<TlsDatabase>>(&self, database: &P);
80
81 fn set_interaction<P: IsA<TlsInteraction>>(&self, interaction: Option<&P>);
82
83 fn set_rehandshake_mode(&self, mode: TlsRehandshakeMode);
84
85 fn set_require_close_notify(&self, require_close_notify: bool);
86
87 fn get_property_base_io_stream(&self) -> Option<IOStream>;
88
89 fn connect_accept_certificate<
90 F: Fn(&Self, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
91 >(
92 &self,
93 f: F,
94 ) -> SignalHandlerId;
95
96 fn connect_property_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
97
98 fn connect_property_database_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
99
100 fn connect_property_interaction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
101
102 fn connect_property_peer_certificate_notify<F: Fn(&Self) + 'static>(
103 &self,
104 f: F,
105 ) -> SignalHandlerId;
106
107 fn connect_property_peer_certificate_errors_notify<F: Fn(&Self) + 'static>(
108 &self,
109 f: F,
110 ) -> SignalHandlerId;
111
112 fn connect_property_rehandshake_mode_notify<F: Fn(&Self) + 'static>(
113 &self,
114 f: F,
115 ) -> SignalHandlerId;
116
117 fn connect_property_require_close_notify_notify<F: Fn(&Self) + 'static>(
118 &self,
119 f: F,
120 ) -> SignalHandlerId;
121}
122
123impl<O: IsA<TlsConnection>> TlsConnectionExt for O {
124 fn emit_accept_certificate<P: IsA<TlsCertificate>>(
125 &self,
126 peer_cert: &P,
127 errors: TlsCertificateFlags,
128 ) -> bool {
129 unsafe {
130 from_glib(gio_sys::g_tls_connection_emit_accept_certificate(
131 self.as_ref().to_glib_none().0,
132 peer_cert.as_ref().to_glib_none().0,
133 errors.to_glib(),
134 ))
135 }
136 }
137
138 fn get_certificate(&self) -> Option<TlsCertificate> {
139 unsafe {
140 from_glib_none(gio_sys::g_tls_connection_get_certificate(
141 self.as_ref().to_glib_none().0,
142 ))
143 }
144 }
145
146 fn get_database(&self) -> Option<TlsDatabase> {
147 unsafe {
148 from_glib_none(gio_sys::g_tls_connection_get_database(
149 self.as_ref().to_glib_none().0,
150 ))
151 }
152 }
153
154 fn get_interaction(&self) -> Option<TlsInteraction> {
155 unsafe {
156 from_glib_none(gio_sys::g_tls_connection_get_interaction(
157 self.as_ref().to_glib_none().0,
158 ))
159 }
160 }
161
162 fn get_peer_certificate(&self) -> Option<TlsCertificate> {
163 unsafe {
164 from_glib_none(gio_sys::g_tls_connection_get_peer_certificate(
165 self.as_ref().to_glib_none().0,
166 ))
167 }
168 }
169
170 fn get_peer_certificate_errors(&self) -> TlsCertificateFlags {
171 unsafe {
172 from_glib(gio_sys::g_tls_connection_get_peer_certificate_errors(
173 self.as_ref().to_glib_none().0,
174 ))
175 }
176 }
177
178 fn get_rehandshake_mode(&self) -> TlsRehandshakeMode {
179 unsafe {
180 from_glib(gio_sys::g_tls_connection_get_rehandshake_mode(
181 self.as_ref().to_glib_none().0,
182 ))
183 }
184 }
185
186 fn get_require_close_notify(&self) -> bool {
187 unsafe {
188 from_glib(gio_sys::g_tls_connection_get_require_close_notify(
189 self.as_ref().to_glib_none().0,
190 ))
191 }
192 }
193
194 fn handshake<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error> {
195 unsafe {
196 let mut error = ptr::null_mut();
197 let _ = gio_sys::g_tls_connection_handshake(
198 self.as_ref().to_glib_none().0,
199 cancellable.map(|p| p.as_ref()).to_glib_none().0,
200 &mut error,
201 );
202 if error.is_null() {
203 Ok(())
204 } else {
205 Err(from_glib_full(error))
206 }
207 }
208 }
209
210 fn handshake_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
211 &self,
212 io_priority: glib::Priority,
213 cancellable: Option<&P>,
214 callback: Q,
215 ) {
216 let user_data: Box<Q> = Box::new(callback);
217 unsafe extern "C" fn handshake_async_trampoline<
218 Q: FnOnce(Result<(), Error>) + Send + 'static,
219 >(
220 _source_object: *mut gobject_sys::GObject,
221 res: *mut gio_sys::GAsyncResult,
222 user_data: glib_sys::gpointer,
223 ) {
224 let mut error = ptr::null_mut();
225 let _ = gio_sys::g_tls_connection_handshake_finish(
226 _source_object as *mut _,
227 res,
228 &mut error,
229 );
230 let result = if error.is_null() {
231 Ok(())
232 } else {
233 Err(from_glib_full(error))
234 };
235 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
236 callback(result);
237 }
238 let callback = handshake_async_trampoline::<Q>;
239 unsafe {
240 gio_sys::g_tls_connection_handshake_async(
241 self.as_ref().to_glib_none().0,
242 io_priority.to_glib(),
243 cancellable.map(|p| p.as_ref()).to_glib_none().0,
244 Some(callback),
245 Box::into_raw(user_data) as *mut _,
246 );
247 }
248 }
249
250 #[cfg(feature = "futures")]
251 fn handshake_async_future(
252 &self,
253 io_priority: glib::Priority,
254 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
255 use fragile::Fragile;
256 use GioFuture;
257
258 GioFuture::new(self, move |obj, send| {
259 let cancellable = Cancellable::new();
260 let send = Fragile::new(send);
261 obj.handshake_async(io_priority, Some(&cancellable), move |res| {
262 let _ = send.into_inner().send(res);
263 });
264
265 cancellable
266 })
267 }
268
269 fn set_certificate<P: IsA<TlsCertificate>>(&self, certificate: &P) {
270 unsafe {
271 gio_sys::g_tls_connection_set_certificate(
272 self.as_ref().to_glib_none().0,
273 certificate.as_ref().to_glib_none().0,
274 );
275 }
276 }
277
278 fn set_database<P: IsA<TlsDatabase>>(&self, database: &P) {
279 unsafe {
280 gio_sys::g_tls_connection_set_database(
281 self.as_ref().to_glib_none().0,
282 database.as_ref().to_glib_none().0,
283 );
284 }
285 }
286
287 fn set_interaction<P: IsA<TlsInteraction>>(&self, interaction: Option<&P>) {
288 unsafe {
289 gio_sys::g_tls_connection_set_interaction(
290 self.as_ref().to_glib_none().0,
291 interaction.map(|p| p.as_ref()).to_glib_none().0,
292 );
293 }
294 }
295
296 fn set_rehandshake_mode(&self, mode: TlsRehandshakeMode) {
297 unsafe {
298 gio_sys::g_tls_connection_set_rehandshake_mode(
299 self.as_ref().to_glib_none().0,
300 mode.to_glib(),
301 );
302 }
303 }
304
305 fn set_require_close_notify(&self, require_close_notify: bool) {
306 unsafe {
307 gio_sys::g_tls_connection_set_require_close_notify(
308 self.as_ref().to_glib_none().0,
309 require_close_notify.to_glib(),
310 );
311 }
312 }
313
314 fn get_property_base_io_stream(&self) -> Option<IOStream> {
315 unsafe {
316 let mut value = Value::from_type(<IOStream as StaticType>::static_type());
317 gobject_sys::g_object_get_property(
318 self.to_glib_none().0 as *mut gobject_sys::GObject,
319 b"base-io-stream\0".as_ptr() as *const _,
320 value.to_glib_none_mut().0,
321 );
322 value.get()
323 }
324 }
325
326 fn connect_accept_certificate<
327 F: Fn(&Self, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
328 >(
329 &self,
330 f: F,
331 ) -> SignalHandlerId {
332 unsafe extern "C" fn accept_certificate_trampoline<
333 P,
334 F: Fn(&P, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
335 >(
336 this: *mut gio_sys::GTlsConnection,
337 peer_cert: *mut gio_sys::GTlsCertificate,
338 errors: gio_sys::GTlsCertificateFlags,
339 f: glib_sys::gpointer,
340 ) -> glib_sys::gboolean
341 where
342 P: IsA<TlsConnection>,
343 {
344 let f: &F = &*(f as *const F);
345 f(
346 &TlsConnection::from_glib_borrow(this).unsafe_cast(),
347 &from_glib_borrow(peer_cert),
348 from_glib(errors),
349 )
350 .to_glib()
351 }
352 unsafe {
353 let f: Box_<F> = Box_::new(f);
354 connect_raw(
355 self.as_ptr() as *mut _,
356 b"accept-certificate\0".as_ptr() as *const _,
357 Some(transmute(accept_certificate_trampoline::<Self, F> as usize)),
358 Box_::into_raw(f),
359 )
360 }
361 }
362
363 fn connect_property_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
364 unsafe extern "C" fn notify_certificate_trampoline<P, F: Fn(&P) + 'static>(
365 this: *mut gio_sys::GTlsConnection,
366 _param_spec: glib_sys::gpointer,
367 f: glib_sys::gpointer,
368 ) where
369 P: IsA<TlsConnection>,
370 {
371 let f: &F = &*(f as *const F);
372 f(&TlsConnection::from_glib_borrow(this).unsafe_cast())
373 }
374 unsafe {
375 let f: Box_<F> = Box_::new(f);
376 connect_raw(
377 self.as_ptr() as *mut _,
378 b"notify::certificate\0".as_ptr() as *const _,
379 Some(transmute(notify_certificate_trampoline::<Self, F> as usize)),
380 Box_::into_raw(f),
381 )
382 }
383 }
384
385 fn connect_property_database_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
386 unsafe extern "C" fn notify_database_trampoline<P, F: Fn(&P) + 'static>(
387 this: *mut gio_sys::GTlsConnection,
388 _param_spec: glib_sys::gpointer,
389 f: glib_sys::gpointer,
390 ) where
391 P: IsA<TlsConnection>,
392 {
393 let f: &F = &*(f as *const F);
394 f(&TlsConnection::from_glib_borrow(this).unsafe_cast())
395 }
396 unsafe {
397 let f: Box_<F> = Box_::new(f);
398 connect_raw(
399 self.as_ptr() as *mut _,
400 b"notify::database\0".as_ptr() as *const _,
401 Some(transmute(notify_database_trampoline::<Self, F> as usize)),
402 Box_::into_raw(f),
403 )
404 }
405 }
406
407 fn connect_property_interaction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
408 unsafe extern "C" fn notify_interaction_trampoline<P, F: Fn(&P) + 'static>(
409 this: *mut gio_sys::GTlsConnection,
410 _param_spec: glib_sys::gpointer,
411 f: glib_sys::gpointer,
412 ) where
413 P: IsA<TlsConnection>,
414 {
415 let f: &F = &*(f as *const F);
416 f(&TlsConnection::from_glib_borrow(this).unsafe_cast())
417 }
418 unsafe {
419 let f: Box_<F> = Box_::new(f);
420 connect_raw(
421 self.as_ptr() as *mut _,
422 b"notify::interaction\0".as_ptr() as *const _,
423 Some(transmute(notify_interaction_trampoline::<Self, F> as usize)),
424 Box_::into_raw(f),
425 )
426 }
427 }
428
429 fn connect_property_peer_certificate_notify<F: Fn(&Self) + 'static>(
430 &self,
431 f: F,
432 ) -> SignalHandlerId {
433 unsafe extern "C" fn notify_peer_certificate_trampoline<P, F: Fn(&P) + 'static>(
434 this: *mut gio_sys::GTlsConnection,
435 _param_spec: glib_sys::gpointer,
436 f: glib_sys::gpointer,
437 ) where
438 P: IsA<TlsConnection>,
439 {
440 let f: &F = &*(f as *const F);
441 f(&TlsConnection::from_glib_borrow(this).unsafe_cast())
442 }
443 unsafe {
444 let f: Box_<F> = Box_::new(f);
445 connect_raw(
446 self.as_ptr() as *mut _,
447 b"notify::peer-certificate\0".as_ptr() as *const _,
448 Some(transmute(
449 notify_peer_certificate_trampoline::<Self, F> as usize,
450 )),
451 Box_::into_raw(f),
452 )
453 }
454 }
455
456 fn connect_property_peer_certificate_errors_notify<F: Fn(&Self) + 'static>(
457 &self,
458 f: F,
459 ) -> SignalHandlerId {
460 unsafe extern "C" fn notify_peer_certificate_errors_trampoline<P, F: Fn(&P) + 'static>(
461 this: *mut gio_sys::GTlsConnection,
462 _param_spec: glib_sys::gpointer,
463 f: glib_sys::gpointer,
464 ) where
465 P: IsA<TlsConnection>,
466 {
467 let f: &F = &*(f as *const F);
468 f(&TlsConnection::from_glib_borrow(this).unsafe_cast())
469 }
470 unsafe {
471 let f: Box_<F> = Box_::new(f);
472 connect_raw(
473 self.as_ptr() as *mut _,
474 b"notify::peer-certificate-errors\0".as_ptr() as *const _,
475 Some(transmute(
476 notify_peer_certificate_errors_trampoline::<Self, F> as usize,
477 )),
478 Box_::into_raw(f),
479 )
480 }
481 }
482
483 fn connect_property_rehandshake_mode_notify<F: Fn(&Self) + 'static>(
484 &self,
485 f: F,
486 ) -> SignalHandlerId {
487 unsafe extern "C" fn notify_rehandshake_mode_trampoline<P, F: Fn(&P) + 'static>(
488 this: *mut gio_sys::GTlsConnection,
489 _param_spec: glib_sys::gpointer,
490 f: glib_sys::gpointer,
491 ) where
492 P: IsA<TlsConnection>,
493 {
494 let f: &F = &*(f as *const F);
495 f(&TlsConnection::from_glib_borrow(this).unsafe_cast())
496 }
497 unsafe {
498 let f: Box_<F> = Box_::new(f);
499 connect_raw(
500 self.as_ptr() as *mut _,
501 b"notify::rehandshake-mode\0".as_ptr() as *const _,
502 Some(transmute(
503 notify_rehandshake_mode_trampoline::<Self, F> as usize,
504 )),
505 Box_::into_raw(f),
506 )
507 }
508 }
509
510 fn connect_property_require_close_notify_notify<F: Fn(&Self) + 'static>(
511 &self,
512 f: F,
513 ) -> SignalHandlerId {
514 unsafe extern "C" fn notify_require_close_notify_trampoline<P, F: Fn(&P) + 'static>(
515 this: *mut gio_sys::GTlsConnection,
516 _param_spec: glib_sys::gpointer,
517 f: glib_sys::gpointer,
518 ) where
519 P: IsA<TlsConnection>,
520 {
521 let f: &F = &*(f as *const F);
522 f(&TlsConnection::from_glib_borrow(this).unsafe_cast())
523 }
524 unsafe {
525 let f: Box_<F> = Box_::new(f);
526 connect_raw(
527 self.as_ptr() as *mut _,
528 b"notify::require-close-notify\0".as_ptr() as *const _,
529 Some(transmute(
530 notify_require_close_notify_trampoline::<Self, F> as usize,
531 )),
532 Box_::into_raw(f),
533 )
534 }
535 }
536}
537
538impl fmt::Display for TlsConnection {
539 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
540 write!(f, "TlsConnection")
541 }
542}