From fe48ee2961c8a50f0b48a7bb9a51f93df43b103b Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Wed, 24 Mar 2021 14:55:42 +1000 Subject: [PATCH] * check auth on "inet" csocket connections --- src/commands.c | 9 +++++++++ src/commands.h | 1 + src/csocket.c | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/commands.c b/src/commands.c index 1b8d040..b5bf862 100644 --- a/src/commands.c +++ b/src/commands.c @@ -20,6 +20,11 @@ struct cmd_desc { .argc = 0, .tokenc = 1, .tokens = { "help", NULL }, .help = "Show available commands", + }, { + .type = CMD_AUTH, + .argc = 2, .tokenc = 3, + .tokens = { "auth", "", "", NULL }, + .help = "Check authorization (available types is: plain)", }, { .type = CMD_STATUS, .argc = 0, .tokenc = 1, @@ -205,6 +210,10 @@ f2b_cmd_parse(f2b_cmd_t *cmd, const char *src) { if (cmd->argc == 4 && strcmp(cmd->args[2], "filter") == 0 && strcmp(cmd->args[3], "reload") == 0) { cmd->type = CMD_JAIL_FILTER_RELOAD; return true; } + } else if (strcmp(cmd->args[0], "auth") == 0 && cmd->argc > 1) { + if (cmd->argc == 3 && strcmp(cmd->args[1], "plain") == 0) { + cmd->type = CMD_AUTH; return true; + } } else if (strcmp(cmd->args[0], "log") == 0 && cmd->argc > 1) { if (cmd->argc == 2 && strcmp(cmd->args[1], "rotate") == 0) { cmd->type = CMD_LOG_ROTATE; return true; diff --git a/src/commands.h b/src/commands.h index 82bcfcd..932a457 100644 --- a/src/commands.h +++ b/src/commands.h @@ -18,6 +18,7 @@ enum f2b_command_type { CMD_UNKNOWN = 0, /**< unset */ + CMD_AUTH, /**< authorization */ CMD_HELP, /**< show help for commands */ CMD_STATUS, /**< show general status of f2b daemon */ CMD_RELOAD, /**< reload all jails */ diff --git a/src/csocket.c b/src/csocket.c index ef48c09..dbcfbc0 100644 --- a/src/csocket.c +++ b/src/csocket.c @@ -22,6 +22,7 @@ typedef struct f2b_conn_t { f2b_buf_t send; int sock; int flags; + const char *password; char peer[40]; /* remote address ipv4/ipv6 */ } f2b_conn_t; @@ -70,6 +71,35 @@ f2b_conn_destroy(f2b_conn_t *conn) { free(conn); } +bool +f2b_conn_check_auth(f2b_conn_t *conn, f2b_cmd_t *cmd) { + assert(conn != NULL); + assert(cmd != NULL); + + if ((conn->flags & CSOCKET_CONN_NEED_AUTH) == 0) + return true; /* not needed */ + + if (conn->flags & CSOCKET_CONN_AUTH_OK) + return true; /* already passed */ + + if (cmd->type == CMD_AUTH) { + if (strcmp(cmd->args[1], "plain") == 0) { + if (strcmp(cmd->args[2], conn->password) == 0) { + conn->flags |= CSOCKET_CONN_AUTH_OK; + f2b_buf_append(&conn->send, "+ok\n", 0); + return true; + } else { + f2b_log_msg(log_error, "csocket auth failure from %s: password mismatch", conn->peer); + } + } else { + f2b_log_msg(log_error, "csocket auth failure from %s: unknown auth method", conn->peer); + } + } /* else: other command */ + + f2b_buf_append(&conn->send, "-unauthorized\n", 0); + return false; +} + int f2b_conn_process(f2b_conn_t *conn, bool in, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) { f2b_cmd_t *cmd = NULL; @@ -108,7 +138,9 @@ f2b_conn_process(f2b_conn_t *conn, bool in, void (*cb)(const f2b_cmd_t *cmd, f2b } f2b_log_msg(log_debug, "extracted line: %s", line); if ((cmd = f2b_cmd_create(line)) != NULL) { - cb(cmd, &conn->send); /* handle command */ + if (f2b_conn_check_auth(conn, cmd)) { + cb(cmd, &conn->send); /* handle command */ + } f2b_cmd_destroy(cmd); } else { f2b_buf_append(&conn->send, "-can't parse input, try 'help'\n", 0); @@ -411,6 +443,7 @@ f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t conn->flags |= CSOCKET_CONN_NEED_AUTH; } conn->sock = sock; + conn->password = csock->password; csock->clients[cnum] = conn; } else { f2b_log_msg(log_error, "can't create new connection");