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