Browse Source

* check auth on "inet" csocket connections

master
Alex 'AdUser' Z 4 years ago
parent
commit
fe48ee2961
  1. 9
      src/commands.c
  2. 1
      src/commands.h
  3. 35
      src/csocket.c

9
src/commands.c

@ -20,6 +20,11 @@ struct cmd_desc {
.argc = 0, .tokenc = 1, .argc = 0, .tokenc = 1,
.tokens = { "help", NULL }, .tokens = { "help", NULL },
.help = "Show available commands", .help = "Show available commands",
}, {
.type = CMD_AUTH,
.argc = 2, .tokenc = 3,
.tokens = { "auth", "<type>", "<password>", NULL },
.help = "Check authorization (available types is: plain)",
}, { }, {
.type = CMD_STATUS, .type = CMD_STATUS,
.argc = 0, .tokenc = 1, .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) { if (cmd->argc == 4 && strcmp(cmd->args[2], "filter") == 0 && strcmp(cmd->args[3], "reload") == 0) {
cmd->type = CMD_JAIL_FILTER_RELOAD; return true; 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) { } else if (strcmp(cmd->args[0], "log") == 0 && cmd->argc > 1) {
if (cmd->argc == 2 && strcmp(cmd->args[1], "rotate") == 0) { if (cmd->argc == 2 && strcmp(cmd->args[1], "rotate") == 0) {
cmd->type = CMD_LOG_ROTATE; return true; cmd->type = CMD_LOG_ROTATE; return true;

1
src/commands.h

@ -18,6 +18,7 @@
enum f2b_command_type { enum f2b_command_type {
CMD_UNKNOWN = 0, /**< unset */ CMD_UNKNOWN = 0, /**< unset */
CMD_AUTH, /**< authorization */
CMD_HELP, /**< show help for commands */ CMD_HELP, /**< show help for commands */
CMD_STATUS, /**< show general status of f2b daemon */ CMD_STATUS, /**< show general status of f2b daemon */
CMD_RELOAD, /**< reload all jails */ CMD_RELOAD, /**< reload all jails */

35
src/csocket.c

@ -22,6 +22,7 @@ typedef struct f2b_conn_t {
f2b_buf_t send; f2b_buf_t send;
int sock; int sock;
int flags; int flags;
const char *password;
char peer[40]; /* remote address ipv4/ipv6 */ char peer[40]; /* remote address ipv4/ipv6 */
} f2b_conn_t; } f2b_conn_t;
@ -70,6 +71,35 @@ f2b_conn_destroy(f2b_conn_t *conn) {
free(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 int
f2b_conn_process(f2b_conn_t *conn, bool in, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) { 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; 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); f2b_log_msg(log_debug, "extracted line: %s", line);
if ((cmd = f2b_cmd_create(line)) != NULL) { 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); f2b_cmd_destroy(cmd);
} else { } else {
f2b_buf_append(&conn->send, "-can't parse input, try 'help'\n", 0); 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->flags |= CSOCKET_CONN_NEED_AUTH;
} }
conn->sock = sock; conn->sock = sock;
conn->password = csock->password;
csock->clients[cnum] = conn; csock->clients[cnum] = conn;
} else { } else {
f2b_log_msg(log_error, "can't create new connection"); f2b_log_msg(log_error, "can't create new connection");

Loading…
Cancel
Save