Skip to content

Commit d5bb987

Browse files
authored
Merge 4254b3a into 1211c56
2 parents 1211c56 + 4254b3a commit d5bb987

10 files changed

Lines changed: 242 additions & 91 deletions

File tree

NEWS.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ https://github.com/networkupstools/nut/milestone/12
327327

328328
- `upsd` data server updates:
329329
* Sometimes "Data for UPS [X] is stale" and "UPS [X] data is no longer
330-
stale" messages were logged in the same second, especially no busy
330+
stale" messages were logged in the same second, especially on busy
331331
systems. Now we allow one more second on top of `MAXAGE` setting to
332332
declare the device dead, just in case fractional/whole second rounding
333333
comes into play and breaks things. [issue #661]
@@ -502,6 +502,8 @@ several `FSD` notifications into one executed action. [PR #3097]
502502
* Added an option to (primarily) `--disable-threading` for systems with
503503
detected but broken `libpthread` support, or to test alternate code
504504
paths during development or in CI. [#3300]
505+
* Adjusted C++ header search path on Termux when `-isystem` is involved,
506+
as noted with NSS builds. [issues #1599, #1711, PR #3353]
505507

506508
- Recipes, CI and helper script updates not classified above:
507509
* Fixed CI recipes for PyPI publication of PyNUT(Client) module to also

clients/Makefile.am

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ CLEANFILES =
1616
# optionally includes "common.h" with the NUT build setup - and this option
1717
# was never triggered in fact, not until pushed through command line like this:
1818
AM_CXXFLAGS = -DHAVE_NUTCOMMON=1 -I$(top_builddir)/include -I$(top_srcdir)/include
19-
if WITH_SSL
20-
AM_CXXFLAGS += $(LIBSSL_CFLAGS)
21-
endif WITH_SSL
19+
if WITH_SSL_CXX
20+
AM_CXXFLAGS += $(LIBSSL_CXXFLAGS)
21+
endif WITH_SSL_CXX
2222

2323
# Make sure out-of-dir dependencies exist (especially when dev-building parts):
2424
$(top_builddir)/include/nut_version.h \
@@ -309,9 +309,9 @@ if HAVE_WINDOWS
309309
# Many versions of MingW seem to fail to build non-static DLL without this
310310
libnutclient_la_LDFLAGS += -no-undefined
311311
endif HAVE_WINDOWS
312-
if WITH_SSL
312+
if WITH_SSL_CXX
313313
libnutclient_la_LIBADD += $(LIBSSL_LDFLAGS_RPATH) $(LIBSSL_LIBS)
314-
endif WITH_SSL
314+
endif WITH_SSL_CXX
315315
else !HAVE_CXX11
316316
EXTRA_DIST += nutclient.h nutclient.cpp
317317
endif !HAVE_CXX11

clients/nutclient.cpp

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@
4747
#include <string.h>
4848
#include <stdio.h>
4949

50-
#ifdef WITH_NSS
51-
# include <prerror.h>
52-
# include <prinit.h>
53-
# include <pk11func.h>
54-
# include <prtypes.h>
55-
# include <ssl.h>
56-
# include <private/pprio.h>
57-
#endif /* WITH_NSS */
50+
#ifdef WITH_SSL_CXX
51+
# ifdef WITH_NSS
52+
# include <prerror.h>
53+
# include <prinit.h>
54+
# include <pk11func.h>
55+
# include <prtypes.h>
56+
# include <ssl.h>
57+
# include <private/pprio.h>
58+
# endif /* WITH_NSS */
59+
#endif /* WITH_SSL_CXX */
5860

5961
/* Windows/Linux Socket compatibility layer: */
6062
/* Thanks to Benjamin Roux (http://broux.developpez.com/articles/c/sockets/) */
@@ -258,11 +260,13 @@ class Socket
258260

259261
private:
260262
SOCKET _sock;
261-
#ifdef WITH_OPENSSL
263+
#ifdef WITH_SSL_CXX
264+
# ifdef WITH_OPENSSL
262265
SSL* _ssl;
263266
static SSL_CTX* _ssl_ctx;
264-
#elif defined(WITH_NSS)
267+
# elif defined(WITH_NSS)
265268
PRFileDesc* _ssl;
269+
# endif
266270
#endif
267271
bool _debugConnect;
268272
struct timeval _tv;
@@ -271,7 +275,8 @@ class Socket
271275
uint16_t _port;
272276
int _ssl_configured;
273277
int _force_ssl; /* Always known, so even non-SSL builds can fail if security is required */
274-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
278+
#ifdef WITH_SSL_CXX
279+
# if defined(WITH_OPENSSL) || defined(WITH_NSS)
275280
int _certverify;
276281
/* OpenSSL specific */
277282
std::string _ca_path;
@@ -284,14 +289,14 @@ class Socket
284289
std::string _certstore_prefix;
285290
std::string _certident_name;
286291
std::string _certhost_name;
287-
#endif
292+
# endif
288293

289-
#if defined(WITH_OPENSSL)
294+
# if defined(WITH_OPENSSL)
290295
/* Callbacks, syntax dictated by OpenSSL */
291296
static int openssl_password_callback(char *buf, int size, int rwflag, void *userdata); /* pem_passwd_cb, 1.1.0+ */
292-
#endif
297+
# endif
293298

294-
#if defined(WITH_NSS)
299+
# if defined(WITH_NSS)
295300
/* Callbacks, syntax dictated by NSS */
296301
static char *nss_password_callback(PK11SlotInfo *slot, PRBool retry, void *arg);
297302
static SECStatus AuthCertificate(CERTCertDBHandle *arg, PRFileDesc *fd,
@@ -303,10 +308,12 @@ class Socket
303308
CERTDistNames *caNames, CERTCertificate **pRetCert,
304309
SECKEYPrivateKey **pRetKey);
305310
static void HandshakeCallback(PRFileDesc *fd, void *arg);
306-
#endif
311+
# endif
312+
#endif /* WITH_SSL_CXX */
307313
};
308314

309-
#ifdef WITH_OPENSSL
315+
#ifdef WITH_SSL_CXX
316+
# ifdef WITH_OPENSSL
310317
SSL_CTX* Socket::_ssl_ctx = nullptr;
311318

312319
/*static*/ int Socket::openssl_password_callback(char *buf, int size, int rwflag, void *userdata) /* pem_passwd_cb, 1.1.0+ */
@@ -322,9 +329,9 @@ SSL_CTX* Socket::_ssl_ctx = nullptr;
322329
buf[size - 1] = '\0';
323330
return static_cast<int>(strlen(buf));
324331
}
325-
#endif
332+
# endif /* WITH_OPENSSL */
326333

327-
#ifdef WITH_NSS
334+
# ifdef WITH_NSS
328335
static void nss_error(const char* funcname)
329336
{
330337
char buffer[256];
@@ -423,20 +430,25 @@ static void nss_error(const char* funcname)
423430
std::cerr << "SSL handshake done successfully with server " << sock->_host << std::endl;
424431
}
425432
}
426-
#endif /* WITH_NSS */
433+
# endif /* WITH_NSS */
434+
#endif /* WITH_SSL_CXX */
427435

428436
Socket::Socket():
429437
_sock(INVALID_SOCKET),
430-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
438+
#ifdef WITH_SSL_CXX
439+
# if defined(WITH_OPENSSL) || defined(WITH_NSS)
431440
_ssl(nullptr),
441+
# endif
432442
#endif
433443
_debugConnect(false),
434444
_tv(),
435445
_port(NUT_PORT),
436446
_force_ssl(0)
437-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
447+
#ifdef WITH_SSL_CXX
448+
# if defined(WITH_OPENSSL) || defined(WITH_NSS)
438449
,_certverify(-1)
439-
#endif
450+
# endif
451+
#endif /* WITH_SSL_CXX */
440452
{
441453
_tv.tv_sec = -1;
442454
_tv.tv_usec = 0;
@@ -761,17 +773,20 @@ void Socket::connect(const std::string& host, uint16_t port)
761773

762774
void Socket::disconnect()
763775
{
764-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
776+
#ifdef WITH_SSL_CXX
777+
# if defined(WITH_OPENSSL) || defined(WITH_NSS)
765778
if (_ssl) {
766-
# ifdef WITH_OPENSSL
779+
# ifdef WITH_OPENSSL
767780
SSL_shutdown(_ssl);
768781
SSL_free(_ssl);
769-
# elif defined(WITH_NSS)
782+
# elif defined(WITH_NSS)
770783
PR_Close(_ssl);
771-
# endif
784+
# endif
772785
_ssl = nullptr;
773786
}
774-
#endif
787+
# endif
788+
#endif /* WITH_SSL_CXX */
789+
775790
if(_sock != INVALID_SOCKET)
776791
{
777792
::closesocket(_sock);
@@ -782,7 +797,7 @@ void Socket::disconnect()
782797

783798
bool Socket::isSSL()const
784799
{
785-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
800+
#if defined (WITH_SSL_CXX) && (defined(WITH_OPENSSL) || defined(WITH_NSS))
786801
return _ssl != nullptr;
787802
#else
788803
return false;
@@ -793,7 +808,7 @@ void Socket::setSSLConfig_OpenSSL(bool force_ssl, int certverify, const std::str
793808
{
794809
_force_ssl = force_ssl;
795810

796-
#if defined(WITH_OPENSSL)
811+
#if defined(WITH_SSL_CXX) && defined(WITH_OPENSSL)
797812
_certverify = certverify;
798813
/* These need to be saved at least to handle callbacks
799814
* (to see if errors are fatal or ignorable)
@@ -821,7 +836,7 @@ void Socket::setSSLConfig_NSS(bool force_ssl, int certverify, const std::string&
821836
{
822837
_force_ssl = force_ssl;
823838

824-
#if defined(WITH_NSS)
839+
#if defined(WITH_SSL_CXX) && defined(WITH_NSS)
825840
_certverify = certverify;
826841
/* These need to be saved at least to handle NSS callbacks
827842
* (to see if errors are fatal or ignorable)
@@ -851,7 +866,8 @@ void Socket::startTLS()
851866
throw nut::NotConnectedException();
852867
}
853868

854-
#ifdef WITH_OPENSSL
869+
#ifdef WITH_SSL_CXX
870+
# ifdef WITH_OPENSSL
855871
if (!(_ssl_configured & UPSCLI_SSL_CAPS_OPENSSL)) {
856872
if (_debugConnect) std::cerr <<
857873
"[D2] Socket::startTLS(): Not configured for OpenSSL" <<
@@ -863,7 +879,7 @@ void Socket::startTLS()
863879
}
864880
return;
865881
}
866-
#elif defined(WITH_NSS)
882+
# elif defined(WITH_NSS)
867883
if (!(_ssl_configured & UPSCLI_SSL_CAPS_NSS)) {
868884
if (_debugConnect) std::cerr <<
869885
"[D2] Socket::startTLS(): Not configured for NSS" <<
@@ -875,9 +891,9 @@ void Socket::startTLS()
875891
}
876892
return;
877893
}
878-
#endif /* WITH_OPENSSL || WITH_NSS */
894+
# endif /* WITH_OPENSSL || WITH_NSS */
879895

880-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
896+
# if defined(WITH_OPENSSL) || defined(WITH_NSS)
881897
write("STARTTLS");
882898
std::string res = read();
883899
if (res.substr(0, 11) != "OK STARTTLS") {
@@ -887,17 +903,17 @@ void Socket::startTLS()
887903
}
888904
return;
889905
}
890-
#endif /* WITH_OPENSSL || WITH_NSS */
906+
# endif /* WITH_OPENSSL || WITH_NSS */
891907

892-
#ifdef WITH_OPENSSL
908+
# ifdef WITH_OPENSSL
893909
if (!_ssl_ctx) {
894-
# if OPENSSL_VERSION_NUMBER < 0x10100000L
910+
# if OPENSSL_VERSION_NUMBER < 0x10100000L
895911
SSL_load_error_strings();
896912
SSL_library_init();
897913
_ssl_ctx = SSL_CTX_new(SSLv23_client_method());
898-
# else
914+
# else
899915
_ssl_ctx = SSL_CTX_new(TLS_client_method());
900-
# endif
916+
# endif
901917
if (!_ssl_ctx) {
902918
throw nut::SSLException_OpenSSL("Cannot create SSL context");
903919
}
@@ -916,17 +932,17 @@ void Socket::startTLS()
916932
throw nut::SSLException_OpenSSL("Failed to load client certificate file");
917933
}
918934
if (!_key_pass.empty()) {
919-
# if OPENSSL_VERSION_NUMBER < 0x10100000L
935+
# if OPENSSL_VERSION_NUMBER < 0x10100000L
920936
throw nut::SSLException_OpenSSL("Private key password support not implemented for OpenSSL < 1.1 yet");
921-
# else
937+
# else
922938
/* OpenSSL 1.1.0+
923939
* https://docs.openssl.org/3.5/man3/SSL_CTX_set_default_passwd_cb/#return-values
924940
*/
925941
/* 1. Set the callback function */
926942
SSL_CTX_set_default_passwd_cb(_ssl_ctx, openssl_password_callback);
927943
/* 2. Set the userdata to the password string */
928944
SSL_CTX_set_default_passwd_cb_userdata(_ssl_ctx, const_cast<void *>(static_cast<const void *>(_key_pass.c_str())));
929-
# endif
945+
# endif
930946
}
931947
if (SSL_CTX_use_PrivateKey_file(_ssl_ctx, _key_file.empty() ? _cert_file.c_str() : _key_file.c_str(), SSL_FILETYPE_PEM) != 1) {
932948
throw nut::SSLException_OpenSSL("Failed to load client private key file");
@@ -948,7 +964,7 @@ void Socket::startTLS()
948964
throw nut::SSLException_OpenSSL(std::string("SSL connection failed: ") + errbuf);
949965
}
950966

951-
#elif defined(WITH_NSS)
967+
# elif defined(WITH_NSS)
952968
/* NSS implementation following upsclient.c logic */
953969
static bool nss_initialized = false;
954970

@@ -1025,6 +1041,7 @@ void Socket::startTLS()
10251041
disconnect();
10261042
throw nut::SSLException_NSS("Handshake failed");
10271043
}
1044+
# endif /* WITH_NSS */
10281045
#else
10291046
if (_debugConnect) std::cerr <<
10301047
"[D2] Socket::startTLS(): SSL support not compiled in" <<
@@ -1034,7 +1051,7 @@ void Socket::startTLS()
10341051
disconnect();
10351052
throw nut::SSLException("SSL support not compiled in");
10361053
}
1037-
#endif
1054+
#endif /* WITH_SSL_CXX */
10381055
}
10391056

10401057
bool Socket::isConnected()const
@@ -1061,7 +1078,7 @@ size_t Socket::read(void* buf, size_t sz)
10611078
}
10621079

10631080
ssize_t res;
1064-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
1081+
#if defined(WITH_SSL_CXX) && (defined(WITH_OPENSSL) || defined(WITH_NSS))
10651082
if (_ssl) {
10661083
# ifdef WITH_OPENSSL
10671084
res = SSL_read(_ssl, buf, static_cast<int>(sz));
@@ -1102,7 +1119,7 @@ size_t Socket::write(const void* buf, size_t sz)
11021119
}
11031120

11041121
ssize_t res;
1105-
#if defined(WITH_OPENSSL) || defined(WITH_NSS)
1122+
#if defined(WITH_SSL_CXX) && (defined(WITH_OPENSSL) || defined(WITH_NSS))
11061123
if (_ssl) {
11071124
# ifdef WITH_OPENSSL
11081125
res = SSL_write(_ssl, buf, static_cast<int>(sz));
@@ -1320,14 +1337,14 @@ TcpClient::~TcpClient()
13201337
{
13211338
int ret = UPSCLI_SSL_CAPS_NONE;
13221339

1323-
#ifdef WITH_SSL
1340+
#ifdef WITH_SSL_CXX
13241341
# ifdef WITH_OPENSSL
13251342
ret |= UPSCLI_SSL_CAPS_OPENSSL;
13261343
# endif
13271344
# ifdef WITH_NSS
13281345
ret |= UPSCLI_SSL_CAPS_NSS;
13291346
# endif
1330-
#endif /* WITH_SSL */
1347+
#endif /* WITH_SSL_CXX */
13311348

13321349
return ret;
13331350
}

clients/nutclient.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@
2929
/* Begin of C++ nutclient library declaration */
3030
#ifdef __cplusplus
3131

32-
#ifdef WITH_OPENSSL
32+
#ifdef WITH_SSL_CXX
33+
# ifdef WITH_OPENSSL
3334
# include <openssl/err.h>
3435
# include <openssl/ssl.h>
35-
#elif defined(WITH_NSS) /* not WITH_OPENSSL */
36+
# elif defined(WITH_NSS) /* not WITH_OPENSSL */
3637
# include <nss.h>
3738
# include <ssl.h>
38-
#endif /* WITH_OPENSSL | WITH_NSS */
39+
# endif /* WITH_OPENSSL | WITH_NSS */
40+
#endif /* WITH_SSL_CXX */
3941

4042
#include <string>
4143
#include <vector>

conf/ups.conf.sample

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ maxretry = 3
131131
# user, group: OPTIONAL. Overrides the compiled-in (also global-section,
132132
# when used in driver section) default unprivileged user/group
133133
# name for NUT device driver. Impacts access rights used for
134-
# the socket file access (group) and communication ports (user).
134+
# the socket file access (group) and communication ports (user
135+
# and its default group; you may want to add that user in the
136+
# operating system to `dialout` group to access serial ports).
135137
#
136138
# synchronous: OPTIONAL. The driver work by default in asynchronous
137139
# mode (like *no*) with fallback to synchronous if sending

0 commit comments

Comments
 (0)