comparison 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
comparison
equal deleted inserted replaced
907:7bd75417e14e 908:d1c951b3012d
1 /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
2 * Software engineering by Intevation GmbH
3 *
4 * This file is Free Software under the GNU GPL (v>=2)
5 * and comes with ABSOLUTELY NO WARRANTY!
6 * See LICENSE.txt for details.
7 */
8
9 #include "sslconnection_curl.h"
10
11 #define CONNECTION_DEBUG
12
13 SSLConnectionCurl::SSLConnectionCurl(const QString& url,
14 const QByteArray& certificate):
15 SSLConnection (url, certificate),
16 mCurl (NULL)
17 {
18 curl_global_init(CURL_GLOBAL_DEFAULT);
19 mCurl = curl_easy_init();
20
21 if (!mCurl) {
22 qDebug() << "Failed to initialize curl";
23 return;
24 }
25
26 if (curl_easy_setopt(mCurl, CURLOPT_URL, QUrl(url).toEncoded().constData()) != CURLE_OK) {
27 qDebug() << "Setting url failed";
28 return;
29 }
30
31 if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, 1L) != CURLE_OK) {
32 /* Should be default anyway */
33 qDebug() << "Setting verifypeer failed";
34 return;
35 }
36
37 if (curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, 0L) != CURLE_OK) {
38 /* There are no limitiations for the pinned certificate */
39 qDebug() << "Setting verifyhost failed";
40 return;
41 }
42
43 mCertFile.open();
44 if (mCertFile.write(mPinnedCert) != mPinnedCert.size()) {
45 qDebug() << "Failed to write temporary certificate";
46 return;
47 }
48 mCertFile.close();
49
50 if (curl_easy_setopt(mCurl, CURLOPT_CAINFO,
51 mCertFile.fileName().toUtf8().constData()) != CURLE_OK) {
52 qDebug() << "Failed to write temporary certificate";
53 return;
54 }
55 mInitialized = true;
56
57 #ifdef CONNECTION_DEBUG
58 curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L);
59 #endif
60 }
61
62 SSLConnectionCurl::~SSLConnectionCurl() {
63 if (mCurl) {
64 curl_easy_cleanup (mCurl);
65 }
66 if (mInitialized) {
67 mCertFile.close();
68 }
69 curl_global_cleanup();
70 }
71
72 int SSLConnectionCurl::connect() {
73 if (curl_easy_setopt(mCurl, CURLOPT_CONNECT_ONLY, 1L) != CURLE_OK) {
74 qDebug() << "Failed to set connect only option";
75 return -1;
76 }
77 if (curl_easy_perform (mCurl) != CURLE_OK) {
78 qDebug() << "Failed to connect";
79 mErrorState = NoConnection;
80 return -1;
81 }
82 mConnected = true;
83 return 0;
84 }
85
86 int SSLConnectionCurl::write(const QByteArray& request) {
87 size_t written = 0;
88
89 if (curl_easy_send (mCurl, request.constData(), request.size(), &written) != CURLE_OK) {
90 qDebug() << "Failed to send request";
91 return -1;
92 }
93 if (written != (size_t)request.size()) {
94 qDebug() << "Failed to write everything";
95 return -1;
96 }
97 return 0;
98 }
99
100 QByteArray SSLConnectionCurl::read(size_t len)
101 {
102 unsigned char buf[len];
103 QByteArray retval("");
104 CURLcode ret;
105 size_t read = 0;
106 unsigned int tries = 0;
107
108 do {
109 memset (buf, 0, sizeof(buf));
110 ret = curl_easy_recv (mCurl, buf, len, &read);
111 if (ret == CURLE_OK && read == 0) {
112 return retval;
113 }
114 if (ret == CURLE_AGAIN) {
115 tries++;
116 continue;
117 }
118 if (ret != CURLE_OK) {
119 qDebug() << "Read failed.";
120 return QByteArray();
121 }
122 if (len < (len - read)) {
123 /* Should never happen if ssl_read behaves */
124 qDebug() << "integer overflow in polarSSLRead";
125 return QByteArray();
126 }
127
128 len -= read;
129 retval.append((const char *)buf, read);
130 } while (len > 0 && tries < 10);
131
132 return retval;
133 }

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