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 }