From 8269e2c961456a66b97a245eef4a10cdc7b11425 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 8 Apr 2025 12:27:23 -1000 Subject: [PATCH] Ensure plaintext responds with bad indicator byte before dropping the connection (#8521) --- esphome/components/api/api_frame_helper.cpp | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index 62f375508c..9e1b1521dd 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -893,8 +893,28 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) { ParsedFrame frame; aerr = try_read_frame_(&frame); - if (aerr != APIError::OK) + if (aerr != APIError::OK) { + if (aerr == APIError::BAD_INDICATOR) { + // Make sure to tell the remote that we don't + // understand the indicator byte so it knows + // we do not support it. + struct iovec iov[1]; + // The \x00 first byte is the marker for plaintext. + // + // The remote will know how to handle the indicator byte, + // but it likely won't understand the rest of the message. + // + // We must send at least 3 bytes to be read, so we add + // a message after the indicator byte to ensures its long + // enough and can aid in debugging. + const char msg[] = "\x00" + "Bad indicator byte"; + iov[0].iov_base = (void *) msg; + iov[0].iov_len = 19; + write_raw_(iov, 1); + } return aerr; + } buffer->container = std::move(frame.msg); buffer->data_offset = 0;