From ab97fc32990b1452017d8721639f1d9fa90ab2a4 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 19 Feb 2022 12:55:38 +0100 Subject: [PATCH] add --capath and --cafile including insecure option --- src/ebusd/main.cpp | 22 ++++++++++++++++++---- src/ebusd/main.h | 2 ++ src/ebusd/mainloop.cpp | 2 +- src/lib/utils/httpclient.cpp | 4 +--- src/lib/utils/httpclient.h | 4 ++-- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/ebusd/main.cpp b/src/ebusd/main.cpp index d270edef..7b02706f 100644 --- a/src/ebusd/main.cpp +++ b/src/ebusd/main.cpp @@ -91,6 +91,8 @@ static struct options s_opt = { 5, // pollInterval false, // injectMessages false, // stopAfterInject + nullptr, // caFile + nullptr, // caPath 0x31, // address false, // answer @@ -135,10 +137,10 @@ static MessageMap* s_messageMap = nullptr; static MainLoop* s_mainLoop = nullptr; /** the path prefix (including trailing "/") for retrieving configuration files from local files (empty for HTTPS). */ -static string s_configLocalPrefix; +static string s_configLocalPrefix = ""; /** the URI prefix (including trailing "/") for retrieving configuration files from HTTPS (empty for local files). */ -static string s_configUriPrefix; +static string s_configUriPrefix = ""; /** the @a HttpClient for retrieving configuration files from HTTPS. */ static HttpClient* s_configHttpClient = nullptr; @@ -153,7 +155,9 @@ static const char argpdoc[] = #define O_CHKCFG (O_CFGLNG+1) #define O_DMPCFG (O_CHKCFG+1) #define O_POLINT (O_DMPCFG+1) -#define O_ANSWER (O_POLINT+1) +#define O_CAFILE (O_POLINT+1) +#define O_CAPATH (O_CAFILE+1) +#define O_ANSWER (O_CAPATH+1) #define O_ACQTIM (O_ANSWER+1) #define O_ACQRET (O_ACQTIM+1) #define O_SNDRET (O_ACQRET+1) @@ -205,6 +209,10 @@ static const struct argp_option argpoptions[] = { {"pollinterval", O_POLINT, "SEC", 0, "Poll for data every SEC seconds (0=disable) [5]", 0 }, {"inject", 'i', "stop", OPTION_ARG_OPTIONAL, "Inject remaining arguments as already seen messages (e.g. " "\"FF08070400/0AB5454850303003277201\"), optionally stop afterwards", 0 }, +#ifdef HAVE_SSL + {"cafile", O_CAFILE, "FILE", 0, "Use CA FILE for checking certificates (uses defaults, \"#\" for insecure)", 0 }, + {"capath", O_CAPATH, "PATH", 0, "Use CA PATH for checking certificates (uses defaults)", 0 }, +#endif // HAVE_SSL {nullptr, 0, nullptr, 0, "eBUS options:", 3 }, {"address", 'a', "ADDR", 0, "Use ADDR as own bus address [31]", 0 }, @@ -388,6 +396,12 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) { opt->injectMessages = true; opt->stopAfterInject = arg && strcmp("stop", arg) == 0; break; + case O_CAFILE: // --cafile=FILE + opt->caFile = arg; + break; + case O_CAPATH: // --capath=PATH + opt->caPath = arg; + break; // eBUS options: case 'a': // --address=31 @@ -779,7 +793,7 @@ void signalHandler(int sig) { */ bool lazyHttpClient() { if (!s_configHttpClient) { - s_configHttpClient = new HttpClient(); + s_configHttpClient = new HttpClient(s_opt.caFile, s_opt.caPath); } return true; } diff --git a/src/ebusd/main.h b/src/ebusd/main.h index 756c4437..04d5c33b 100644 --- a/src/ebusd/main.h +++ b/src/ebusd/main.h @@ -52,6 +52,8 @@ struct options { unsigned int pollInterval; //!< poll interval in seconds, 0 to disable [5] bool injectMessages; //!< inject remaining arguments as already seen messages bool stopAfterInject; //!< only inject messages once, then stop + const char* caFile; //!< the CA file to use (uses defaults if neither caFile nor caPath are set), or "#" for insecure + const char* caPath; //!< the path with CA files to use (uses defaults if neither caFile nor caPath are set) symbol_t address; //!< own bus address [31] bool answer; //!< answer to requests from other masters diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index 3aa9474a..a0f67d1e 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -108,7 +108,7 @@ MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messag : Thread(), m_device(device), m_reconnectCount(0), m_userList(opt.accessLevel), m_messages(messages), m_address(opt.address), m_scanConfig(opt.scanConfig), m_initialScan(opt.readOnly ? ESC : opt.initialScan), m_polling(opt.pollInterval > 0), m_enableHex(opt.enableHex), m_shutdown(false), m_runUpdateCheck(opt.updateCheck), - m_httpClient(nullptr, nullptr) { + m_httpClient(opt.caFile, opt.caPath) { m_device->setListener(this); // open Device result_t result = m_device->open(); diff --git a/src/lib/utils/httpclient.cpp b/src/lib/utils/httpclient.cpp index 1b3ad236..0ced436c 100755 --- a/src/lib/utils/httpclient.cpp +++ b/src/lib/utils/httpclient.cpp @@ -142,9 +142,6 @@ bool SSLSocket::isValid() { return time(nullptr) < m_until && !BIO_eof(m_bio); } -// general switch for future insecure option -static const bool verifyPeer = true; - SSLSocket* SSLSocket::connect(const string& host, const uint16_t& port, bool https, int timeout, const char* caFile, const char* caPath) { BIO *bio = nullptr; @@ -173,6 +170,7 @@ SSLSocket* SSLSocket::connect(const string& host, const uint16_t& port, bool htt if (isError("ctx_new", ctx)) { break; } + bool verifyPeer = !caFile || strcmp(caFile, "#")!=0; SSL_CTX_set_verify(ctx, verifyPeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, nullptr); if (verifyPeer) { #if OPENSSL_VERSION_NUMBER >= 0x10101000L diff --git a/src/lib/utils/httpclient.h b/src/lib/utils/httpclient.h index f844f795..3c26a463 100755 --- a/src/lib/utils/httpclient.h +++ b/src/lib/utils/httpclient.h @@ -67,7 +67,7 @@ class SSLSocket { * @param port the port number. * @param https true for HTTPS, false for HTTP. * @param timeout the connect, send, and receive timeout in seconds, or 0 for blocking mode. - * @param caFile the CA file to use (uses defaults if neither caFile nor caPath are set). + * @param caFile the CA file to use (uses defaults if neither caFile nor caPath are set), or "#" for insecure. * @param caPath the path with CA files to use (uses defaults if neither caFile nor caPath are set). * @return the connected SSLSocket, or nullptr on error. */ @@ -122,7 +122,7 @@ class HttpClient { public: /** * Constructor. - * @param caFile the CA file to use (uses defaults if neither caFile nor caPath are set). + * @param caFile the CA file to use (uses defaults if neither caFile nor caPath are set), or "#" for insecure. * @param caPath the path with CA files to use (uses defaults if neither caFile nor caPath are set). */ explicit HttpClient(const char* caFile = nullptr, const char* caPath = nullptr) :