📄 tcpslavebase.cpp
字号:
d->kssl->setPeerHost(d->realHost); } else { kdDebug(7029) << "Setting real hostname: " << d->host << endl; d->kssl->setPeerHost(d->host); } certificatePrompt(); int rc = d->kssl->connect(m_iSock); if (rc < 0) { delete d->kssl; d->kssl = NULL; return -2; } d->usingTLS = true; setMetaData("ssl_in_use", "TRUE"); rc = verifyCertificate(); if (rc != 1) { setMetaData("ssl_in_use", "FALSE"); d->usingTLS = false; delete d->kssl; d->kssl = NULL; return -3; } return (d->usingTLS ? 1 : 0);}void TCPSlaveBase::stopTLS(){ if (d->cc) { delete d->cc; d->cc = NULL; } if (d->usingTLS) { delete d->kssl; d->kssl = NULL; d->usingTLS = false; setMetaData("ssl_in_use", "FALSE"); }}bool TCPSlaveBase::canUseTLS(){ if (m_bIsSSL || d->needSSLHandShake || !KSSL::doesSSLWork()) return false; KSSLSettings kss; return kss.tlsv1();}void TCPSlaveBase::certificatePrompt(){QString certname; // the cert to use this sessionbool send = false, prompt = false, save = false, forcePrompt = false;KSSLCertificateHome::KSSLAuthAction aa; setMetaData("ssl_using_client_cert", "FALSE"); // we change this if needed if (metaData("ssl_no_client_cert") == "TRUE") return; forcePrompt = (metaData("ssl_force_cert_prompt") == "TRUE"); // Delete the old cert since we're certainly done with it now if (d->pkcs) { delete d->pkcs; d->pkcs = NULL; } if (!d->kssl) return; // Look for a general certificate if (!forcePrompt) { certname = KSSLCertificateHome::getDefaultCertificateName(&aa); switch(aa) { case KSSLCertificateHome::AuthSend: send = true; prompt = false; break; case KSSLCertificateHome::AuthDont: send = false; prompt = false; certname = ""; break; case KSSLCertificateHome::AuthPrompt: send = false; prompt = true; break; default: break; } } // Look for a certificate on a per-host basis as an override QString tmpcn = KSSLCertificateHome::getDefaultCertificateName(d->host, &aa); if (aa != KSSLCertificateHome::AuthNone) { // we must override switch (aa) { case KSSLCertificateHome::AuthSend: send = true; prompt = false; certname = tmpcn; break; case KSSLCertificateHome::AuthDont: send = false; prompt = false; certname = ""; break; case KSSLCertificateHome::AuthPrompt: send = false; prompt = true; certname = tmpcn; break; default: break; } } // Finally, we allow the application to override anything. if (hasMetaData("ssl_demand_certificate")) { certname = metaData("ssl_demand_certificate"); if (!certname.isEmpty()) { forcePrompt = false; prompt = false; send = true; } } if (certname.isEmpty() && !prompt && !forcePrompt) return; // Ok, we're supposed to prompt the user.... if (prompt || forcePrompt) { QStringList certs = KSSLCertificateHome::getCertificateList(); if (certs.isEmpty()) return; // we had nothing else, and prompt failed if (!d->dcc) { d->dcc = new DCOPClient; d->dcc->attach(); if (!d->dcc->isApplicationRegistered("kio_uiserver")) { KApplication::startServiceByDesktopPath("kio_uiserver.desktop", QStringList() ); } } QByteArray data, retval; QCString rettype; QDataStream arg(data, IO_WriteOnly); arg << d->host+":"+QString::number(m_iPort); arg << certs; bool rc = d->dcc->call("kio_uiserver", "UIServer", "showSSLCertDialog(QString, QStringList)", data, rettype, retval); if (rc && rettype == "KSSLCertDlgRet") { QDataStream retStream(retval, IO_ReadOnly); KSSLCertDlgRet drc; retStream >> drc; if (drc.ok) { send = drc.send; save = drc.save; certname = drc.choice; } } } // The user may have said to not send the certificate, // but to save the choice if (!send) { if (save) { KSSLCertificateHome::setDefaultCertificate(certname, d->host, false, false); } return; } // We're almost committed. If we can read the cert, we'll send it now. KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(certname); if (!pkcs && KSSLCertificateHome::hasCertificateByName(certname)) { // We need the password do { QString pass; QByteArray authdata, authval; QCString rettype; KIO::AuthInfo ai; QDataStream qds(authdata, IO_WriteOnly); ai.prompt = i18n("Enter the certificate password:"); ai.caption = i18n("SSL Certificate Password"); ai.setModified(true); ai.username = certname; ai.keepPassword = false; qds << ai; if (!d->dcc) { d->dcc = new DCOPClient; d->dcc->attach(); if (!d->dcc->isApplicationRegistered("kio_uiserver")) { KApplication::startServiceByDesktopPath("kio_uiserver.desktop", QStringList() ); } } bool rc = d->dcc->call("kio_uiserver", "UIServer", "openPassDlg(KIO::AuthInfo)", authdata, rettype, authval); if (!rc) break; if (rettype != "QByteArray") continue; QDataStream qdret(authval, IO_ReadOnly); QByteArray authdecode; qdret >> authdecode; QDataStream qdtoo(authdecode, IO_ReadOnly); qdtoo >> ai; if (!ai.isModified()) break; pass = ai.password; pkcs = KSSLCertificateHome::getCertificateByName(certname, pass); if (!pkcs) { int rc = messageBox(WarningYesNo, i18n("Couldn't open the " "certificate. Try a " "new password?"), i18n("SSL")); if (rc == KMessageBox::No) break; } } while (!pkcs); } // If we could open the certificate, let's send it if (pkcs) { if (!d->kssl->setClientCertificate(pkcs)) { messageBox(Information, i18n("Sorry, the procedure to set the " "client certificate for the session " "failed."), i18n("SSL")); delete pkcs; // we don't need this anymore } else { kdDebug(7029) << "Client SSL certificate is being used." << endl; setMetaData("ssl_using_client_cert", "TRUE"); if (save) { KSSLCertificateHome::setDefaultCertificate(certname, d->host, true, false); } } d->pkcs = pkcs; }}bool TCPSlaveBase::usingTLS(){ return d->usingTLS;}// Returns 0 for failed verification, -1 for rejected cert and 1 for okint TCPSlaveBase::verifyCertificate(){ int rc = 0; bool permacache = false; bool isChild = false; QString theurl = QString(m_sServiceName)+"://"+d->host+":"+QString::number(m_iPort); bool _IPmatchesCN = false; if (!hasMetaData("ssl_militant") || metaData("ssl_militant") == "FALSE") d->militantSSL = false; else if (metaData("ssl_militant") == "TRUE") d->militantSSL = true; if (!d->cc) d->cc = new KSSLCertificateCache; KSSLCertificate& pc = d->kssl->peerInfo().getPeerCertificate(); KSSLCertificate::KSSLValidation ksv = pc.validate(); /* Setting the various bits of meta-info that will be needed. */ setMetaData("ssl_peer_cert_subject", pc.getSubject()); setMetaData("ssl_peer_cert_issuer", pc.getIssuer()); setMetaData("ssl_cipher", d->kssl->connectionInfo().getCipher()); setMetaData("ssl_cipher_desc", d->kssl->connectionInfo().getCipherDescription()); setMetaData("ssl_cipher_version", d->kssl->connectionInfo().getCipherVersion()); setMetaData("ssl_cipher_used_bits", QString::number(d->kssl->connectionInfo().getCipherUsedBits())); setMetaData("ssl_cipher_bits", QString::number(d->kssl->connectionInfo().getCipherBits())); setMetaData("ssl_peer_ip", d->ip); setMetaData("ssl_cert_state", QString::number(ksv)); setMetaData("ssl_good_from", pc.getNotBefore()); setMetaData("ssl_good_until", pc.getNotAfter()); if (ksv == KSSLCertificate::Ok) { rc = 1; setMetaData("ssl_action", "accept"); } _IPmatchesCN = d->kssl->peerInfo().certMatchesAddress(); //kdDebug(7029) << "SSL HTTP frame the parent? " << metaData("main_frame_request") << endl; if (!hasMetaData("main_frame_request") || metaData("main_frame_request") == "TRUE") { // Since we're the parent, we need to teach the child. setMetaData("ssl_parent_ip", d->ip); setMetaData("ssl_parent_cert", pc.toString()); // - Read from cache and see if there is a policy for this KSSLCertificateCache::KSSLCertificatePolicy cp = d->cc->getPolicyByCertificate(pc); // - validation code if (ksv != KSSLCertificate::Ok || !_IPmatchesCN) { if (d->militantSSL) return -1; if (cp == KSSLCertificateCache::Unknown || cp == KSSLCertificateCache::Ambiguous) { cp = KSSLCertificateCache::Prompt; } else { // A policy was already set so let's honour that. permacache = d->cc->isPermanent(pc); } // Precondition: cp is one of Reject, Accept or Prompt switch (cp) { case KSSLCertificateCache::Accept: rc = 1; setMetaData("ssl_action", "accept"); break; case KSSLCertificateCache::Reject: rc = -1; setMetaData("ssl_action", "reject"); break; case KSSLCertificateCache::Prompt: { int result; do { if (ksv == KSSLCertificate::Ok && !_IPmatchesCN) { QString msg = i18n("The IP address of the host %1 " "does not match the one the " "certificate was issued to."); result = messageBox( WarningYesNoCancel, msg.arg(d->host), i18n("Server Authentication"), i18n("&Details..."), i18n("Co&ntinue") ); } else { QString msg = i18n("The server certificate failed the " "authenticity test (%1)."); result = messageBox( WarningYesNoCancel, msg.arg(d->host), i18n("Server Authentication"), i18n("&Details..."), i18n("Co&ntinue") ); } if (result == KMessageBox::Yes) { if (!d->dcc) { d->dcc = new DCOPClient; d->dcc->attach(); } QByteArray data, ignore; QCString ignoretype; QDataStream arg(data, IO_WriteOnly);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -