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