1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gio.TlsConnection;
26 
27 private import gio.AsyncResultIF;
28 private import gio.Cancellable;
29 private import gio.IOStream;
30 private import gio.TlsCertificate;
31 private import gio.TlsDatabase;
32 private import gio.TlsInteraction;
33 private import glib.ErrorG;
34 private import glib.GException;
35 private import gobject.ObjectG;
36 private import gobject.Signals;
37 private import gtkc.gio;
38 public  import gtkc.giotypes;
39 private import std.algorithm;
40 
41 
42 /**
43  * #GTlsConnection is the base TLS connection class type, which wraps
44  * a #GIOStream and provides TLS encryption on top of it. Its
45  * subclasses, #GTlsClientConnection and #GTlsServerConnection,
46  * implement client-side and server-side TLS, respectively.
47  * 
48  * For DTLS (Datagram TLS) support, see #GDtlsConnection.
49  *
50  * Since: 2.28
51  */
52 public class TlsConnection : IOStream
53 {
54 	/** the main Gtk struct */
55 	protected GTlsConnection* gTlsConnection;
56 
57 	/** Get the main Gtk struct */
58 	public GTlsConnection* getTlsConnectionStruct(bool transferOwnership = false)
59 	{
60 		if (transferOwnership)
61 			ownedRef = false;
62 		return gTlsConnection;
63 	}
64 
65 	/** the main Gtk struct as a void* */
66 	protected override void* getStruct()
67 	{
68 		return cast(void*)gTlsConnection;
69 	}
70 
71 	protected override void setStruct(GObject* obj)
72 	{
73 		gTlsConnection = cast(GTlsConnection*)obj;
74 		super.setStruct(obj);
75 	}
76 
77 	/**
78 	 * Sets our main struct and passes it to the parent class.
79 	 */
80 	public this (GTlsConnection* gTlsConnection, bool ownedRef = false)
81 	{
82 		this.gTlsConnection = gTlsConnection;
83 		super(cast(GIOStream*)gTlsConnection, ownedRef);
84 	}
85 
86 
87 	/** */
88 	public static GType getType()
89 	{
90 		return g_tls_connection_get_type();
91 	}
92 
93 	/**
94 	 * Used by #GTlsConnection implementations to emit the
95 	 * #GTlsConnection::accept-certificate signal.
96 	 *
97 	 * Params:
98 	 *     peerCert = the peer's #GTlsCertificate
99 	 *     errors = the problems with @peer_cert
100 	 *
101 	 * Returns: %TRUE if one of the signal handlers has returned
102 	 *     %TRUE to accept @peer_cert
103 	 *
104 	 * Since: 2.28
105 	 */
106 	public bool emitAcceptCertificate(TlsCertificate peerCert, GTlsCertificateFlags errors)
107 	{
108 		return g_tls_connection_emit_accept_certificate(gTlsConnection, (peerCert is null) ? null : peerCert.getTlsCertificateStruct(), errors) != 0;
109 	}
110 
111 	/**
112 	 * Gets @conn's certificate, as set by
113 	 * g_tls_connection_set_certificate().
114 	 *
115 	 * Returns: @conn's certificate, or %NULL
116 	 *
117 	 * Since: 2.28
118 	 */
119 	public TlsCertificate getCertificate()
120 	{
121 		auto p = g_tls_connection_get_certificate(gTlsConnection);
122 		
123 		if(p is null)
124 		{
125 			return null;
126 		}
127 		
128 		return ObjectG.getDObject!(TlsCertificate)(cast(GTlsCertificate*) p);
129 	}
130 
131 	/**
132 	 * Gets the certificate database that @conn uses to verify
133 	 * peer certificates. See g_tls_connection_set_database().
134 	 *
135 	 * Returns: the certificate database that @conn uses or %NULL
136 	 *
137 	 * Since: 2.30
138 	 */
139 	public TlsDatabase getDatabase()
140 	{
141 		auto p = g_tls_connection_get_database(gTlsConnection);
142 		
143 		if(p is null)
144 		{
145 			return null;
146 		}
147 		
148 		return ObjectG.getDObject!(TlsDatabase)(cast(GTlsDatabase*) p);
149 	}
150 
151 	/**
152 	 * Get the object that will be used to interact with the user. It will be used
153 	 * for things like prompting the user for passwords. If %NULL is returned, then
154 	 * no user interaction will occur for this connection.
155 	 *
156 	 * Returns: The interaction object.
157 	 *
158 	 * Since: 2.30
159 	 */
160 	public TlsInteraction getInteraction()
161 	{
162 		auto p = g_tls_connection_get_interaction(gTlsConnection);
163 		
164 		if(p is null)
165 		{
166 			return null;
167 		}
168 		
169 		return ObjectG.getDObject!(TlsInteraction)(cast(GTlsInteraction*) p);
170 	}
171 
172 	/**
173 	 * Gets @conn's peer's certificate after the handshake has completed.
174 	 * (It is not set during the emission of
175 	 * #GTlsConnection::accept-certificate.)
176 	 *
177 	 * Returns: @conn's peer's certificate, or %NULL
178 	 *
179 	 * Since: 2.28
180 	 */
181 	public TlsCertificate getPeerCertificate()
182 	{
183 		auto p = g_tls_connection_get_peer_certificate(gTlsConnection);
184 		
185 		if(p is null)
186 		{
187 			return null;
188 		}
189 		
190 		return ObjectG.getDObject!(TlsCertificate)(cast(GTlsCertificate*) p);
191 	}
192 
193 	/**
194 	 * Gets the errors associated with validating @conn's peer's
195 	 * certificate, after the handshake has completed. (It is not set
196 	 * during the emission of #GTlsConnection::accept-certificate.)
197 	 *
198 	 * Returns: @conn's peer's certificate errors
199 	 *
200 	 * Since: 2.28
201 	 */
202 	public GTlsCertificateFlags getPeerCertificateErrors()
203 	{
204 		return g_tls_connection_get_peer_certificate_errors(gTlsConnection);
205 	}
206 
207 	/**
208 	 * Gets @conn rehandshaking mode. See
209 	 * g_tls_connection_set_rehandshake_mode() for details.
210 	 *
211 	 * Returns: @conn's rehandshaking mode
212 	 *
213 	 * Since: 2.28
214 	 */
215 	public GTlsRehandshakeMode getRehandshakeMode()
216 	{
217 		return g_tls_connection_get_rehandshake_mode(gTlsConnection);
218 	}
219 
220 	/**
221 	 * Tests whether or not @conn expects a proper TLS close notification
222 	 * when the connection is closed. See
223 	 * g_tls_connection_set_require_close_notify() for details.
224 	 *
225 	 * Returns: %TRUE if @conn requires a proper TLS close
226 	 *     notification.
227 	 *
228 	 * Since: 2.28
229 	 */
230 	public bool getRequireCloseNotify()
231 	{
232 		return g_tls_connection_get_require_close_notify(gTlsConnection) != 0;
233 	}
234 
235 	/**
236 	 * Gets whether @conn uses the system certificate database to verify
237 	 * peer certificates. See g_tls_connection_set_use_system_certdb().
238 	 *
239 	 * Deprecated: Use g_tls_connection_get_database() instead
240 	 *
241 	 * Returns: whether @conn uses the system certificate database
242 	 */
243 	public bool getUseSystemCertdb()
244 	{
245 		return g_tls_connection_get_use_system_certdb(gTlsConnection) != 0;
246 	}
247 
248 	/**
249 	 * Attempts a TLS handshake on @conn.
250 	 *
251 	 * On the client side, it is never necessary to call this method;
252 	 * although the connection needs to perform a handshake after
253 	 * connecting (or after sending a "STARTTLS"-type command) and may
254 	 * need to rehandshake later if the server requests it,
255 	 * #GTlsConnection will handle this for you automatically when you try
256 	 * to send or receive data on the connection. However, you can call
257 	 * g_tls_connection_handshake() manually if you want to know for sure
258 	 * whether the initial handshake succeeded or failed (as opposed to
259 	 * just immediately trying to write to @conn's output stream, in which
260 	 * case if it fails, it may not be possible to tell if it failed
261 	 * before or after completing the handshake).
262 	 *
263 	 * Likewise, on the server side, although a handshake is necessary at
264 	 * the beginning of the communication, you do not need to call this
265 	 * function explicitly unless you want clearer error reporting.
266 	 * However, you may call g_tls_connection_handshake() later on to
267 	 * renegotiate parameters (encryption methods, etc) with the client.
268 	 *
269 	 * #GTlsConnection::accept_certificate may be emitted during the
270 	 * handshake.
271 	 *
272 	 * Params:
273 	 *     cancellable = a #GCancellable, or %NULL
274 	 *
275 	 * Returns: success or failure
276 	 *
277 	 * Since: 2.28
278 	 *
279 	 * Throws: GException on failure.
280 	 */
281 	public bool handshake(Cancellable cancellable)
282 	{
283 		GError* err = null;
284 		
285 		auto p = g_tls_connection_handshake(gTlsConnection, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0;
286 		
287 		if (err !is null)
288 		{
289 			throw new GException( new ErrorG(err) );
290 		}
291 		
292 		return p;
293 	}
294 
295 	/**
296 	 * Asynchronously performs a TLS handshake on @conn. See
297 	 * g_tls_connection_handshake() for more information.
298 	 *
299 	 * Params:
300 	 *     ioPriority = the [I/O priority][io-priority] of the request
301 	 *     cancellable = a #GCancellable, or %NULL
302 	 *     callback = callback to call when the handshake is complete
303 	 *     userData = the data to pass to the callback function
304 	 *
305 	 * Since: 2.28
306 	 */
307 	public void handshakeAsync(int ioPriority, Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
308 	{
309 		g_tls_connection_handshake_async(gTlsConnection, ioPriority, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
310 	}
311 
312 	/**
313 	 * Finish an asynchronous TLS handshake operation. See
314 	 * g_tls_connection_handshake() for more information.
315 	 *
316 	 * Params:
317 	 *     result = a #GAsyncResult.
318 	 *
319 	 * Returns: %TRUE on success, %FALSE on failure, in which
320 	 *     case @error will be set.
321 	 *
322 	 * Since: 2.28
323 	 *
324 	 * Throws: GException on failure.
325 	 */
326 	public bool handshakeFinish(AsyncResultIF result)
327 	{
328 		GError* err = null;
329 		
330 		auto p = g_tls_connection_handshake_finish(gTlsConnection, (result is null) ? null : result.getAsyncResultStruct(), &err) != 0;
331 		
332 		if (err !is null)
333 		{
334 			throw new GException( new ErrorG(err) );
335 		}
336 		
337 		return p;
338 	}
339 
340 	/**
341 	 * This sets the certificate that @conn will present to its peer
342 	 * during the TLS handshake. For a #GTlsServerConnection, it is
343 	 * mandatory to set this, and that will normally be done at construct
344 	 * time.
345 	 *
346 	 * For a #GTlsClientConnection, this is optional. If a handshake fails
347 	 * with %G_TLS_ERROR_CERTIFICATE_REQUIRED, that means that the server
348 	 * requires a certificate, and if you try connecting again, you should
349 	 * call this method first. You can call
350 	 * g_tls_client_connection_get_accepted_cas() on the failed connection
351 	 * to get a list of Certificate Authorities that the server will
352 	 * accept certificates from.
353 	 *
354 	 * (It is also possible that a server will allow the connection with
355 	 * or without a certificate; in that case, if you don't provide a
356 	 * certificate, you can tell that the server requested one by the fact
357 	 * that g_tls_client_connection_get_accepted_cas() will return
358 	 * non-%NULL.)
359 	 *
360 	 * Params:
361 	 *     certificate = the certificate to use for @conn
362 	 *
363 	 * Since: 2.28
364 	 */
365 	public void setCertificate(TlsCertificate certificate)
366 	{
367 		g_tls_connection_set_certificate(gTlsConnection, (certificate is null) ? null : certificate.getTlsCertificateStruct());
368 	}
369 
370 	/**
371 	 * Sets the certificate database that is used to verify peer certificates.
372 	 * This is set to the default database by default. See
373 	 * g_tls_backend_get_default_database(). If set to %NULL, then
374 	 * peer certificate validation will always set the
375 	 * %G_TLS_CERTIFICATE_UNKNOWN_CA error (meaning
376 	 * #GTlsConnection::accept-certificate will always be emitted on
377 	 * client-side connections, unless that bit is not set in
378 	 * #GTlsClientConnection:validation-flags).
379 	 *
380 	 * Params:
381 	 *     database = a #GTlsDatabase
382 	 *
383 	 * Since: 2.30
384 	 */
385 	public void setDatabase(TlsDatabase database)
386 	{
387 		g_tls_connection_set_database(gTlsConnection, (database is null) ? null : database.getTlsDatabaseStruct());
388 	}
389 
390 	/**
391 	 * Set the object that will be used to interact with the user. It will be used
392 	 * for things like prompting the user for passwords.
393 	 *
394 	 * The @interaction argument will normally be a derived subclass of
395 	 * #GTlsInteraction. %NULL can also be provided if no user interaction
396 	 * should occur for this connection.
397 	 *
398 	 * Params:
399 	 *     interaction = an interaction object, or %NULL
400 	 *
401 	 * Since: 2.30
402 	 */
403 	public void setInteraction(TlsInteraction interaction)
404 	{
405 		g_tls_connection_set_interaction(gTlsConnection, (interaction is null) ? null : interaction.getTlsInteractionStruct());
406 	}
407 
408 	/**
409 	 * Sets how @conn behaves with respect to rehandshaking requests.
410 	 *
411 	 * %G_TLS_REHANDSHAKE_NEVER means that it will never agree to
412 	 * rehandshake after the initial handshake is complete. (For a client,
413 	 * this means it will refuse rehandshake requests from the server, and
414 	 * for a server, this means it will close the connection with an error
415 	 * if the client attempts to rehandshake.)
416 	 *
417 	 * %G_TLS_REHANDSHAKE_SAFELY means that the connection will allow a
418 	 * rehandshake only if the other end of the connection supports the
419 	 * TLS `renegotiation_info` extension. This is the default behavior,
420 	 * but means that rehandshaking will not work against older
421 	 * implementations that do not support that extension.
422 	 *
423 	 * %G_TLS_REHANDSHAKE_UNSAFELY means that the connection will allow
424 	 * rehandshaking even without the `renegotiation_info` extension. On
425 	 * the server side in particular, this is not recommended, since it
426 	 * leaves the server open to certain attacks. However, this mode is
427 	 * necessary if you need to allow renegotiation with older client
428 	 * software.
429 	 *
430 	 * Params:
431 	 *     mode = the rehandshaking mode
432 	 *
433 	 * Since: 2.28
434 	 */
435 	public void setRehandshakeMode(GTlsRehandshakeMode mode)
436 	{
437 		g_tls_connection_set_rehandshake_mode(gTlsConnection, mode);
438 	}
439 
440 	/**
441 	 * Sets whether or not @conn expects a proper TLS close notification
442 	 * before the connection is closed. If this is %TRUE (the default),
443 	 * then @conn will expect to receive a TLS close notification from its
444 	 * peer before the connection is closed, and will return a
445 	 * %G_TLS_ERROR_EOF error if the connection is closed without proper
446 	 * notification (since this may indicate a network error, or
447 	 * man-in-the-middle attack).
448 	 *
449 	 * In some protocols, the application will know whether or not the
450 	 * connection was closed cleanly based on application-level data
451 	 * (because the application-level data includes a length field, or is
452 	 * somehow self-delimiting); in this case, the close notify is
453 	 * redundant and sometimes omitted. (TLS 1.1 explicitly allows this;
454 	 * in TLS 1.0 it is technically an error, but often done anyway.) You
455 	 * can use g_tls_connection_set_require_close_notify() to tell @conn
456 	 * to allow an "unannounced" connection close, in which case the close
457 	 * will show up as a 0-length read, as in a non-TLS
458 	 * #GSocketConnection, and it is up to the application to check that
459 	 * the data has been fully received.
460 	 *
461 	 * Note that this only affects the behavior when the peer closes the
462 	 * connection; when the application calls g_io_stream_close() itself
463 	 * on @conn, this will send a close notification regardless of the
464 	 * setting of this property. If you explicitly want to do an unclean
465 	 * close, you can close @conn's #GTlsConnection:base-io-stream rather
466 	 * than closing @conn itself, but note that this may only be done when no other
467 	 * operations are pending on @conn or the base I/O stream.
468 	 *
469 	 * Params:
470 	 *     requireCloseNotify = whether or not to require close notification
471 	 *
472 	 * Since: 2.28
473 	 */
474 	public void setRequireCloseNotify(bool requireCloseNotify)
475 	{
476 		g_tls_connection_set_require_close_notify(gTlsConnection, requireCloseNotify);
477 	}
478 
479 	/**
480 	 * Sets whether @conn uses the system certificate database to verify
481 	 * peer certificates. This is %TRUE by default. If set to %FALSE, then
482 	 * peer certificate validation will always set the
483 	 * %G_TLS_CERTIFICATE_UNKNOWN_CA error (meaning
484 	 * #GTlsConnection::accept-certificate will always be emitted on
485 	 * client-side connections, unless that bit is not set in
486 	 * #GTlsClientConnection:validation-flags).
487 	 *
488 	 * Deprecated: Use g_tls_connection_set_database() instead
489 	 *
490 	 * Params:
491 	 *     useSystemCertdb = whether to use the system certificate database
492 	 */
493 	public void setUseSystemCertdb(bool useSystemCertdb)
494 	{
495 		g_tls_connection_set_use_system_certdb(gTlsConnection, useSystemCertdb);
496 	}
497 
498 	protected class OnAcceptCertificateDelegateWrapper
499 	{
500 		static OnAcceptCertificateDelegateWrapper[] listeners;
501 		bool delegate(TlsCertificate, GTlsCertificateFlags, TlsConnection) dlg;
502 		gulong handlerId;
503 		
504 		this(bool delegate(TlsCertificate, GTlsCertificateFlags, TlsConnection) dlg)
505 		{
506 			this.dlg = dlg;
507 			this.listeners ~= this;
508 		}
509 		
510 		void remove(OnAcceptCertificateDelegateWrapper source)
511 		{
512 			foreach(index, wrapper; listeners)
513 			{
514 				if (wrapper.handlerId == source.handlerId)
515 				{
516 					listeners[index] = null;
517 					listeners = std.algorithm.remove(listeners, index);
518 					break;
519 				}
520 			}
521 		}
522 	}
523 
524 	/**
525 	 * Emitted during the TLS handshake after the peer certificate has
526 	 * been received. You can examine @peer_cert's certification path by
527 	 * calling g_tls_certificate_get_issuer() on it.
528 	 *
529 	 * For a client-side connection, @peer_cert is the server's
530 	 * certificate, and the signal will only be emitted if the
531 	 * certificate was not acceptable according to @conn's
532 	 * #GTlsClientConnection:validation_flags. If you would like the
533 	 * certificate to be accepted despite @errors, return %TRUE from the
534 	 * signal handler. Otherwise, if no handler accepts the certificate,
535 	 * the handshake will fail with %G_TLS_ERROR_BAD_CERTIFICATE.
536 	 *
537 	 * For a server-side connection, @peer_cert is the certificate
538 	 * presented by the client, if this was requested via the server's
539 	 * #GTlsServerConnection:authentication_mode. On the server side,
540 	 * the signal is always emitted when the client presents a
541 	 * certificate, and the certificate will only be accepted if a
542 	 * handler returns %TRUE.
543 	 *
544 	 * Note that if this signal is emitted as part of asynchronous I/O
545 	 * in the main thread, then you should not attempt to interact with
546 	 * the user before returning from the signal handler. If you want to
547 	 * let the user decide whether or not to accept the certificate, you
548 	 * would have to return %FALSE from the signal handler on the first
549 	 * attempt, and then after the connection attempt returns a
550 	 * %G_TLS_ERROR_HANDSHAKE, you can interact with the user, and if
551 	 * the user decides to accept the certificate, remember that fact,
552 	 * create a new connection, and return %TRUE from the signal handler
553 	 * the next time.
554 	 *
555 	 * If you are doing I/O in another thread, you do not
556 	 * need to worry about this, and can simply block in the signal
557 	 * handler until the UI thread returns an answer.
558 	 *
559 	 * Params:
560 	 *     peerCert = the peer's #GTlsCertificate
561 	 *     errors = the problems with @peer_cert.
562 	 *
563 	 * Returns: %TRUE to accept @peer_cert (which will also
564 	 *     immediately end the signal emission). %FALSE to allow the signal
565 	 *     emission to continue, which will cause the handshake to fail if
566 	 *     no one else overrides it.
567 	 *
568 	 * Since: 2.28
569 	 */
570 	gulong addOnAcceptCertificate(bool delegate(TlsCertificate, GTlsCertificateFlags, TlsConnection) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
571 	{
572 		auto wrapper = new OnAcceptCertificateDelegateWrapper(dlg);
573 		wrapper.handlerId = Signals.connectData(
574 			this,
575 			"accept-certificate",
576 			cast(GCallback)&callBackAcceptCertificate,
577 			cast(void*)wrapper,
578 			cast(GClosureNotify)&callBackAcceptCertificateDestroy,
579 			connectFlags);
580 		return wrapper.handlerId;
581 	}
582 	
583 	extern(C) static int callBackAcceptCertificate(GTlsConnection* tlsconnectionStruct, GTlsCertificate* peerCert, GTlsCertificateFlags errors, OnAcceptCertificateDelegateWrapper wrapper)
584 	{
585 		return wrapper.dlg(ObjectG.getDObject!(TlsCertificate)(peerCert), errors, wrapper.outer);
586 	}
587 	
588 	extern(C) static void callBackAcceptCertificateDestroy(OnAcceptCertificateDelegateWrapper wrapper, GClosure* closure)
589 	{
590 		wrapper.remove(wrapper);
591 	}
592 }