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