Mercurial > trustbridge
view 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 source
/* 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; }