Mercurial > trustbridge
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; +}