From cb21eefec7a836927a2e313f83cda80c573f1b65 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 14 May 2014 20:55:29 +0200 Subject: [PATCH] frontend: Handle missing authentication early. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit … and limit the max amount of buffered data for unauthenticated connections in order reduce the impact of anonymous DoS attempts. --- src/frontend/connection.c | 19 ++++++++------- t/unit/frontend/connection_test.c | 40 +++++++++++++++++++------------ 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/frontend/connection.c b/src/frontend/connection.c index b913939..dba4310 100644 --- a/src/frontend/connection.c +++ b/src/frontend/connection.c @@ -265,14 +265,6 @@ command_handle(sdb_conn_t *conn) sdb_log(SDB_LOG_DEBUG, "frontend: Handling command %u (len: %u)", conn->cmd, conn->cmd_len); - if ((! conn->username) && (conn->cmd != CONNECTION_STARTUP)) { - const char *errmsg = "Authentication required"; - sdb_strbuf_sprintf(conn->errbuf, errmsg); - sdb_connection_send(conn, CONNECTION_ERROR, - (uint32_t)strlen(errmsg), errmsg); - return -1; - } - switch (conn->cmd) { case CONNECTION_PING: status = sdb_connection_ping(conn); @@ -379,7 +371,16 @@ command_init(sdb_conn_t *conn) conn->cmd = connection_get_int32(conn, 0); conn->cmd_len = connection_get_int32(conn, sizeof(uint32_t)); - if (conn->cmd == CONNECTION_IDLE) { + if ((! conn->username) && (conn->cmd != CONNECTION_STARTUP)) { + const char *errmsg = "Authentication required"; + sdb_strbuf_sprintf(conn->errbuf, errmsg); + sdb_connection_send(conn, CONNECTION_ERROR, + (uint32_t)strlen(errmsg), errmsg); + conn->skip_len += conn->cmd_len; + conn->cmd = CONNECTION_IDLE; + conn->cmd_len = 0; + } + else if (conn->cmd == CONNECTION_IDLE) { const char *errmsg = "Invalid command 0"; sdb_strbuf_sprintf(conn->errbuf, errmsg); sdb_connection_send(conn, CONNECTION_ERROR, diff --git a/t/unit/frontend/connection_test.c b/t/unit/frontend/connection_test.c index 43322e0..a069903 100644 --- a/t/unit/frontend/connection_test.c +++ b/t/unit/frontend/connection_test.c @@ -169,7 +169,7 @@ mock_client(void *arg) } /* mock_client */ static void -connection_setup(sdb_conn_t *conn) +connection_startup(sdb_conn_t *conn) { ssize_t check, expected; @@ -191,7 +191,7 @@ connection_setup(sdb_conn_t *conn) "buffer; expected: 0", sdb_strbuf_len(conn->errbuf)); mock_conn_truncate(conn); -} /* connection_setup */ +} /* connection_startup */ /* * tests @@ -238,7 +238,7 @@ START_TEST(test_conn_setup) } golden_data[] = { /* code == UINT32_MAX => no data will be sent */ { UINT32_MAX, NULL, NULL }, - { CONNECTION_IDLE, "fakedata", "Invalid command 0" }, + { CONNECTION_IDLE, "fakedata", "Authentication required" }, { CONNECTION_PING, NULL, "Authentication required" }, { CONNECTION_STARTUP, "fakeuser", NULL }, { CONNECTION_PING, NULL, NULL }, @@ -308,23 +308,28 @@ START_TEST(test_conn_io) const char *err; } golden_data[] = { /* code == UINT32_MAX => this is a follow-up package */ - { CONNECTION_PING, 20, "9876543210", 10, NULL }, - { UINT32_MAX, -1, "9876543210", 0, NULL }, - { CONNECTION_IDLE, 20, "9876543210", 0, "Invalid command 0" }, - { UINT32_MAX, -1, "9876543210", 0, "Invalid command 0" }, - { CONNECTION_IDLE, 20, "9876543210", 0, "Invalid command 0" }, - { UINT32_MAX, -1, "9876543210", 0, "Invalid command 0" }, - { CONNECTION_PING, 10, "9876543210", 0, NULL }, - { CONNECTION_PING, 20, "9876543210", 10, NULL }, - { UINT32_MAX, -1, "9876543210", 0, NULL }, + { CONNECTION_PING, 20, "9876543210", 0, "Authentication required" }, + { UINT32_MAX, -1, "9876543210", 0, "Authentication required" }, + { CONNECTION_PING, 10, "9876543210", 0, "Authentication required" }, + { CONNECTION_IDLE, 10, "9876543210", 0, "Authentication required" }, + { CONNECTION_IDLE, 20, "9876543210", 0, "Authentication required" }, + { UINT32_MAX, -1, "9876543210", 0, "Authentication required" }, + { CONNECTION_STARTUP, -1, NULL, 0, NULL }, + { CONNECTION_PING, 20, "9876543210", 10, NULL }, + { UINT32_MAX, -1, "9876543210", 0, NULL }, + { CONNECTION_IDLE, 20, "9876543210", 0, "Invalid command 0" }, + { UINT32_MAX, -1, "9876543210", 0, "Invalid command 0" }, + { CONNECTION_IDLE, 20, "9876543210", 0, "Invalid command 0" }, + { UINT32_MAX, -1, "9876543210", 0, "Invalid command 0" }, + { CONNECTION_PING, 10, "9876543210", 0, NULL }, + { CONNECTION_PING, 20, "9876543210", 10, NULL }, + { UINT32_MAX, -1, "9876543210", 0, NULL }, }; size_t i; - connection_setup(conn); - for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) { - size_t msg_len = strlen(golden_data[i].msg); + size_t msg_len = golden_data[i].msg ? strlen(golden_data[i].msg) : 0; char buffer[2 * sizeof(uint32_t) + msg_len]; size_t offset = 0; @@ -332,6 +337,11 @@ START_TEST(test_conn_io) mock_conn_truncate(conn); + if (golden_data[i].code == CONNECTION_STARTUP) { + connection_startup(conn); + continue; + } + if (golden_data[i].code != UINT32_MAX) { uint32_t tmp; -- 2.30.2