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