00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ksslinfodlg.h"
00023
00024 #include <kssl.h>
00025
00026 #include <qlayout.h>
00027 #include <kpushbutton.h>
00028 #include <qframe.h>
00029 #include <qlabel.h>
00030 #include <qscrollview.h>
00031 #include <qfile.h>
00032
00033 #include <kapplication.h>
00034 #include <kglobal.h>
00035 #include <klocale.h>
00036 #include <kprocess.h>
00037 #include <kiconloader.h>
00038 #include <kglobalsettings.h>
00039 #include <ksqueezedtextlabel.h>
00040 #include <kurllabel.h>
00041 #include <kstdguiitem.h>
00042
00043
00044 #include <kcombobox.h>
00045 #include "ksslcertificate.h"
00046 #include "ksslcertchain.h"
00047 #include "ksslsigners.h"
00048
00049
00050 class KSSLInfoDlg::KSSLInfoDlgPrivate {
00051 private:
00052 friend class KSSLInfoDlg;
00053 bool m_secCon;
00054 QGridLayout *m_layout;
00055 KComboBox *_chain;
00056 KSSLCertificate *_cert;
00057 KSSLCertificate::KSSLValidationList _cert_ksvl;
00058
00059 bool inQuestion;
00060
00061 QLabel *_serialNum;
00062 QLabel *_csl;
00063 QLabel *_validFrom;
00064 QLabel *_validUntil;
00065 QLabel *_digest;
00066
00067 QLabel *pixmap;
00068 QLabel *info;
00069
00070 KSSLCertBox *_subject, *_issuer;
00071 };
00072
00073
00074
00075 KSSLInfoDlg::KSSLInfoDlg(bool secureConnection, QWidget *parent, const char *name, bool modal)
00076 : KDialog(parent, name, modal, Qt::WDestructiveClose), d(new KSSLInfoDlgPrivate) {
00077 QVBoxLayout *topLayout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());
00078 d->m_secCon = secureConnection;
00079 d->m_layout = new QGridLayout(topLayout, 3, 3, KDialog::spacingHint());
00080 d->m_layout->setColStretch(1, 1);
00081 d->m_layout->setColStretch(2, 1);
00082
00083 d->pixmap = new QLabel(this);
00084 d->m_layout->addWidget(d->pixmap, 0, 0);
00085
00086 d->info = new QLabel(this);
00087 d->m_layout->addWidget(d->info, 0, 1);
00088
00089 if (KSSL::doesSSLWork()) {
00090 if (d->m_secCon) {
00091 d->pixmap->setPixmap(BarIcon("encrypted"));
00092 d->info->setText(i18n("Current connection is secured with SSL."));
00093 } else {
00094 d->pixmap->setPixmap(BarIcon("decrypted"));
00095 d->info->setText(i18n("Current connection is not secured with SSL."));
00096 }
00097 } else {
00098 d->pixmap->setPixmap(BarIcon("decrypted"));
00099 d->info->setText(i18n("SSL support is not available in this build of KDE."));
00100 }
00101 d->m_layout->addRowSpacing( 0, 50 );
00102
00103 QHBoxLayout *buttonLayout = new QHBoxLayout(topLayout, KDialog::spacingHint());
00104 buttonLayout->addStretch( 1 );
00105
00106 KPushButton *button;
00107
00108 if (KSSL::doesSSLWork()) {
00109 button = new KPushButton(KGuiItem(i18n("C&ryptography Configuration..."),"configure"), this);
00110 connect(button, SIGNAL(clicked()), SLOT(launchConfig()));
00111 buttonLayout->addWidget( button );
00112 }
00113
00114 button = new KPushButton(KStdGuiItem::close(), this);
00115 connect(button, SIGNAL(clicked()), SLOT(close()));
00116 buttonLayout->addWidget( button );
00117
00118 button->setFocus();
00119
00120 setCaption(i18n("KDE SSL Information"));
00121 d->inQuestion = false;
00122 }
00123
00124
00125 KSSLInfoDlg::~KSSLInfoDlg() {
00126 delete d;
00127 }
00128
00129 void KSSLInfoDlg::launchConfig() {
00130 KProcess p;
00131 p << "kcmshell" << "crypto";
00132 p.start(KProcess::DontCare);
00133 }
00134
00135
00136 void KSSLInfoDlg::setSecurityInQuestion(bool isIt) {
00137 d->inQuestion = isIt;
00138 if (KSSL::doesSSLWork())
00139 if (isIt) {
00140 d->pixmap->setPixmap(BarIcon("halfencrypted"));
00141 if (d->m_secCon) {
00142 d->info->setText(i18n("The main part of this document is secured with SSL, but some parts are not."));
00143 } else {
00144 d->info->setText(i18n("Some of this document is secured with SSL, but the main part is not."));
00145 }
00146 } else {
00147 if (d->m_secCon) {
00148 d->pixmap->setPixmap(BarIcon("encrypted"));
00149 d->info->setText(i18n("Current connection is secured with SSL."));
00150 } else {
00151 d->pixmap->setPixmap(BarIcon("decrypted"));
00152 d->info->setText(i18n("Current connection is not secured with SSL."));
00153 }
00154 }
00155 }
00156
00157
00158 void KSSLInfoDlg::setup( KSSL & ssl, const QString & ip, const QString & url )
00159 {
00160 setup(
00161 &ssl.peerInfo().getPeerCertificate(),
00162 ip,
00163 url,
00164 ssl.connectionInfo().getCipher(),
00165 ssl.connectionInfo().getCipherDescription(),
00166 ssl.connectionInfo().getCipherVersion(),
00167 ssl.connectionInfo().getCipherUsedBits(),
00168 ssl.connectionInfo().getCipherBits(),
00169 ssl.peerInfo().getPeerCertificate().validate()
00170 );
00171 }
00172
00173 void KSSLInfoDlg::setup(KSSLCertificate *cert,
00174 const QString& ip, const QString& url,
00175 const QString& cipher, const QString& cipherdesc,
00176 const QString& sslversion, int usedbits, int bits,
00177 KSSLCertificate::KSSLValidation ) {
00178
00179
00180 d->_cert = cert;
00181
00182 QGridLayout *layout = new QGridLayout(4, 2, KDialog::spacingHint());
00183
00184 layout->addWidget(new QLabel(i18n("Chain:"), this), 0, 0);
00185 d->_chain = new KComboBox(this);
00186 layout->addMultiCellWidget(d->_chain, 1, 1, 0, 1);
00187 connect(d->_chain, SIGNAL(activated(int)), this, SLOT(slotChain(int)));
00188
00189 d->_chain->clear();
00190
00191 if (cert->chain().isValid() && cert->chain().depth() > 1) {
00192 d->_chain->setEnabled(true);
00193 d->_chain->insertItem(i18n("0 - Site Certificate"));
00194 int cnt = 0;
00195 QPtrList<KSSLCertificate> cl = cert->chain().getChain();
00196 cl.setAutoDelete(true);
00197 for (KSSLCertificate *c = cl.first(); c != 0; c = cl.next()) {
00198 KSSLX509Map map(c->getSubject());
00199 QString id;
00200 id = map.getValue("CN");
00201 if (id.length() == 0)
00202 id = map.getValue("O");
00203 if (id.length() == 0)
00204 id = map.getValue("OU");
00205 d->_chain->insertItem(QString::number(++cnt)+" - "+id);
00206 }
00207 d->_chain->setCurrentItem(0);
00208 } else d->_chain->setEnabled(false);
00209
00210 layout->addWidget(new QLabel(i18n("Peer certificate:"), this), 2, 0);
00211 layout->addWidget(d->_subject = static_cast<KSSLCertBox*>(buildCertInfo(cert->getSubject())), 3, 0);
00212 layout->addWidget(new QLabel(i18n("Issuer:"), this), 2, 1);
00213 layout->addWidget(d->_issuer = static_cast<KSSLCertBox*>(buildCertInfo(cert->getIssuer())), 3, 1);
00214 d->m_layout->addMultiCell(layout, 1, 1, 0, 2);
00215
00216 layout = new QGridLayout(11, 2, KDialog::spacingHint());
00217 layout->setColStretch(1, 1);
00218 QLabel *ipl = new QLabel(i18n("IP address:"), this);
00219 layout->addWidget(ipl, 0, 0);
00220 if (ip.isEmpty()) {
00221 ipl->hide();
00222 }
00223 layout->addWidget(ipl = new QLabel(ip, this), 0, 1);
00224 if (ip.isEmpty()) {
00225 ipl->hide();
00226 }
00227 layout->addWidget(new QLabel(i18n("URL:"), this), 1, 0);
00228 KSqueezedTextLabel *urlLabel = new KSqueezedTextLabel(url, this);
00229 layout->addWidget(urlLabel, 1, 1);
00230 layout->addWidget(new QLabel(i18n("Certificate state:"), this), 2, 0);
00231
00232 layout->addWidget(d->_csl = new QLabel("", this), 2, 1);
00233
00234 update();
00235
00236 layout->addWidget(new QLabel(i18n("Valid from:"), this), 3, 0);
00237 layout->addWidget(d->_validFrom = new QLabel("", this), 3, 1);
00238 layout->addWidget(new QLabel(i18n("Valid until:"), this), 4, 0);
00239 layout->addWidget(d->_validUntil = new QLabel("", this), 4, 1);
00240
00241 layout->addWidget(new QLabel(i18n("Serial number:"), this), 5, 0);
00242 layout->addWidget(d->_serialNum = new QLabel("", this), 5, 1);
00243 layout->addWidget(new QLabel(i18n("MD5 digest:"), this), 6, 0);
00244 layout->addWidget(d->_digest = new QLabel("", this), 6, 1);
00245
00246 layout->addWidget(new QLabel(i18n("Cipher in use:"), this), 7, 0);
00247 layout->addWidget(new QLabel(cipher, this), 7, 1);
00248 layout->addWidget(new QLabel(i18n("Details:"), this), 8, 0);
00249 layout->addWidget(new QLabel(cipherdesc.simplifyWhiteSpace(), this), 8, 1);
00250 layout->addWidget(new QLabel(i18n("SSL version:"), this), 9, 0);
00251 layout->addWidget(new QLabel(sslversion, this), 9, 1);
00252 layout->addWidget(new QLabel(i18n("Cipher strength:"), this), 10, 0);
00253 layout->addWidget(new QLabel(i18n("%1 bits used of a %2 bit cipher").arg(usedbits).arg(bits), this), 10, 1);
00254 d->m_layout->addMultiCell(layout, 2, 2, 0, 2);
00255
00256 displayCert(cert);
00257 }
00258
00259 void KSSLInfoDlg::setCertState(const QString &errorNrs)
00260 {
00261 d->_cert_ksvl.clear();
00262 QStringList errors = QStringList::split(':', errorNrs);
00263 for(QStringList::ConstIterator it = errors.begin();
00264 it != errors.end(); ++it)
00265 {
00266 d->_cert_ksvl << (KSSLCertificate::KSSLValidation) (*it).toInt();
00267 }
00268 }
00269
00270 void KSSLInfoDlg::displayCert(KSSLCertificate *x) {
00271 QPalette cspl;
00272
00273 d->_serialNum->setText(x->getSerialNumber());
00274
00275 cspl = d->_validFrom->palette();
00276 if (x->getQDTNotBefore() > QDateTime::currentDateTime(Qt::UTC))
00277 cspl.setColor(QColorGroup::Foreground, QColor(196,33,21));
00278 else cspl.setColor(QColorGroup::Foreground, QColor(42,153,59));
00279 d->_validFrom->setPalette(cspl);
00280 d->_validFrom->setText(x->getNotBefore());
00281
00282 cspl = d->_validUntil->palette();
00283 if (x->getQDTNotAfter() < QDateTime::currentDateTime(Qt::UTC))
00284 cspl.setColor(QColorGroup::Foreground, QColor(196,33,21));
00285 else cspl.setColor(QColorGroup::Foreground, QColor(42,153,59));
00286 d->_validUntil->setPalette(cspl);
00287 d->_validUntil->setText(x->getNotAfter());
00288
00289 cspl = palette();
00290
00291 KSSLCertificate::KSSLValidation ksv;
00292 KSSLCertificate::KSSLValidationList ksvl;
00293 if ((x == d->_cert) && !d->_cert_ksvl.isEmpty()) {
00294 ksvl = d->_cert_ksvl;
00295 ksv = ksvl.first();
00296 } else {
00297 if (x == d->_cert)
00298 ksvl = d->_cert->validateVerbose(KSSLCertificate::SSLServer);
00299 else
00300 ksvl = d->_cert->validateVerbose(KSSLCertificate::SSLServer, x);
00301
00302 if (ksvl.isEmpty())
00303 ksvl << KSSLCertificate::Ok;
00304
00305 ksv = ksvl.first();
00306
00307 if (ksv == KSSLCertificate::SelfSigned) {
00308 if (x->getQDTNotAfter() > QDateTime::currentDateTime(Qt::UTC) &&
00309 x->getQDTNotBefore() < QDateTime::currentDateTime(Qt::UTC)) {
00310 if (KSSLSigners().useForSSL(*x))
00311 ksv = KSSLCertificate::Ok;
00312 } else {
00313 ksv = KSSLCertificate::Expired;
00314 }
00315 }
00316 }
00317
00318 if (ksv == KSSLCertificate::Ok) {
00319 cspl.setColor(QColorGroup::Foreground, QColor(42,153,59));
00320 } else if (ksv != KSSLCertificate::Irrelevant) {
00321 cspl.setColor(QColorGroup::Foreground, QColor(196,33,21));
00322 }
00323 d->_csl->setPalette(cspl);
00324
00325 QString errorStr;
00326 for(KSSLCertificate::KSSLValidationList::ConstIterator it = ksvl.begin();
00327 it != ksvl.end(); ++it) {
00328 if (!errorStr.isEmpty())
00329 errorStr.append('\n');
00330 errorStr += KSSLCertificate::verifyText(*it);
00331 }
00332
00333 d->_csl->setText(errorStr);
00334 d->_csl->setMinimumSize(d->_csl->sizeHint());
00335
00336 d->_subject->setValues(x->getSubject());
00337 d->_issuer->setValues(x->getIssuer());
00338
00339 d->_digest->setText(x->getMD5DigestText());
00340 }
00341
00342
00343 void KSSLInfoDlg::slotChain(int x) {
00344 if (x == 0) {
00345 displayCert(d->_cert);
00346 } else {
00347 QPtrList<KSSLCertificate> cl = d->_cert->chain().getChain();
00348 cl.setAutoDelete(true);
00349 for (int i = 0; i < x-1; i++)
00350 cl.remove((unsigned int)0);
00351 KSSLCertificate thisCert = *(cl.at(0));
00352 cl.remove((unsigned int)0);
00353 thisCert.chain().setChain(cl);
00354 displayCert(&thisCert);
00355 }
00356 }
00357
00358
00359 KSSLCertBox *KSSLInfoDlg::certInfoWidget(QWidget *parent, const QString &certName, QWidget *mailCatcher) {
00360 KSSLCertBox *result = new KSSLCertBox(parent);
00361 if (!certName.isEmpty()) {
00362 result->setValues(certName, mailCatcher);
00363 }
00364 return result;
00365 }
00366
00367
00368 KSSLCertBox::KSSLCertBox(QWidget *parent, const char *name, WFlags f)
00369 : QScrollView(parent, name, f)
00370 {
00371 _frame = 0L;
00372 setBackgroundMode(QWidget::PaletteButton);
00373 setValues(QString::null, 0L);
00374 }
00375
00376
00377 void KSSLCertBox::setValues(QString certName, QWidget *mailCatcher) {
00378 if (_frame) {
00379 removeChild(_frame);
00380 delete _frame;
00381 }
00382
00383 if (certName.isEmpty()) {
00384 _frame = new QFrame(this);
00385 addChild(_frame);
00386 viewport()->setBackgroundMode(_frame->backgroundMode());
00387 _frame->show();
00388 updateScrollBars();
00389 show();
00390 return;
00391 }
00392
00393 KSSLX509Map cert(certName);
00394 QString tmp;
00395 viewport()->setBackgroundMode(QWidget::PaletteButton);
00396 _frame = new QFrame(this);
00397 QGridLayout *grid = new QGridLayout(_frame, 1, 2, KDialog::marginHint(), KDialog::spacingHint());
00398 grid->setAutoAdd(true);
00399 QLabel *label = 0L;
00400 if (!(tmp = cert.getValue("O")).isEmpty()) {
00401 label = new QLabel(i18n("Organization:"), _frame);
00402 label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00403 new QLabel(tmp, _frame);
00404 }
00405 if (!(tmp = cert.getValue("OU")).isEmpty()) {
00406 label = new QLabel(i18n("Organizational unit:"), _frame);
00407 label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00408 new QLabel(tmp, _frame);
00409 }
00410 if (!(tmp = cert.getValue("L")).isEmpty()) {
00411 label = new QLabel(i18n("Locality:"), _frame);
00412 label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00413 new QLabel(tmp, _frame);
00414 }
00415 if (!(tmp = cert.getValue("ST")).isEmpty()) {
00416 label = new QLabel(i18n("Federal State","State:"), _frame);
00417 label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00418 new QLabel(tmp, _frame);
00419 }
00420 if (!(tmp = cert.getValue("C")).isEmpty()) {
00421 label = new QLabel(i18n("Country:"), _frame);
00422 label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00423 new QLabel(tmp, _frame);
00424 }
00425 if (!(tmp = cert.getValue("CN")).isEmpty()) {
00426 label = new QLabel(i18n("Common name:"), _frame);
00427 label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00428 new QLabel(tmp, _frame);
00429 }
00430 if (!(tmp = cert.getValue("Email")).isEmpty()) {
00431 label = new QLabel(i18n("Email:"), _frame);
00432 label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00433 if (mailCatcher) {
00434 KURLLabel *mail = new KURLLabel(tmp, tmp, _frame);
00435 connect(mail, SIGNAL(leftClickedURL(const QString &)), mailCatcher, SLOT(mailClicked(const QString &)));
00436 } else {
00437 label = new QLabel(tmp, _frame);
00438 }
00439 }
00440 if (label && viewport()) {
00441 viewport()->setBackgroundMode(label->backgroundMode());
00442 }
00443 addChild(_frame);
00444 updateScrollBars();
00445 _frame->show();
00446 show();
00447 }
00448
00449
00450 QScrollView *KSSLInfoDlg::buildCertInfo(const QString &certName) {
00451 return KSSLInfoDlg::certInfoWidget(this, certName, this);
00452 }
00453
00454 void KSSLInfoDlg::urlClicked(const QString &url) {
00455 kapp->invokeBrowser(url);
00456 }
00457
00458 void KSSLInfoDlg::mailClicked(const QString &url) {
00459 kapp->invokeMailer(url, QString::null);
00460 }
00461
00462 #include "ksslinfodlg.moc"
00463