ksslinfodlg.cc
00001 /* This file is part of the KDE project 00002 * 00003 * Copyright (C) 2000,2001 George Staikos <staikos@kde.org> 00004 * Copyright (C) 2000 Malte Starostik <malte@kde.org> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "ksslinfodlg.h" 00023 00024 #include <kssl.h> 00025 00026 #include <tqlayout.h> 00027 #include <kpushbutton.h> 00028 #include <tqframe.h> 00029 #include <tqlabel.h> 00030 #include <tqscrollview.h> 00031 #include <tqfile.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 //#include <kstandarddirs.h> 00043 //#include <krun.h> 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 TQGridLayout *m_layout; 00055 KComboBox *_chain; 00056 KSSLCertificate *_cert; 00057 KSSLCertificate::KSSLValidationList _cert_ksvl; 00058 00059 bool inQuestion; 00060 00061 TQLabel *_serialNum; 00062 TQLabel *_csl; 00063 TQLabel *_validFrom; 00064 TQLabel *_validUntil; 00065 TQLabel *_digest; 00066 00067 TQLabel *pixmap; 00068 TQLabel *info; 00069 00070 KSSLCertBox *_subject, *_issuer; 00071 }; 00072 00073 00074 00075 KSSLInfoDlg::KSSLInfoDlg(bool secureConnection, TQWidget *parent, const char *name, bool modal) 00076 : KDialog(parent, name, modal, (WFlags)TQt::WDestructiveClose), d(new KSSLInfoDlgPrivate) { 00077 TQVBoxLayout *topLayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); 00078 d->m_secCon = secureConnection; 00079 d->m_layout = new TQGridLayout(topLayout, 3, 3, KDialog::spacingHint()); 00080 d->m_layout->setColStretch(1, 1); 00081 d->m_layout->setColStretch(2, 1); 00082 00083 d->pixmap = new TQLabel(this); 00084 d->m_layout->addWidget(d->pixmap, 0, 0); 00085 00086 d->info = new TQLabel(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 ); // give minimum height to look better 00102 00103 TQHBoxLayout *buttonLayout = new TQHBoxLayout(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, TQT_SIGNAL(clicked()), TQT_SLOT(launchConfig())); 00111 buttonLayout->addWidget( button ); 00112 } 00113 00114 button = new KPushButton(KStdGuiItem::close(), this); 00115 connect(button, TQT_SIGNAL(clicked()), TQT_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 TQString & ip, const TQString & 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 TQString& ip, const TQString& url, 00175 const TQString& cipher, const TQString& cipherdesc, 00176 const TQString& sslversion, int usedbits, int bits, 00177 KSSLCertificate::KSSLValidation /*certState*/) { 00178 // Needed to put the GUI stuff here to get the layouting right 00179 00180 d->_cert = cert; 00181 00182 TQGridLayout *layout = new TQGridLayout(4, 2, KDialog::spacingHint()); 00183 00184 layout->addWidget(new TQLabel(i18n("Chain:"), this), 0, 0); 00185 d->_chain = new KComboBox(this); 00186 layout->addMultiCellWidget(d->_chain, 1, 1, 0, 1); 00187 connect(d->_chain, TQT_SIGNAL(activated(int)), this, TQT_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 TQPtrList<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 TQString 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(TQString::number(++cnt)+" - "+id); 00206 } 00207 d->_chain->setCurrentItem(0); 00208 } else d->_chain->setEnabled(false); 00209 00210 layout->addWidget(new TQLabel(i18n("Peer certificate:"), this), 2, 0); 00211 layout->addWidget(d->_subject = static_cast<KSSLCertBox*>(buildCertInfo(cert->getSubject())), 3, 0); 00212 layout->addWidget(new TQLabel(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 TQGridLayout(11, 2, KDialog::spacingHint()); 00217 layout->setColStretch(1, 1); 00218 TQLabel *ipl = new TQLabel(i18n("IP address:"), this); 00219 layout->addWidget(ipl, 0, 0); 00220 if (ip.isEmpty()) { 00221 ipl->hide(); 00222 } 00223 layout->addWidget(ipl = new TQLabel(ip, this), 0, 1); 00224 if (ip.isEmpty()) { 00225 ipl->hide(); 00226 } 00227 layout->addWidget(new TQLabel(i18n("URL:"), this), 1, 0); 00228 KSqueezedTextLabel *urlLabel = new KSqueezedTextLabel(url, this); 00229 layout->addWidget(urlLabel, 1, 1); 00230 layout->addWidget(new TQLabel(i18n("Certificate state:"), this), 2, 0); 00231 00232 layout->addWidget(d->_csl = new TQLabel("", this), 2, 1); 00233 00234 update(); 00235 00236 layout->addWidget(new TQLabel(i18n("Valid from:"), this), 3, 0); 00237 layout->addWidget(d->_validFrom = new TQLabel("", this), 3, 1); 00238 layout->addWidget(new TQLabel(i18n("Valid until:"), this), 4, 0); 00239 layout->addWidget(d->_validUntil = new TQLabel("", this), 4, 1); 00240 00241 layout->addWidget(new TQLabel(i18n("Serial number:"), this), 5, 0); 00242 layout->addWidget(d->_serialNum = new TQLabel("", this), 5, 1); 00243 layout->addWidget(new TQLabel(i18n("MD5 digest:"), this), 6, 0); 00244 layout->addWidget(d->_digest = new TQLabel("", this), 6, 1); 00245 00246 layout->addWidget(new TQLabel(i18n("Cipher in use:"), this), 7, 0); 00247 layout->addWidget(new TQLabel(cipher, this), 7, 1); 00248 layout->addWidget(new TQLabel(i18n("Details:"), this), 8, 0); 00249 layout->addWidget(new TQLabel(cipherdesc.simplifyWhiteSpace(), this), 8, 1); 00250 layout->addWidget(new TQLabel(i18n("SSL version:"), this), 9, 0); 00251 layout->addWidget(new TQLabel(sslversion, this), 9, 1); 00252 layout->addWidget(new TQLabel(i18n("Cipher strength:"), this), 10, 0); 00253 layout->addWidget(new TQLabel(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 ipl->setTextFormat(TQt::PlainText); 00257 urlLabel->setTextFormat(TQt::PlainText); 00258 d->_serialNum->setTextFormat(TQt::PlainText); 00259 d->_csl->setTextFormat(TQt::PlainText); 00260 d->_validFrom->setTextFormat(TQt::PlainText); 00261 d->_validUntil->setTextFormat(TQt::PlainText); 00262 d->_digest->setTextFormat(TQt::PlainText); 00263 00264 displayCert(cert); 00265 } 00266 00267 void KSSLInfoDlg::setCertState(const TQString &errorNrs) 00268 { 00269 d->_cert_ksvl.clear(); 00270 TQStringList errors = TQStringList::split(':', errorNrs); 00271 for(TQStringList::ConstIterator it = errors.begin(); 00272 it != errors.end(); ++it) 00273 { 00274 d->_cert_ksvl << (KSSLCertificate::KSSLValidation) (*it).toInt(); 00275 } 00276 } 00277 00278 void KSSLInfoDlg::displayCert(KSSLCertificate *x) { 00279 TQPalette cspl; 00280 00281 d->_serialNum->setText(x->getSerialNumber()); 00282 00283 cspl = d->_validFrom->palette(); 00284 if (x->getQDTNotBefore() > TQDateTime::currentDateTime(Qt::UTC)) 00285 cspl.setColor(TQColorGroup::Foreground, TQColor(196,33,21)); 00286 else cspl.setColor(TQColorGroup::Foreground, TQColor(42,153,59)); 00287 d->_validFrom->setPalette(cspl); 00288 d->_validFrom->setText(x->getNotBefore()); 00289 00290 cspl = d->_validUntil->palette(); 00291 if (x->getQDTNotAfter() < TQDateTime::currentDateTime(Qt::UTC)) 00292 cspl.setColor(TQColorGroup::Foreground, TQColor(196,33,21)); 00293 else cspl.setColor(TQColorGroup::Foreground, TQColor(42,153,59)); 00294 d->_validUntil->setPalette(cspl); 00295 d->_validUntil->setText(x->getNotAfter()); 00296 00297 cspl = palette(); 00298 00299 KSSLCertificate::KSSLValidation ksv; 00300 KSSLCertificate::KSSLValidationList ksvl; 00301 if ((x == d->_cert) && !d->_cert_ksvl.isEmpty()) { 00302 ksvl = d->_cert_ksvl; 00303 ksv = ksvl.first(); 00304 } else { 00305 if (x == d->_cert) 00306 ksvl = d->_cert->validateVerbose(KSSLCertificate::SSLServer); 00307 else 00308 ksvl = d->_cert->validateVerbose(KSSLCertificate::SSLServer, x); 00309 00310 if (ksvl.isEmpty()) 00311 ksvl << KSSLCertificate::Ok; 00312 00313 ksv = ksvl.first(); 00314 00315 if (ksv == KSSLCertificate::SelfSigned) { 00316 if (x->getQDTNotAfter() > TQDateTime::currentDateTime(Qt::UTC) && 00317 x->getQDTNotBefore() < TQDateTime::currentDateTime(Qt::UTC)) { 00318 if (KSSLSigners().useForSSL(*x)) 00319 ksv = KSSLCertificate::Ok; 00320 } else { 00321 ksv = KSSLCertificate::Expired; 00322 } 00323 } 00324 } 00325 00326 if (ksv == KSSLCertificate::Ok) { 00327 cspl.setColor(TQColorGroup::Foreground, TQColor(42,153,59)); 00328 } else if (ksv != KSSLCertificate::Irrelevant) { 00329 cspl.setColor(TQColorGroup::Foreground, TQColor(196,33,21)); 00330 } 00331 d->_csl->setPalette(cspl); 00332 00333 TQString errorStr; 00334 for(KSSLCertificate::KSSLValidationList::ConstIterator it = ksvl.begin(); 00335 it != ksvl.end(); ++it) { 00336 if (!errorStr.isEmpty()) 00337 errorStr.append('\n'); 00338 errorStr += KSSLCertificate::verifyText(*it); 00339 } 00340 00341 d->_csl->setText(errorStr); 00342 d->_csl->setMinimumSize(d->_csl->sizeHint()); 00343 00344 d->_subject->setValues(x->getSubject()); 00345 d->_issuer->setValues(x->getIssuer()); 00346 00347 d->_digest->setText(x->getMD5DigestText()); 00348 } 00349 00350 00351 void KSSLInfoDlg::slotChain(int x) { 00352 if (x == 0) { 00353 displayCert(d->_cert); 00354 } else { 00355 TQPtrList<KSSLCertificate> cl = d->_cert->chain().getChain(); 00356 cl.setAutoDelete(true); 00357 for (int i = 0; i < x-1; i++) 00358 cl.remove((unsigned int)0); 00359 KSSLCertificate thisCert = *(cl.at(0)); 00360 cl.remove((unsigned int)0); 00361 thisCert.chain().setChain(cl); 00362 displayCert(&thisCert); 00363 } 00364 } 00365 00366 00367 KSSLCertBox *KSSLInfoDlg::certInfoWidget(TQWidget *parent, const TQString &certName, TQWidget *mailCatcher) { 00368 KSSLCertBox *result = new KSSLCertBox(parent); 00369 if (!certName.isEmpty()) { 00370 result->setValues(certName, mailCatcher); 00371 } 00372 return result; 00373 } 00374 00375 00376 KSSLCertBox::KSSLCertBox(TQWidget *parent, const char *name, WFlags f) 00377 : TQScrollView(parent, name, f) 00378 { 00379 _frame = 0L; 00380 setBackgroundMode(TQWidget::PaletteButton); 00381 setValues(TQString::null, 0L); 00382 } 00383 00384 00385 void KSSLCertBox::setValues(TQString certName, TQWidget *mailCatcher) { 00386 if (_frame) { 00387 removeChild(_frame); 00388 delete _frame; 00389 } 00390 00391 if (certName.isEmpty()) { 00392 _frame = new TQFrame(this); 00393 addChild(_frame); 00394 viewport()->setBackgroundMode(_frame->backgroundMode()); 00395 _frame->show(); 00396 updateScrollBars(); 00397 show(); 00398 return; 00399 } 00400 00401 KSSLX509Map cert(certName); 00402 TQString tmp; 00403 viewport()->setBackgroundMode(TQWidget::PaletteButton); 00404 _frame = new TQFrame(this); 00405 TQGridLayout *grid = new TQGridLayout(_frame, 1, 2, KDialog::marginHint(), KDialog::spacingHint()); 00406 grid->setAutoAdd(true); 00407 TQLabel *label = 0L; 00408 if (!(tmp = cert.getValue("O")).isEmpty()) { 00409 label = new TQLabel(i18n("Organization:"), _frame); 00410 label->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00411 (new TQLabel(tmp, _frame))->setTextFormat(TQt::PlainText); 00412 } 00413 if (!(tmp = cert.getValue("OU")).isEmpty()) { 00414 label = new TQLabel(i18n("Organizational unit:"), _frame); 00415 label->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00416 (new TQLabel(tmp, _frame))->setTextFormat(TQt::PlainText); 00417 } 00418 if (!(tmp = cert.getValue("L")).isEmpty()) { 00419 label = new TQLabel(i18n("Locality:"), _frame); 00420 label->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00421 (new TQLabel(tmp, _frame))->setTextFormat(TQt::PlainText); 00422 } 00423 if (!(tmp = cert.getValue("ST")).isEmpty()) { 00424 label = new TQLabel(i18n("Federal State","State:"), _frame); 00425 label->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00426 (new TQLabel(tmp, _frame))->setTextFormat(TQt::PlainText); 00427 } 00428 if (!(tmp = cert.getValue("C")).isEmpty()) { 00429 label = new TQLabel(i18n("Country:"), _frame); 00430 label->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00431 (new TQLabel(tmp, _frame))->setTextFormat(TQt::PlainText); 00432 } 00433 if (!(tmp = cert.getValue("CN")).isEmpty()) { 00434 label = new TQLabel(i18n("Common name:"), _frame); 00435 label->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00436 (new TQLabel(tmp, _frame))->setTextFormat(TQt::PlainText); 00437 } 00438 if (!(tmp = cert.getValue("Email")).isEmpty()) { 00439 label = new TQLabel(i18n("Email:"), _frame); 00440 label->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00441 if (mailCatcher) { 00442 KURLLabel *mail = new KURLLabel(tmp, tmp, _frame); 00443 connect(mail, TQT_SIGNAL(leftClickedURL(const TQString &)), mailCatcher, TQT_SLOT(mailClicked(const TQString &))); 00444 } else { 00445 label = new TQLabel(tmp, _frame); 00446 label->setTextFormat(TQt::PlainText); 00447 } 00448 } 00449 if (label && viewport()) { 00450 viewport()->setBackgroundMode(label->backgroundMode()); 00451 } 00452 addChild(_frame); 00453 updateScrollBars(); 00454 _frame->show(); 00455 show(); 00456 } 00457 00458 00459 TQScrollView *KSSLInfoDlg::buildCertInfo(const TQString &certName) { 00460 return KSSLInfoDlg::certInfoWidget(this, certName, this); 00461 } 00462 00463 void KSSLInfoDlg::urlClicked(const TQString &url) { 00464 kapp->invokeBrowser(url); 00465 } 00466 00467 void KSSLInfoDlg::mailClicked(const TQString &url) { 00468 kapp->invokeMailer(url, TQString::null); 00469 } 00470 00471 #include "ksslinfodlg.moc" 00472 // vim: ts=4 sw=4 et