Skip to content

libupsclient: Support multiple SSL contexts - #3607

Open
jimklimov wants to merge 26 commits into
networkupstools:masterfrom
jimklimov:issue-3439
Open

libupsclient: Support multiple SSL contexts#3607
jimklimov wants to merge 26 commits into
networkupstools:masterfrom
jimklimov:issue-3439

Conversation

@jimklimov

@jimklimov jimklimov commented Sep 1, 2026

Copy link
Copy Markdown
Member

Until now, the NUT C and C++ client libraries supported a global singleton for OpenSSL context, while the library itself allows many contexts (they track trusted CA, helper callback methods, security requirements, etc.) and individual ssl connections are based on this or that context. For comparison, PERL and Python bindings use multiple-context SSL right away.

Mozilla NSS backend does not have this feature, its one process-wide context is based on an NSS DB loaded once, but individual connections can be handled via callbacks to e.g. present different client certificates, and the multitude of servers and their CAs can be preloaded into the NSS DB.

This PR allows NUT clients which make multiple connections (upsmon, upslog, upsstats.cgi, eventually the out-of-tree wmnut) to try using a suitable one of many contexts if the loaded AUTHCONF settings would dictate that setup.

Closes: #3439

Work augmented by CoPilot AI (kudos to GitHub for sponsoring it to FOSS maintainers; even so it took two months' credit allowances to complete the quest).

…ext [networkupstools#3439]

...as an alternative to the global SSL context, which is not suitable
for multiple connections with different SSL parameters (certificates,
trusted CA realms, etc.) in the same process.

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ed" flag properties of the Socket class instance, not static globals assigned once per process [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…() (currently via upscli_set_ssl_context() not C++) [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…rs for SSLContext [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…() to use pure C++ implementation [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…tion in our and ecosystem code [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ontext approach [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ith its password [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ored for the connection (if any) over global default (first known pass) [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
… desired cert with its password [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…NN_t` [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…implementation [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…) methods [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…factor with secure memory zeroing [networkupstools#3439]

- Implement process-wide SSL context registry for caching and reuse
- Registry stores config parameters (certverify, certpath, certname, certpasswd, certfile)
- Per-connection references use opaque handles to registry entries (not owned)
- NSS per-connection client cert identity now works correctly via registry
- Remove sql_ctx_owned field (registry handles lifecycle)
- Remove per-connection certident_name/certident_pass (moved to registry)
- Implement secure zeroing of sensitive fields (passwords, cert names/paths)
- Registry automatically freed in upscli_cleanup()
- upscli_sslinit() now uses registry context instead of global ssl_ctx
- Full backward compatibility with legacy upscli_init*() APIs via default context
- Supports simultaneous multi-realm connections with different CAs and client certs

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
Co-authored-by: GitHub CoPilot
…n public header for clarity [networkupstools#3439]

- Add forward declaration of upscli_ssl_context_config_t (struct upscli_ssl_context_config_s)
- Change UPSCONN_t::ssl_ctx from void* to typed upscli_ssl_context_config_t* on all platforms
- Clarify in comments that ssl_ctx is used for both NSS and OpenSSL (per-connection client cert identity)
- Keep extra_reserved padding in non-OpenSSL builds for struct size compatibility
- This makes the public API clearer without exposing internals: users know ssl_ctx is a registry handle

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…server clients to use per-connection SSL contexts [networkupstools#3439]

upsmon.c, upslog.c, upsstats.c:
- Before connecting to each server, fetch per-server authconf with
  upscli_get_authconf_item() and create SSL context with
  upscli_get_or_create_ssl_context_authconf()
- Attach context to connection via upscli_set_ssl_context() before connect
- This allows simultaneous connections to different servers with different
  client certificates/CAs, resolving the limitation in issue networkupstools#3494
- Update FIXME comments to NOTE as the limitation is now resolved

Benefits:
- upsmon can monitor UPS devices behind different CAs/client certs simultaneously
- upslog can log multiple systems with independent SSL configurations
- upsstats can query multiple data servers with per-server SSL setup
- All within a single process, no shared global SSL context constraint

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…s#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
@jimklimov jimklimov added this to the 2.8.6 milestone Sep 1, 2026
@jimklimov jimklimov added enhancement documentation SSL/NSS Issues and PRs about SSL, TLS and other crypto-related matters upsmon AI For good or bad, machine tools are upon us. Humans are still the responsible ones. labels Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Preparing a ZIP file with standard source tarball and another tarball with pre-built docs for commit e2ef507 ...

Comment thread clients/upsmon.c
* And do not reload any new data for nutauth.conf (default or
* AUTHCONF-provided) file contents...
*/
/*upscli_cleanup();*/
Comment thread clients/upsmon.c
}

if (reload_flag == 0) {
/* FIXME: See also comment above, to support reloading AUTHCONF */
Comment thread tests/nutclienttest.cpp
/* Test the C++ API for per-connection SSL context management */
nut::TcpClient client;

//std::cerr << "Starting test_ssl_context_registry" << std::endl;
Comment thread tests/nutclienttest.cpp
void *initial = client.getSSLContext();
CPPUNIT_ASSERT_MESSAGE("Expected no initial SSL context", initial == nullptr);

//std::cerr << "Setting custom SSL context" << std::endl;
Comment thread tests/nutclienttest.cpp
CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected the registered SSL context to be returned by getter",
test_ctx, client.getSSLContext());

//std::cerr << "Updating SSL context" << std::endl;
Comment thread tests/nutclienttest.cpp
* our test pointers above are not real SSL_CTX objects. */
client.setSSLContext(nullptr);

//std::cerr << "Finished test_ssl_context_registry" << std::endl;
…t support [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…init(): search for suitable ups->ssl_ctx if missing [networkupstools#3439]

An older hypothesis about pre-assigning ups->ssl_ctx was wrong
because upscli_tryconnect() wipes the ups contents as heap trash.

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
@AppVeyorBot

Copy link
Copy Markdown

@AppVeyorBot

Copy link
Copy Markdown

@AppVeyorBot

Copy link
Copy Markdown

@AppVeyorBot

Copy link
Copy Markdown

@AppVeyorBot

Copy link
Copy Markdown

@AppVeyorBot

Copy link
Copy Markdown

Comment thread clients/authconf.c Dismissed
…introduce AUTHCONF keyword [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…SL attempt [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
… without OpenSSL backend [networkupstools#3439]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…non-absolute paths as relative to confpath() [networkupstools#3439, networkupstools#3329]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ial values of AUTHCONF option like command-line clients do [networkupstools#3439, networkupstools#3329]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI For good or bad, machine tools are upon us. Humans are still the responsible ones. documentation enhancement SSL/NSS Issues and PRs about SSL, TLS and other crypto-related matters upsmon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NUT SSL clients can only use one identity and one trust store per process

3 participants