changeset 198:56ae02b4a0fc

Merged
author Sascha Wilde <wilde@intevation.de>
date Wed, 26 Mar 2014 12:38:10 +0100
parents 5d380b662198 (current diff) 17eb8ad43984 (diff)
children 45f6b62f91e7
files
diffstat 13 files changed, 255 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/cinst/windowsstore.c	Wed Mar 26 12:37:19 2014 +0100
+++ b/cinst/windowsstore.c	Wed Mar 26 12:38:10 2014 +0100
@@ -17,7 +17,7 @@
                   NULL, err, 0, (LPWSTR) &bufPtr, 0, NULL);
   if (!bufPtr)
     {
-      HMODULE hWinhttp = GetModuleHandleW (L"winhttp");
+      HMODULE hWinhttp = GetModuleHandleW (L"crypt32");
       if (hWinhttp)
         {
           FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -28,7 +28,7 @@
         }
     }
   if (!bufPtr)
-    printf ("Error getting last error\n");
+    printf ("Error getting last error for code: %lx \n", err);
   return bufPtr;
 }
 
--- a/common/strhelp.c	Wed Mar 26 12:37:19 2014 +0100
+++ b/common/strhelp.c	Wed Mar 26 12:38:10 2014 +0100
@@ -175,10 +175,10 @@
 
     ret = base64_decode((unsigned char *)*dst, dst_size,
                         (unsigned char *)src, src_size);
-    if (!ret) {
+    if (ret) {
         free (*dst);
         *dst = NULL;
-        dst_size = 0;
+        *dst_size = 0;
     }
     return ret;
 }
--- a/common/strhelp.h	Wed Mar 26 12:37:19 2014 +0100
+++ b/common/strhelp.h	Wed Mar 26 12:38:10 2014 +0100
@@ -1,6 +1,10 @@
 #ifndef STRHELP_H
 #define STRHELP_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdbool.h>
 
 /**
@@ -89,5 +93,8 @@
  */
 int str_base64_decode(char **dst, size_t *dst_size, char *src,
                       size_t src_size);
+#ifdef __cplusplus
+}
+#endif
 
 #endif
--- a/ui/CMakeLists.txt	Wed Mar 26 12:37:19 2014 +0100
+++ b/ui/CMakeLists.txt	Wed Mar 26 12:38:10 2014 +0100
@@ -16,6 +16,7 @@
     ${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/listupdatedialog.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/helpdialog.cpp
     ${CERTIFICATELIST_SOURCES}
     ${DOWNLOADER_SOURCES}
 )
--- a/ui/certificate.cpp	Wed Mar 26 12:37:19 2014 +0100
+++ b/ui/certificate.cpp	Wed Mar 26 12:38:10 2014 +0100
@@ -1,15 +1,18 @@
 #include "certificate.h"
 #include <QDebug>
+#include <QStringList>
 #include <QObject>
 
 #include <polarssl/x509_crt.h>
 
+#define POLARSSL_INFO_BUF_SIZE 2000
+
 Certificate::Certificate(const QString& b64Line) :
-    mValid(false),
-    mShortDescription(QObject::tr("Invalid Certificate"))
+    mValid(false)
 {
     int ret = -1;
-    char buf[2000];
+    char buf[POLARSSL_INFO_BUF_SIZE];
+
     x509_crt x509cert;
 
     /* Cut of the first two chars (e.g. I: and decode) */
@@ -26,8 +29,8 @@
         return;
     }
 
-    ret = x509_crt_info(buf, 2000, "", &x509cert);
-    x509_crt_free(&x509cert);
+    /* Get a full details string */
+    ret = x509_crt_info(buf, POLARSSL_INFO_BUF_SIZE, "", &x509cert);
 
     if (ret <= 0) {
         qDebug() << "Getting certificate info failed with error: " << ret;
@@ -35,14 +38,46 @@
     }
 
     /* In case of success the return value is the size of the information
-     * written into buf
-     * */
-
+     * written into buf */
     mDetails = QString::fromUtf8(buf, ret);
 
-    mShortDescription = mDetails; /* TODO */
+    /* Get the subject */
+    ret = x509_dn_gets(buf, POLARSSL_INFO_BUF_SIZE, &(x509cert.subject));
+
+    if (ret <= 0) {
+        qDebug() << "Getting certificate subject failed with error: " << ret;
+        return;
+    }
+
+    /* TODO check that all asn encodings are handled */
+    QString subject = QString::fromUtf8(buf, ret);
+
+    /* TODO check that escaped , are not possible */
+    QStringList attrs = subject.split(", ");
+
+    foreach (const QString& attr, attrs) {
+        QStringList kv = attr.split("=");
+        if (kv.size() != 2) {
+            qDebug() << "Failed to parse subject element: " << attr;
+            continue;
+        }
+        mSubjectAttrs.insert(kv[0], kv[1]);
+    }
+
+    /* For more information to get from a x509_crt see
+     * https://polarssl.org/api/x509_8h.html */
+
+    x509_crt_free(&x509cert);
 
     mValid = true;
 
     mBaseLine = b64Line;
 }
+
+QString Certificate::getSubjectAttr (const QString& attrName) const {
+    return mSubjectAttrs.value(attrName);
+}
+
+QString Certificate::shortDescription() const {
+    return getSubjectAttr("CN");
+}
--- a/ui/certificate.h	Wed Mar 26 12:37:19 2014 +0100
+++ b/ui/certificate.h	Wed Mar 26 12:38:10 2014 +0100
@@ -7,6 +7,7 @@
  */
 
 #include <QByteArray>
+#include <QMap>
 #include <QString>
 
 #ifdef Q_OS_WIN
@@ -36,7 +37,7 @@
      *  for this certificate
      *
      **/
-    const QString& shortDescription() const {return mShortDescription;}
+    QString shortDescription() const;
 
     /** @brief get details for the certificate
      *
@@ -54,11 +55,22 @@
      **/
     const QString& base64Line() const {return mBaseLine;}
 
+    /** @brief get a single attribute of the subject
+     *
+     * Returns a single attribute of the subject such as the
+     * common name.
+     *
+     * @param[in] attr the Attribute name. to get e.g. "CN"
+     *
+     * @returns the value of the attribute or a null string
+     **/
+    QString getSubjectAttr(const QString& attr) const;
+
 private:
     bool mValid;
 
     QString mDetails;
-    QString mShortDescription;
     QString mBaseLine;
+    QMap <QString, QString> mSubjectAttrs;
 };
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/helpdialog.cpp	Wed Mar 26 12:38:10 2014 +0100
@@ -0,0 +1,28 @@
+#include "helpdialog.h"
+#include <QDebug>
+#include <QVBoxLayout>
+#include <QTextEdit>
+#include <QPushButton>
+
+HelpDialog::HelpDialog(QMainWindow *parent) :
+    QDialog(parent)
+{
+    setupGUI();
+}
+
+void HelpDialog::setupGUI()
+{
+    QVBoxLayout *mainLayout = new QVBoxLayout(this);
+    QTextEdit *helpText = new QTextEdit;
+    helpText->setReadOnly(true);
+    helpText->setPlainText(tr("This dialog contains some text to help the user."));
+
+    QHBoxLayout *buttonLayout = new QHBoxLayout;
+    QPushButton *closeButton = new QPushButton(tr("Close"));
+    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
+    buttonLayout->insertStretch(0, 10);
+    buttonLayout->addWidget(closeButton);
+
+    mainLayout->addWidget(helpText);
+    mainLayout->addLayout(buttonLayout);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/helpdialog.h	Wed Mar 26 12:38:10 2014 +0100
@@ -0,0 +1,21 @@
+#ifndef HELPDIALOG_H
+#define HELPDIALOG_H
+
+#include <QDialog>
+#include <QMainWindow>
+/**
+ * @file helpdialog.h
+ * @brief The dialog for help text.
+ */
+
+class HelpDialog : public QDialog
+{
+public:
+    /** @brief Create a help dialog */
+    HelpDialog(QMainWindow *parent);
+
+private:
+    void setupGUI();
+
+};
+#endif // HELPDIALOG_H
--- a/ui/mainwindow.cpp	Wed Mar 26 12:37:19 2014 +0100
+++ b/ui/mainwindow.cpp	Wed Mar 26 12:38:10 2014 +0100
@@ -9,6 +9,11 @@
 #include <QApplication>
 #include <QFile>
 #include <QTimer>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGroupBox>
+#include <QPushButton>
+#include <QSplitter>
 
 // The amount of time in minutes stay silent if we have
 // something to say
@@ -21,11 +26,13 @@
 #include "certificatelist.h"
 #include "downloader.h"
 #include "listupdatedialog.h"
+#include "helpdialog.h"
 
 MainWindow::MainWindow() {
     createActions();
     createTrayIcon();
     createMenuBar();
+    createContent();
     qRegisterMetaType<SSLConnection::ErrorCode>("SSLConnection::ErrorCode");
 
     connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
@@ -118,6 +125,7 @@
         mCurMessage = tr("An updated certificate list is available. Click here to install.");
         setState(NewListAvailable);
         showMessage();
+        loadCertificateList();
     }
 }
 
@@ -213,16 +221,88 @@
     setMenuBar(mMenuBar);
 }
 
-void MainWindow::showSettings() {
+void MainWindow::createContent()
+{
+    // Create a central widget containing the main layout.
+    QWidget *base = new QWidget;
+
+    QVBoxLayout *mainLayout = new QVBoxLayout;
+    QHBoxLayout *certLayout = new QHBoxLayout;
+    QHBoxLayout *bottomLayout = new QHBoxLayout;
+
+    QGroupBox *certBox = new QGroupBox(tr("Managed Certificates"));
+    certificateList = new QListWidget;
+    connect(certificateList, SIGNAL(itemClicked(QListWidgetItem*)),
+        this, SLOT(showDetails(QListWidgetItem*)));
+    certificateDetails = new QTextEdit;
+    certificateDetails->setReadOnly(true);
+    QSplitter *splitter = new QSplitter(certBox);
+    splitter->addWidget(certificateList);
+    splitter->addWidget(certificateDetails);
+    certLayout->addWidget(splitter);
+    certBox->setLayout(certLayout);
+
+    QPushButton *update = new QPushButton("Search for Updates");
+    connect(update, SIGNAL(clicked()), this, SLOT(checkUpdates()));
+    bottomLayout->insertStretch(0, 10);
+    bottomLayout->addWidget(update);
+    mainLayout->addWidget(certBox);
+    mainLayout->addLayout(bottomLayout);
+
+    // QMainWindow allready has a layout. All child layouts and widgets are
+    // managed in the central widget.
+    base->setLayout(mainLayout);
+    setCentralWidget(base);
+}
+
+void MainWindow::loadCertificateList()
+{
+    qDebug() << "display certificates";
+    certificateList->clear();
+    foreach (const Certificate &cert, mListToInstall.getInstallCertificates()) {
+        if (!cert.isValid()) {
+            qWarning() << "Invalid certificate in list";
+            continue;
+        }
+        QListWidgetItem* item = new QListWidgetItem(cert.shortDescription());
+        item->setData(Qt::UserRole, cert.details());
+        QIcon *certIcon = new QIcon(":/img/tray_22.png");
+        item->setIcon(*certIcon);
+        certificateList->addItem(item);
+    }
+    foreach (const Certificate& cert, mListToInstall.getRemoveCertificates()) {
+        if (!cert.isValid()) {
+            qWarning() << "Invalid certificate in list";
+            continue;
+        }
+        QListWidgetItem* item = new QListWidgetItem(cert.shortDescription());
+        item->setData(Qt::UserRole, cert.details());
+        QIcon *certIcon = new QIcon(":/img/tray_22.png");
+        item->setIcon(*certIcon);
+        certificateList->addItem(item);
+    }
+}
+
+void MainWindow::showSettings()
+{
     qDebug() << "show settingsdialog";
 }
 
 void MainWindow::showHelp()
 {
     qDebug() << "show helpdialog";
+    HelpDialog *help = new HelpDialog(this);
+    help->show();
 }
 
 void MainWindow::showAbout()
 {
     qDebug() << "show aboutdialog";
 }
+
+void MainWindow::showDetails(QListWidgetItem *item)
+{
+    qDebug() << "show details";
+    QString details = item->data(Qt::UserRole).toString();
+    certificateDetails->setPlainText(details);
+}
--- a/ui/mainwindow.h	Wed Mar 26 12:37:19 2014 +0100
+++ b/ui/mainwindow.h	Wed Mar 26 12:38:10 2014 +0100
@@ -10,6 +10,8 @@
 #include <QMainWindow>
 #include <QSettings>
 #include <QMenuBar>
+#include <QListWidget>
+#include <QTextEdit>
 
 #include "downloader.h"
 #include "certificatelist.h"
@@ -49,6 +51,7 @@
     void showSettings();
     void showHelp();
     void showAbout();
+    void showDetails(QListWidgetItem*);
 
 private:
     /** @brief check the integrity of available files.
@@ -63,6 +66,8 @@
     void createTrayIcon();
     void createActions();
     void createMenuBar();
+    void createContent();
+    void loadCertificateList();
 
     QString mCurMessage;
     QString mInstalledSWVersion;
@@ -79,6 +84,9 @@
     QMenuBar *mMenuBar;
 
     CertificateList mListToInstall;
+
+    QListWidget *certificateList;
+    QTextEdit *certificateDetails;
 };
 
 #endif // MAINWINDOW_H
--- a/ui/tests/CMakeLists.txt	Wed Mar 26 12:37:19 2014 +0100
+++ b/ui/tests/CMakeLists.txt	Wed Mar 26 12:38:10 2014 +0100
@@ -37,6 +37,7 @@
 
 # Cinstprocess
 add_m13_test(cinstprocesstest.cpp "${CERTIFICATELIST_SOURCES}")
+add_m13_test(commontest.cpp "")
 
 #add_m13_test(${CMAKE_SOURCE_DIR}/ui/main.cpp "${M13UI_SOURCES}")
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/tests/commontest.cpp	Wed Mar 26 12:38:10 2014 +0100
@@ -0,0 +1,33 @@
+#include <QString>
+#include <QByteArray>
+#include <QTest>
+
+#include "commontest.h"
+#include "strhelp.h"
+
+void CommonTest::testStrBase64Decode() {
+    char garbage[1000];
+    char *data = NULL;
+    size_t data_size = 0;
+    int ret;
+    for (int i = 0; i < 1000; i++) {
+        garbage[i] = (char) qrand() % 255;
+    }
+
+    QByteArray ba(garbage, 1000);
+
+    QByteArray baB64 = ba.toBase64();
+
+    ret = str_base64_decode(&data, &data_size, (char *)baB64.constData(), baB64.size());
+
+    QVERIFY(ret == 0);
+    QVERIFY(data_size == 1000);
+    QVERIFY(data);
+
+    for (size_t i = 0; i < data_size; i++) {
+        QVERIFY(garbage[i] == data[i]);
+    }
+    free (data);
+}
+
+QTEST_GUILESS_MAIN (CommonTest);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/tests/commontest.h	Wed Mar 26 12:38:10 2014 +0100
@@ -0,0 +1,13 @@
+#ifndef COMMONTEST_H
+#define COMMONTEST_H
+
+#include <QObject>
+
+class CommonTest: public QObject
+{
+  Q_OBJECT
+
+private Q_SLOTS:
+  void testStrBase64Decode();
+};
+#endif

http://wald.intevation.org/projects/trustbridge/