Skip to content

Commit f737193

Browse files
committed
Add options to verify SSL certificate
1 parent bca962b commit f737193

File tree

5 files changed

+52
-24
lines changed

5 files changed

+52
-24
lines changed

lib/curlrequester.cpp

+15-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include <cstring>
77
#include <thread>
88

9-
CurlRequester::CurlRequester(const std::string& addr, bool ignoreSslErrors)
9+
CurlRequester::CurlRequester(const std::string& addr, const SslConfig& sslConfig)
1010
: _curl(curl_easy_init())
1111
{
1212
bool debugEnabled = LogController::instance().isEnabled(LogController::Debug);
@@ -15,13 +15,18 @@ CurlRequester::CurlRequester(const std::string& addr, bool ignoreSslErrors)
1515
curl_easy_setopt(_curl, CURLOPT_CONNECTTIMEOUT_MS, 2000);
1616
curl_easy_setopt(_curl, CURLOPT_FAILONERROR, 1);
1717

18-
if(ignoreSslErrors)
18+
if(!sslConfig.verifySsl)
1919
{
2020
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYPEER, 0L);
2121
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYHOST, 0L);
2222
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYSTATUS, 0L);
2323
}
2424

25+
if(sslConfig.pinnedPublicKey != "")
26+
{
27+
curl_easy_setopt(_curl, CURLOPT_PINNEDPUBLICKEY, sslConfig.pinnedPublicKey.c_str());
28+
}
29+
2530
_opts = nullptr;
2631
#ifdef USER_AGENT
2732
_opts = curl_slist_append(_opts, "User-Agent: " USER_AGENT);
@@ -179,8 +184,8 @@ std::string http_url(const std::string& str)
179184
return url.toStr();
180185
}
181186

182-
CurlIppPosterBase::CurlIppPosterBase(const std::string& addr, bool ignoreSslErrors)
183-
: CurlRequester(http_url(addr), ignoreSslErrors)
187+
CurlIppPosterBase::CurlIppPosterBase(const std::string& addr, const SslConfig& sslConfig)
188+
: CurlRequester(http_url(addr), sslConfig)
184189
{
185190
_canWrite.unlock();
186191
_canRead.lock();
@@ -208,23 +213,23 @@ CURLcode CurlIppPosterBase::await(Bytestream* data)
208213
return CurlRequester::await(data);
209214
}
210215

211-
CurlIppPoster::CurlIppPoster(const std::string& addr, Bytestream&& data, bool ignoreSslErrors)
212-
: CurlIppPosterBase(addr, ignoreSslErrors)
216+
CurlIppPoster::CurlIppPoster(const std::string& addr, Bytestream&& data, const SslConfig& sslConfig)
217+
: CurlIppPosterBase(addr, sslConfig)
213218
{
214219
curl_easy_setopt(_curl, CURLOPT_POSTFIELDSIZE, data.size());
215220
write(std::move(data));
216221
doRun();
217222
}
218223

219-
CurlIppStreamer::CurlIppStreamer(const std::string& addr, bool ignoreSslErrors)
220-
: CurlIppPosterBase(addr, ignoreSslErrors)
224+
CurlIppStreamer::CurlIppStreamer(const std::string& addr, const SslConfig& sslConfig)
225+
: CurlIppPosterBase(addr, sslConfig)
221226
{
222227
_opts = curl_slist_append(_opts, "Transfer-Encoding: chunked");
223228
doRun();
224229
}
225230

226-
CurlHttpGetter::CurlHttpGetter(const std::string& addr, bool ignoreSslErrors)
227-
: CurlRequester(addr, ignoreSslErrors)
231+
CurlHttpGetter::CurlHttpGetter(const std::string& addr, const SslConfig& sslConfig)
232+
: CurlRequester(addr, sslConfig)
228233
{
229234
doRun();
230235
}

lib/curlrequester.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ enum class Compression
2121
Gzip
2222
};
2323

24+
struct SslConfig
25+
{
26+
bool verifySsl = true;
27+
std::string pinnedPublicKey;
28+
};
29+
2430
class CurlRequester
2531
{
2632
public:
@@ -33,7 +39,7 @@ class CurlRequester
3339

3440
protected:
3541

36-
CurlRequester(const std::string& addr, bool ignoreSslErrors);
42+
CurlRequester(const std::string& addr, const SslConfig& sslConfig=SslConfig());
3743

3844
void doRun();
3945

@@ -94,7 +100,7 @@ class CurlIppPosterBase : public CurlRequester
94100
}
95101

96102
protected:
97-
CurlIppPosterBase(const std::string& addr, bool ignoreSslErrors);
103+
CurlIppPosterBase(const std::string& addr, const SslConfig& sslConfig=SslConfig());
98104

99105
private:
100106
std::mutex _canWrite;
@@ -106,19 +112,19 @@ class CurlIppPosterBase : public CurlRequester
106112
class CurlIppPoster : public CurlIppPosterBase
107113
{
108114
public:
109-
CurlIppPoster(const std::string& addr, Bytestream&& data, bool ignoreSslErrors = false);
115+
CurlIppPoster(const std::string& addr, Bytestream&& data, const SslConfig& sslConfig=SslConfig());
110116
};
111117

112118
class CurlIppStreamer : public CurlIppPosterBase
113119
{
114120
public:
115-
CurlIppStreamer(const std::string& addr, bool ignoreSslErrors = false);
121+
CurlIppStreamer(const std::string& addr, const SslConfig& sslConfig=SslConfig());
116122
};
117123

118124
class CurlHttpGetter : public CurlRequester
119125
{
120126
public:
121-
CurlHttpGetter(const std::string& addr, bool ignoreSslErrors = false);
127+
CurlHttpGetter(const std::string& addr, const SslConfig& sslConfig=SslConfig());
122128
};
123129

124130
#endif // CURLREQUESTER_H

lib/ippprinter.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22

33
#include "configdir.h"
44
#include "log.h"
5-
#include "curlrequester.h"
65
#include "stringutils.h"
76

87
#include <filesystem>
98

10-
IppPrinter::IppPrinter(std::string addr, bool ignoreSslErrors)
11-
: _addr(std::move(addr)), _ignoreSslErrors(ignoreSslErrors)
9+
IppPrinter::IppPrinter(std::string addr, SslConfig sslConfig)
10+
: _addr(std::move(addr)), _sslConfig(std::move(sslConfig))
1211
{
1312
_error = refresh();
1413
}
@@ -141,7 +140,7 @@ Error IppPrinter::doPrint(IppPrintJob& job, const std::string& inFile, Bytestrea
141140
const Converter::ConvertFun& convertFun, const ProgressFun& progressFun)
142141
{
143142
Error error;
144-
CurlIppStreamer cr(_addr, true);
143+
CurlIppStreamer cr(_addr, _sslConfig);
145144
cr.write(std::move(hdr));
146145

147146
if(job.compression.get() == "gzip")
@@ -531,7 +530,7 @@ Error IppPrinter::_doRequest(const IppMsg& req, IppMsg& resp) const
531530
}
532531
DBG(<< "Printer attrs: " << req.getPrinterAttrs().toJSON().dump());
533532

534-
CurlIppPoster reqPoster(_addr, req.encode(), _ignoreSslErrors);
533+
CurlIppPoster reqPoster(_addr, req.encode(), _sslConfig);
535534
Bytestream respBts;
536535
CURLcode res0 = reqPoster.await(&respBts);
537536
if(res0 == CURLE_OK)

lib/ippprinter.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define IPPPRINTER_H
33

44
#include "converter.h"
5+
#include "curlrequester.h"
56
#include "error.h"
67
#include "ippattr.h"
78
#include "ippmsg.h"
@@ -38,7 +39,7 @@ class IppPrinter
3839
std::string stateMessage;
3940
};
4041

41-
IppPrinter(std::string addr, bool ignoreSslErrors=true);
42+
IppPrinter(std::string addr, SslConfig sslConfig);
4243
IppPrinter(IppAttrs printerAttrs) : _printerAttrs(std::move(printerAttrs))
4344
{}
4445
Error refresh();
@@ -106,7 +107,7 @@ class IppPrinter
106107
void _applyOverrides();
107108

108109
std::string _addr;
109-
bool _ignoreSslErrors = true;
110+
SslConfig _sslConfig;
110111
bool _printJobId = false;
111112

112113
Error _error;

utils/ippclient.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,11 @@ int main(int argc, char** argv)
159159
{
160160
bool help = false;
161161
bool verbose = false;
162+
bool verifySsl = false;
163+
std::string pinnedPublicKey;
162164
bool force = false;
163165
bool oneStage = false;
166+
164167
std::string pages;
165168
int copies;
166169
std::string collatedCopies;
@@ -199,6 +202,8 @@ int main(int argc, char** argv)
199202

200203
SwitchArg<bool> helpOpt(help, {"-h", "--help"}, "Print this help text");
201204
SwitchArg<bool> verboseOpt(verbose, {"-v", "--verbose"}, "Be verbose, print headers and progress");
205+
SwitchArg<bool> verifySslOpt(verifySsl, {"--verify-ssl"}, "Verify the printer's SSL cerificate");
206+
SwitchArg<std::string> pinnedPublicKeyOpt(pinnedPublicKey, {"--ssl-pubkey"}, "Require a certain SSL public key to match");
202207
SwitchArg<bool> forceOpt(force, {"-f", "--force"}, "Force use of unsupported options");
203208
SwitchArg<bool> oneStageOpt(oneStage, {"--one-stage"}, "Force use of one-stage print job");
204209

@@ -248,7 +253,7 @@ int main(int argc, char** argv)
248253
PosArg attrsArg(attrs, "name=value[,name=value]");
249254
PosArg pdfArg(inFile, "input file");
250255

251-
SubArgGet args({&helpOpt, &verboseOpt},
256+
SubArgGet args({&helpOpt, &verboseOpt, &verifySslOpt, &pinnedPublicKeyOpt},
252257
{{"info", {{},
253258
{&addrArg}}},
254259
{"identify", {{},
@@ -288,7 +293,19 @@ int main(int argc, char** argv)
288293
LogController::instance().enable(LogController::Debug);
289294
}
290295

291-
IppPrinter printer(addr);
296+
if(verifySslOpt.isSet() && !string_starts_with(addr, "ipps://"))
297+
{
298+
std::cerr << "--verify-ssl given, but address is not ipps." << std::endl;
299+
return 1;
300+
}
301+
302+
if(pinnedPublicKeyOpt.isSet() && !string_starts_with(addr, "ipps://"))
303+
{
304+
std::cerr << "--ssl-pubkey given, but address is not ipps." << std::endl;
305+
return 1;
306+
}
307+
308+
IppPrinter printer(addr, {verifySsl, pinnedPublicKey});
292309
Error error = printer.error();
293310
if(error)
294311
{

0 commit comments

Comments
 (0)