diff ui/sslconnection_curl.cpp @ 908:d1c951b3012d

Curl based implementation of sslconnection
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 13 Aug 2014 19:35:08 +0200
parents
children eaed02defe6a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/sslconnection_curl.cpp	Wed Aug 13 19:35:08 2014 +0200
@@ -0,0 +1,133 @@
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=2)
+ * and comes with ABSOLUTELY NO WARRANTY!
+ * See LICENSE.txt for details.
+ */
+
+#include "sslconnection_curl.h"
+
+#define CONNECTION_DEBUG
+
+SSLConnectionCurl::SSLConnectionCurl(const QString& url,
+                             const QByteArray& certificate):
+    SSLConnection (url, certificate),
+    mCurl (NULL)
+{
+    curl_global_init(CURL_GLOBAL_DEFAULT);
+    mCurl = curl_easy_init();
+
+    if (!mCurl) {
+        qDebug() << "Failed to initialize curl";
+        return;
+    }
+
+    if (curl_easy_setopt(mCurl, CURLOPT_URL, QUrl(url).toEncoded().constData()) != CURLE_OK) {
+        qDebug() << "Setting url failed";
+        return;
+    }
+
+    if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, 1L) != CURLE_OK) {
+        /* Should be default anyway */
+        qDebug() << "Setting verifypeer failed";
+        return;
+    }
+
+    if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, 0L) != CURLE_OK) {
+        /* There are no limitiations for the pinned certificate */
+        qDebug() << "Setting verifyhost failed";
+        return;
+    }
+
+    mCertFile.open();
+    if (mCertFile.write(mPinnedCert) != mPinnedCert.size()) {
+        qDebug() << "Failed to write temporary certificate";
+        return;
+    }
+    mCertFile.close();
+
+    if (curl_easy_setopt(mCurl, CURLOPT_CAINFO,
+                mCertFile.fileName().toUtf8().constData()) != CURLE_OK) {
+        qDebug() << "Failed to write temporary certificate";
+        return;
+    }
+    mInitialized = true;
+
+#ifdef CONNECTION_DEBUG
+    curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L);
+#endif
+}
+
+SSLConnectionCurl::~SSLConnectionCurl() {
+    if (mCurl) {
+        curl_easy_cleanup (mCurl);
+    }
+    if (mInitialized) {
+        mCertFile.close();
+    }
+    curl_global_cleanup();
+}
+
+int SSLConnectionCurl::connect() {
+    if (curl_easy_setopt(mCurl, CURLOPT_CONNECT_ONLY, 1L) != CURLE_OK) {
+        qDebug() << "Failed to set connect only option";
+        return -1;
+    }
+    if (curl_easy_perform (mCurl) != CURLE_OK) {
+        qDebug() << "Failed to connect";
+        mErrorState = NoConnection;
+        return -1;
+    }
+    mConnected = true;
+    return 0;
+}
+
+int SSLConnectionCurl::write(const QByteArray& request) {
+    size_t written = 0;
+
+    if (curl_easy_send (mCurl, request.constData(), request.size(), &written) != CURLE_OK) {
+        qDebug() << "Failed to send request";
+        return -1;
+    }
+    if (written != (size_t)request.size()) {
+        qDebug() << "Failed to write everything";
+        return -1;
+    }
+    return 0;
+}
+
+QByteArray SSLConnectionCurl::read(size_t len)
+{
+    unsigned char buf[len];
+    QByteArray retval("");
+    CURLcode ret;
+    size_t read = 0;
+    unsigned int tries = 0;
+
+    do {
+        memset (buf, 0, sizeof(buf));
+        ret = curl_easy_recv (mCurl, buf, len, &read);
+        if (ret == CURLE_OK && read == 0) {
+            return retval;
+        }
+        if (ret == CURLE_AGAIN) {
+            tries++;
+            continue;
+        }
+        if (ret != CURLE_OK) {
+            qDebug() << "Read failed.";
+            return QByteArray();
+        }
+        if (len < (len - read)) {
+            /* Should never happen if ssl_read behaves */
+            qDebug() << "integer overflow in polarSSLRead";
+            return QByteArray();
+        }
+
+        len -= read;
+        retval.append((const char *)buf, read);
+    } while (len > 0 && tries < 10);
+
+    return retval;
+}

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