Changeset View
Changeset View
Standalone View
Standalone View
src/core/tcpslavebase.cpp
Show First 20 Lines • Show All 330 Lines • ▼ Show 20 Line(s) | 330 | if (result == SlaveBase::Cancel) { | |||
---|---|---|---|---|---|
331 | if (errorString) { | 331 | if (errorString) { | ||
332 | *errorString = host; | 332 | *errorString = host; | ||
333 | } | 333 | } | ||
334 | return ERR_USER_CANCELED; | 334 | return ERR_USER_CANCELED; | ||
335 | } | 335 | } | ||
336 | } | 336 | } | ||
337 | } | 337 | } | ||
338 | 338 | | |||
339 | /* | | |||
340 | SSL handshake is attempted in the following order: | | |||
341 | | ||||
342 | 1.) KTcpSocket::SecureProtocols | | |||
343 | 2.) KTcpSocket::TlsV1_2 | | |||
344 | 3.) KTcpSocket::TlsV1_1 | | |||
345 | 4.) KTcpSocket::TlsV1_0 | | |||
346 | | ||||
347 | Note that we individually attempt connection with each TLS version | | |||
348 | because some sites don't support SSL negotiation. #275524 | | |||
349 | | ||||
350 | The version used to successfully make encrypted connection with the | | |||
351 | remote server is cached within the process to make subsequent | | |||
352 | connection requests to the same server faster. | | |||
353 | */ | | |||
354 | | ||||
355 | const int lastSslVerson = config()->readEntry("LastUsedSslVersion", static_cast<int>(KTcpSocket::SecureProtocols)); | | |||
356 | KTcpSocket::SslVersion trySslVersion = static_cast<KTcpSocket::SslVersion>(lastSslVerson); | | |||
357 | KTcpSocket::SslVersions alreadyTriedSslVersions = trySslVersion; | | |||
358 | | ||||
359 | const int timeout = (connectTimeout() * 1000); // 20 sec timeout value | 339 | const int timeout = (connectTimeout() * 1000); // 20 sec timeout value | ||
360 | while (true) { | 340 | | ||
361 | disconnectFromHost(); //Reset some state, even if we are already disconnected | 341 | disconnectFromHost(); //Reset some state, even if we are already disconnected | ||
362 | d->host = host; | 342 | d->host = host; | ||
363 | 343 | | |||
364 | d->socket.connectToHost(host, port); | 344 | d->socket.connectToHost(host, port); | ||
365 | /*const bool connectOk = */d->socket.waitForConnected(timeout > -1 ? timeout : -1); | 345 | /*const bool connectOk = */d->socket.waitForConnected(timeout > -1 ? timeout : -1); | ||
366 | 346 | | |||
367 | /*qDebug() << "Socket: state=" << d->socket.state() | 347 | /*qDebug() << "Socket: state=" << d->socket.state() | ||
368 | << ", error=" << d->socket.error() | 348 | << ", error=" << d->socket.error() | ||
Show All 18 Lines | |||||
387 | } | 367 | } | ||
388 | 368 | | |||
389 | //### check for proxyAuthenticationRequiredError | 369 | //### check for proxyAuthenticationRequiredError | ||
390 | 370 | | |||
391 | d->ip = d->socket.peerAddress().toString(); | 371 | d->ip = d->socket.peerAddress().toString(); | ||
392 | d->port = d->socket.peerPort(); | 372 | d->port = d->socket.peerPort(); | ||
393 | 373 | | |||
394 | if (d->autoSSL) { | 374 | if (d->autoSSL) { | ||
395 | SslResult res = d->startTLSInternal(trySslVersion, timeout); | 375 | const SslResult res = d->startTLSInternal(KTcpSocket::SecureProtocols, timeout); | ||
396 | if ((res & ResultFailed) && (res & ResultFailedEarly)) { | | |||
397 | if (!(alreadyTriedSslVersions & KTcpSocket::SecureProtocols)) { | | |||
398 | trySslVersion = KTcpSocket::SecureProtocols; | | |||
399 | alreadyTriedSslVersions |= trySslVersion; | | |||
400 | continue; | | |||
401 | } | | |||
402 | | ||||
403 | if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_2)) { | | |||
404 | trySslVersion = KTcpSocket::TlsV1; | | |||
405 | alreadyTriedSslVersions |= trySslVersion; | | |||
406 | continue; | | |||
407 | } | | |||
408 | 376 | | |||
409 | if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_1)) { | | |||
410 | trySslVersion = KTcpSocket::TlsV1; | | |||
411 | alreadyTriedSslVersions |= trySslVersion; | | |||
412 | continue; | | |||
413 | } | | |||
414 | | ||||
415 | if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_0)) { | | |||
416 | trySslVersion = KTcpSocket::TlsV1_0; | | |||
417 | alreadyTriedSslVersions |= trySslVersion; | | |||
418 | continue; | | |||
419 | } | | |||
420 | } | | |||
421 | | ||||
422 | //### SSL 2.0 is (close to) dead and it's a good thing, too. | | |||
423 | if (res & ResultFailed) { | 377 | if (res & ResultFailed) { | ||
424 | if (errorString) { | 378 | if (errorString) { | ||
425 | *errorString = i18nc("%1 is a host name", "%1: SSL negotiation failed", host); | 379 | *errorString = i18nc("%1 is a host name", "%1: SSL negotiation failed", host); | ||
426 | } | 380 | } | ||
427 | return ERR_CANNOT_CONNECT; | 381 | return ERR_CANNOT_CONNECT; | ||
428 | } | 382 | } | ||
429 | } | 383 | } | ||
430 | // If the SSL handshake was done with anything protocol other than the default, | | |||
431 | // save that information so that any subsequent requests do not have to do thesame thing. | | |||
432 | if (trySslVersion != KTcpSocket::SecureProtocols && lastSslVerson == KTcpSocket::SecureProtocols) { | | |||
433 | setMetaData(QStringLiteral("{internal~currenthost}LastUsedSslVersion"), | | |||
434 | QString::number(trySslVersion)); | | |||
435 | } | | |||
436 | return 0; | | |||
437 | } | | |||
438 | Q_ASSERT(false); | | |||
439 | // Code flow never gets here but let's make the compiler happy. | | |||
440 | // More: the stack allocation of QSslSettings seems to be confusing the compiler; | | |||
441 | // in fact, any non-POD allocation does. | | |||
442 | // even a 'return 0;' directly after the allocation (so before the while(true)) | | |||
443 | // is ignored. definitely seems to be a compiler bug? - aseigo | | |||
444 | return 0; | 384 | return 0; | ||
445 | } | 385 | } | ||
446 | 386 | | |||
447 | void TCPSlaveBase::disconnectFromHost() | 387 | void TCPSlaveBase::disconnectFromHost() | ||
448 | { | 388 | { | ||
449 | //qDebug(); | 389 | //qDebug(); | ||
450 | d->host.clear(); | 390 | d->host.clear(); | ||
451 | d->ip.clear(); | 391 | d->ip.clear(); | ||
▲ Show 20 Lines • Show All 550 Lines • Show Last 20 Lines |