From 8a5f7fde1556ad11edd92d053f1d1f812d7b86c0 Mon Sep 17 00:00:00 2001
From: Eduardo Silva <eduardo@chronosphere.io>
Date: Wed, 15 Oct 2025 11:49:35 -0600
Subject: [PATCH 1/2] in_forward: fix username parsing

Fix parsing of username from the config value and ensure consistent error handling.

Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
---
 plugins/in_forward/fw.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/plugins/in_forward/fw.c b/plugins/in_forward/fw.c
index 73a3b73fb06..77da340d81e 100644
--- a/plugins/in_forward/fw.c
+++ b/plugins/in_forward/fw.c
@@ -216,7 +216,7 @@ static int setup_users(struct flb_in_fw_config *ctx,
 
         /* Get first value (user's name) */
         sentry = mk_list_entry_first(split, struct flb_split_entry, _head);
-        tmp = flb_sds_create_len(sentry->value, sentry->len + 1);
+        tmp = flb_sds_create_len(sentry->value, sentry->len);
         if (tmp == NULL) {
             delete_users(ctx);
             flb_free(user);
@@ -230,13 +230,14 @@ static int setup_users(struct flb_in_fw_config *ctx,
         tmp = flb_sds_create_len(sentry->value, sentry->len);
         if (tmp == NULL) {
             delete_users(ctx);
+            flb_sds_destroy(user->name);
             flb_free(user);
             flb_utils_split_free(split);
             return -1;
         }
         user->password = tmp;
 
-        /* Release split */
+        /* Release split - only after both allocations succeed */
         flb_utils_split_free(split);
 
         /* Link to parent list */

From 5f6c52ca5b13496f20020d238f539f7ed5aa44f3 Mon Sep 17 00:00:00 2001
From: Hiroshi Hatake <hiroshi@chronosphere.io>
Date: Thu, 16 Oct 2025 00:30:59 +0900
Subject: [PATCH 2/2] in_forward: Fix incorrect user auth

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
---
 plugins/in_forward/fw_prot.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/plugins/in_forward/fw_prot.c b/plugins/in_forward/fw_prot.c
index 4ae7636aa0d..f69bff5e65b 100644
--- a/plugins/in_forward/fw_prot.c
+++ b/plugins/in_forward/fw_prot.c
@@ -792,11 +792,10 @@ static int send_pong(struct flb_input_instance *in,
     if (bytes == -1) {
         flb_plg_error(in, "cannot send PONG");
 
-        result = -1;
-    }
-    else if (userauth == FLB_FALSE)  {
-        flb_plg_error(in, "cannot send PONG");
-
+        /*
+         * The 'userauth == FLB_FALSE' case is not an error; it's a successful
+         * transmission of a failure notification. We only fail if the write fails.
+         */
         result = -1;
     }
     else {
@@ -1203,29 +1202,30 @@ int fw_prot_secure_forward_handshake_start(struct flb_input_instance *ins,
 int fw_prot_secure_forward_handshake(struct flb_input_instance *ins,
                                      struct fw_conn *conn)
 {
-    int ret;
     char *shared_key_salt = NULL;
     int userauth = FLB_TRUE;
     flb_sds_t reason = NULL;
+    int ping_ret;
+    int pong_ret;
 
     reason = flb_sds_create_size(32);
     flb_plg_debug(ins, "protocol: checking PING");
-    ret = check_ping(ins, conn, &shared_key_salt);
-    if (ret == -1) {
+    ping_ret = check_ping(ins, conn, &shared_key_salt);
+    if (ping_ret == -1) {
         flb_plg_error(ins, "handshake error checking PING");
 
         goto error;
     }
-    else if (ret == -2) {
+    else if (ping_ret == -2) {
         flb_plg_warn(ins, "user authentication is failed");
         userauth = FLB_FALSE;
         reason = flb_sds_cat(reason, "username/password mismatch", 26);
     }
 
     flb_plg_debug(ins, "protocol: sending PONG");
-    ret = send_pong(ins, conn, shared_key_salt, userauth, reason);
-    if (ret == -1) {
-        flb_plg_error(ins, "handshake error sending PONG");
+    pong_ret = send_pong(ins, conn, shared_key_salt, userauth, reason);
+    if (pong_ret == -1) {
+        flb_plg_error(ins, "handshake error: could not send PONG to client");
 
         goto error;
     }
@@ -1233,6 +1233,15 @@ int fw_prot_secure_forward_handshake(struct flb_input_instance *ins,
     flb_sds_destroy(shared_key_salt);
     flb_sds_destroy(reason);
 
+    /*
+     * If the initial authentication check failed (either shared_key or user),
+     * we have successfully notified the client with a PONG failure message,
+     * so we must now terminate the handshake by returning an error.
+     */
+    if (ping_ret < 0) {
+        return -1;
+    }
+
     return 0;
 
 error:
