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