From 21b2cf0e7059606786551e248e6d5c6ff93d7f9d Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Thu, 12 Feb 2026 10:15:47 +0100 Subject: [PATCH 1/2] server_tls.c: fixed white space issues Signed-off-by: Lars Erik Wik --- cf-serverd/server_tls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cf-serverd/server_tls.c b/cf-serverd/server_tls.c index edc185237b..be4cb8f835 100644 --- a/cf-serverd/server_tls.c +++ b/cf-serverd/server_tls.c @@ -423,9 +423,9 @@ bool ServerSendWelcome(const ServerConnectionState *conn) "USERNAME", conn->username); if (ret < 0) { - Log(LOG_LEVEL_ERR, + Log(LOG_LEVEL_ERR, "Unexpected failure from snprintf (%d - %s) while " - "constructing OK WELCOME message (ServerSendWelcome)", + "constructing OK WELCOME message (ServerSendWelcome)", errno, GetErrorStr()); return false; } From 8b7c34edbe7ca06af6018a1465f02c239722432c Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Wed, 11 Feb 2026 17:15:44 +0100 Subject: [PATCH 2/2] Immediately collect report on bootstrap Made LastSaw1() return bool indicating new host and notify enterprise on first auth. Ticket: ENT-13699 Signed-off-by: Lars Erik Wik --- cf-serverd/cf-serverd-enterprise-stubs.c | 5 +++++ cf-serverd/cf-serverd-enterprise-stubs.h | 2 ++ cf-serverd/server_tls.c | 11 +++++++++-- libpromises/lastseen.c | 20 +++++++++++--------- libpromises/lastseen.h | 9 +++++++-- tests/load/lastseen_load.c | 2 +- tests/load/lastseen_threaded_load.c | 2 +- tests/unit/lastseen_test.c | 2 +- 8 files changed, 37 insertions(+), 16 deletions(-) diff --git a/cf-serverd/cf-serverd-enterprise-stubs.c b/cf-serverd/cf-serverd-enterprise-stubs.c index e45ca0b4a5..a9698eefdc 100644 --- a/cf-serverd/cf-serverd-enterprise-stubs.c +++ b/cf-serverd/cf-serverd-enterprise-stubs.c @@ -106,6 +106,11 @@ ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(void, CollectCallMarkProcessed) { } +ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, NotifyNewHostSeen, + ARG_UNUSED const char *, hostkey) +{ +} + ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, FprintAvahiCfengineTag, FILE *, fp) { fprintf(fp,"CFEngine Community %s Policy Server on %s \n", Version(), "%h"); diff --git a/cf-serverd/cf-serverd-enterprise-stubs.h b/cf-serverd/cf-serverd-enterprise-stubs.h index c3159b3aa7..a462ba5d17 100644 --- a/cf-serverd/cf-serverd-enterprise-stubs.h +++ b/cf-serverd/cf-serverd-enterprise-stubs.h @@ -50,6 +50,8 @@ ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, CleanReportBookFilterSet); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, FprintAvahiCfengineTag, FILE *, fp); +ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, NotifyNewHostSeen, const char *, hostkey); + ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, CollectCallStart, ARG_UNUSED int, interval); ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, CollectCallStop); ENTERPRISE_FUNC_0ARG_DECLARE(bool, CollectCallHasPending); diff --git a/cf-serverd/server_tls.c b/cf-serverd/server_tls.c index be4cb8f835..456da6c088 100644 --- a/cf-serverd/server_tls.c +++ b/cf-serverd/server_tls.c @@ -537,6 +537,8 @@ bool BasicServerTLSSessionEstablish(ServerConnectionState *conn, SSL_CTX *ssl_ct */ bool ServerTLSSessionEstablish(ServerConnectionState *conn, SSL_CTX *ssl_ctx) { + assert (conn != NULL); + if (conn->conn_info->status == CONNECTIONINFO_STATUS_ESTABLISHED) { return true; @@ -608,8 +610,13 @@ bool ServerTLSSessionEstablish(ServerConnectionState *conn, SSL_CTX *ssl_ctx) conn->user_data_set = true; conn->rsa_auth = true; - LastSaw1(conn->ipaddr, KeyPrintableHash(ConnectionInfoKey(conn->conn_info)), - LAST_SEEN_ROLE_ACCEPT); + const char *hostkey = KeyPrintableHash(ConnectionInfoKey(conn->conn_info)); + bool is_new_host = LastSaw1(conn->ipaddr, hostkey, LAST_SEEN_ROLE_ACCEPT); + if (is_new_host) + { + /* This will trigger immediate report collection */ + NotifyNewHostSeen(hostkey); + } ServerSendWelcome(conn); return true; diff --git a/libpromises/lastseen.c b/libpromises/lastseen.c index 34f848e6cd..18da29f791 100644 --- a/libpromises/lastseen.c +++ b/libpromises/lastseen.c @@ -34,7 +34,7 @@ #include #endif -void UpdateLastSawHost(const char *hostkey, const char *address, +bool UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); /* @@ -80,40 +80,40 @@ void UpdateLastSawHost(const char *hostkey, const char *address, * @brief Same as LastSaw() but the digest parameter is the hash as a * "SHA=..." string, to avoid converting twice. */ -void LastSaw1(const char *ipaddress, const char *hashstr, +bool LastSaw1(const char *ipaddress, const char *hashstr, LastSeenRole role) { const char *mapip = MapAddress(ipaddress); - UpdateLastSawHost(hashstr, mapip, role == LAST_SEEN_ROLE_ACCEPT, time(NULL)); + return UpdateLastSawHost(hashstr, mapip, role == LAST_SEEN_ROLE_ACCEPT, time(NULL)); } -void LastSaw(const char *ipaddress, const unsigned char *digest, LastSeenRole role) +bool LastSaw(const char *ipaddress, const unsigned char *digest, LastSeenRole role) { char databuf[CF_HOSTKEY_STRING_SIZE]; if (strlen(ipaddress) == 0) { Log(LOG_LEVEL_INFO, "LastSeen registry for empty IP with role %d", role); - return; + return false; } HashPrintSafe(databuf, sizeof(databuf), digest, CF_DEFAULT_DIGEST, true); const char *mapip = MapAddress(ipaddress); - UpdateLastSawHost(databuf, mapip, role == LAST_SEEN_ROLE_ACCEPT, time(NULL)); + return UpdateLastSawHost(databuf, mapip, role == LAST_SEEN_ROLE_ACCEPT, time(NULL)); } /*****************************************************************************/ -void UpdateLastSawHost(const char *hostkey, const char *address, +bool UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp) { DBHandle *db = NULL; if (!OpenDB(&db, dbid_lastseen)) { Log(LOG_LEVEL_ERR, "Unable to open last seen db"); - return; + return false; } /* Update quality-of-connection entry */ @@ -127,7 +127,8 @@ void UpdateLastSawHost(const char *hostkey, const char *address, }; KeyHostSeen q; - if (ReadDB(db, quality_key, &q, sizeof(q))) + bool host_existed = ReadDB(db, quality_key, &q, sizeof(q)); + if (host_existed) { newq.Q = QAverage(q.Q, newq.lastseen - q.lastseen, 0.4); } @@ -153,6 +154,7 @@ void UpdateLastSawHost(const char *hostkey, const char *address, WriteDB(db, address_key, hostkey, strlen(hostkey) + 1); CloseDB(db); + return !host_existed; } /*****************************************************************************/ diff --git a/libpromises/lastseen.h b/libpromises/lastseen.h index 786c2cb5ed..68484a3559 100644 --- a/libpromises/lastseen.h +++ b/libpromises/lastseen.h @@ -44,8 +44,13 @@ typedef enum bool Address2Hostkey(char *dst, size_t dst_size, const char *address); char *HostkeyToAddress(const char *hostkey); -void LastSaw1(const char *ipaddress, const char *hashstr, LastSeenRole role); -void LastSaw(const char *ipaddress, const unsigned char *digest, LastSeenRole role); +/** + * @brief Record a host connection in the lastseen database. + * @return true if this is the first time the host has been seen (new host), + * false if the host was already known. + */ +bool LastSaw1(const char *ipaddress, const char *hashstr, LastSeenRole role); +bool LastSaw(const char *ipaddress, const unsigned char *digest, LastSeenRole role); bool DeleteIpFromLastSeen(const char *ip, char *digest, size_t digest_size); bool DeleteDigestFromLastSeen(const char *key, char *ip, size_t ip_size, bool a_entry_required); diff --git a/tests/load/lastseen_load.c b/tests/load/lastseen_load.c index 9d76edabd9..7738c21a58 100644 --- a/tests/load/lastseen_load.c +++ b/tests/load/lastseen_load.c @@ -21,7 +21,7 @@ static void tests_setup(void) mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); } -void UpdateLastSawHost(const char *hostkey, const char *address, +bool UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); int main() diff --git a/tests/load/lastseen_threaded_load.c b/tests/load/lastseen_threaded_load.c index 631c66c8bb..cf92a32276 100644 --- a/tests/load/lastseen_threaded_load.c +++ b/tests/load/lastseen_threaded_load.c @@ -35,7 +35,7 @@ pthread_mutex_t end_mtx = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; pthread_cond_t end_cond = PTHREAD_COND_INITIALIZER; -void UpdateLastSawHost(const char *hostkey, const char *address, +bool UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); diff --git a/tests/unit/lastseen_test.c b/tests/unit/lastseen_test.c index 4f710bd073..833a46c7ad 100644 --- a/tests/unit/lastseen_test.c +++ b/tests/unit/lastseen_test.c @@ -10,7 +10,7 @@ char CFWORKDIR[CF_BUFSIZE]; -void UpdateLastSawHost(const char *hostkey, const char *address, +bool UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); /* For abbreviation of tests. */