dbus: added new commands for ban/list

This commit is contained in:
Nikos Mavrogiannopoulos
2015-04-03 10:38:17 +02:00
parent a35f020b32
commit fdaac88e37
2 changed files with 367 additions and 3 deletions
+182
View File
@@ -30,6 +30,7 @@
#include <errno.h>
#include <main-ctl.h>
#include <main-ban.h>
#include <dbus/dbus.h>
#include <str.h>
@@ -48,6 +49,9 @@ static void method_status(main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg);
static void method_list_users(main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg);
static void method_unban_ip(main_server_st * s,
struct dbus_ctx *ctx,
DBusMessage * msg);
static void method_disconnect_user_name(main_server_st * s,
struct dbus_ctx *ctx,
DBusMessage * msg);
@@ -63,6 +67,8 @@ static void method_user_info(main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg);
static void method_id_info(main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg);
static void method_list_banned(main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg);
typedef void (*method_func) (main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg);
@@ -92,12 +98,18 @@ typedef struct {
#define LIST_USERS_SIG "(issssssssusssss)"
#define LIST_SINGLE_USER_SIG "(issssssssusssssuuasasasas)"
#define LIST_BANNED_SIG "(usu)"
#define DESC_LIST \
" <method name=\"list\">\n" \
" <arg name=\"user-info\" direction=\"out\" type=\"a"LIST_USERS_SIG"\"/>\n" \
" </method>\n"
#define DESC_LIST_BANNED \
" <method name=\"list\">\n" \
" <arg name=\"banned-info\" direction=\"out\" type=\"a"LIST_BANNED_SIG"\"/>\n" \
" </method>\n"
#define DESC_USER_INFO \
" <method name=\"user_info\">\n" \
" <arg name=\"user-info\" direction=\"out\" type=\"a"LIST_SINGLE_USER_SIG"\"/>\n" \
@@ -131,6 +143,12 @@ typedef struct {
" <arg name=\"status\" direction=\"out\" type=\"b\"/>\n" \
" </method>\n"
#define DESC_UNBAN_IP \
" <method name=\"unban_ip\">\n" \
" <arg name=\"user-ip\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"status\" direction=\"out\" type=\"b\"/>\n" \
" </method>\n"
#define DESC_STATUS \
" <method name=\"status\">\n" \
" <arg name=\"status\" direction=\"out\" type=\"b\"/>\n" \
@@ -146,11 +164,14 @@ static const ctl_method_st methods[] = {
ENTRY("reload", "org.infradead.ocserv", DESC_RELOAD, method_reload),
ENTRY("stop", "org.infradead.ocserv", DESC_RELOAD, method_stop),
ENTRY("list", "org.infradead.ocserv", DESC_LIST, method_list_users),
ENTRY("list_banned", "org.infradead.ocserv", DESC_LIST_BANNED, method_list_banned),
ENTRY("user_info2", "org.infradead.ocserv", DESC_USER_INFO,
method_user_info),
ENTRY("id_info2", "org.infradead.ocserv", DESC_ID_INFO, method_id_info),
ENTRY("disconnect_name", "org.infradead.ocserv", DESC_DISC_NAME,
method_disconnect_user_name),
ENTRY("unban_ip", "org.infradead.ocserv", DESC_UNBAN_IP,
method_unban_ip),
ENTRY("disconnect_id", "org.infradead.ocserv", DESC_DISC_ID,
method_disconnect_user_id),
{NULL, 0, NULL, 0, NULL}
@@ -661,6 +682,109 @@ static void method_list_users(main_server_st * s, struct dbus_ctx *ctx,
return;
}
static int append_ban_info(main_server_st *s,
DBusMessageIter *suba,
struct ban_entry_st *e)
{
DBusMessageIter subs;
dbus_uint32_t t;
if (dbus_message_iter_open_container
(suba, DBUS_TYPE_STRUCT, NULL, &subs) == 0) {
mslog(s, NULL, LOG_ERR,
"error appending container to dbus reply");
return -1;
}
t = e->score;
if (dbus_message_iter_append_basic(&subs, DBUS_TYPE_UINT32, &t) == 0) {
mslog(s, NULL, LOG_ERR, "error appending to dbus reply");
return -1;
}
if (dbus_message_iter_append_basic(&subs, DBUS_TYPE_STRING, &e->ip) == 0) {
mslog(s, NULL, LOG_ERR, "error appending to dbus reply");
return -1;
}
if (s->config->max_ban_score > 0 && e->score >= s->config->max_ban_score) {
t = e->expires;
} else {
t = 0;
}
if (dbus_message_iter_append_basic(&subs, DBUS_TYPE_UINT32, &t) == 0) {
mslog(s, NULL, LOG_ERR, "error appending to dbus reply");
return -1;
}
if (dbus_message_iter_close_container(suba, &subs) == 0) {
mslog(s, NULL, LOG_ERR,
"error closing container in dbus reply");
return -1;
}
return 0;
}
static void method_list_banned(main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg)
{
DBusMessage *reply;
DBusMessageIter args;
DBusMessageIter suba;
int ret;
struct ban_entry_st *e = NULL;
struct htable *db = s->ban_db;
struct htable_iter iter;
mslog(s, NULL, LOG_DEBUG, "ctl: list-banned");
/* no arguments needed */
reply = dbus_message_new_method_return(msg);
if (reply == NULL) {
mslog(s, NULL, LOG_ERR, "error generating dbus reply");
return;
}
dbus_message_iter_init_append(reply, &args);
if (dbus_message_iter_open_container
(&args, DBUS_TYPE_ARRAY, LIST_BANNED_SIG, &suba) == 0) {
mslog(s, NULL, LOG_ERR,
"error appending container to dbus reply");
goto error;
}
e = htable_first(db, &iter);
while (e != NULL) {
ret = append_ban_info(s, &suba, e);
if (ret < 0) {
mslog(s, NULL, LOG_ERR,
"error appending ban info to reply");
goto error;
}
e = htable_next(db, &iter);
}
if (dbus_message_iter_close_container(&args, &suba) == 0) {
mslog(s, NULL, LOG_ERR,
"error closing container in dbus reply");
goto error;
}
if (!dbus_connection_send(ctx->conn, reply, NULL)) {
mslog(s, NULL, LOG_ERR, "error sending dbus reply");
goto error;
}
error:
dbus_message_unref(reply);
return;
}
static void single_info_common(main_server_st * s, struct dbus_ctx *ctx,
DBusMessage * msg, const char *user, unsigned id)
{
@@ -804,6 +928,64 @@ static void method_id_info(main_server_st * s, struct dbus_ctx *ctx,
return;
}
static void method_unban_ip(main_server_st * s,
struct dbus_ctx *ctx,
DBusMessage * msg)
{
DBusMessage *reply;
DBusMessageIter args;
dbus_bool_t status = 0;
char *ip = "";
mslog(s, NULL, LOG_DEBUG, "ctl: unban_ip");
if (dbus_message_iter_init(msg, &args) == 0) {
mslog(s, NULL, LOG_ERR,
"no arguments provided in unban_ip");
return;
}
if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) {
mslog(s, NULL, LOG_ERR,
"wrong argument provided in unban_ip");
return;
}
dbus_message_iter_get_basic(&args, &ip);
if (remove_ip_from_ban_list(s, ip) != 0) {
if (ip)
mslog(s, NULL, LOG_INFO,
"unbanning IP '%s' due to ctl request", ip);
status = 1;
}
/* reply */
reply = dbus_message_new_method_return(msg);
if (reply == NULL) {
mslog(s, NULL, LOG_ERR, "error generating dbus reply");
return;
}
dbus_message_iter_init_append(reply, &args);
if (dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &status) ==
0) {
mslog(s, NULL, LOG_ERR, "error appending to dbus reply");
goto error;
}
if (!dbus_connection_send(ctx->conn, reply, NULL)) {
mslog(s, NULL, LOG_ERR, "error sending dbus reply");
goto error;
}
error:
dbus_message_unref(reply);
return;
}
static void method_disconnect_user_name(main_server_st * s,
struct dbus_ctx *ctx,
DBusMessage * msg)
+185 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 Red Hat
* Copyright (C) 2014, 2015 Red Hat
*
* Author: Nikos Mavrogiannopoulos
*
@@ -29,6 +29,7 @@
#include <dbus/dbus.h>
#include <occtl.h>
#include <c-strcase.h>
#include <arpa/inet.h>
typedef struct dbus_ctx {
DBusConnection *conn;
@@ -253,6 +254,70 @@ int handle_stop_cmd(dbus_ctx *ctx, const char *arg)
return 1;
}
int handle_unban_ip_cmd(struct dbus_ctx *ctx, const char *arg)
{
int af;
struct sockaddr_storage st;
DBusMessage *msg;
DBusMessageIter args;
dbus_bool_t status;
const char *ip;
char txt[MAX_IP_STR];
int ret;
if (arg == NULL || need_help(arg)) {
check_cmd_help(rl_line_buffer);
return 1;
}
/* convert the IP to the simplest form */
if (strchr(arg, ':') != 0) {
af = AF_INET6;
} else {
af = AF_INET;
}
ret = inet_pton(af, arg, &st);
if (ret == 1) {
inet_ntop(af, &st, txt, sizeof(txt));
ip = txt;
} else {
ip = (char*)arg;
}
msg = send_dbus_cmd(ctx, "org.infradead.ocserv",
"/org/infradead/ocserv",
"org.infradead.ocserv",
"unban_ip", DBUS_TYPE_STRING, &ip);
if (msg == NULL) {
goto error;
}
if (!dbus_message_iter_init(msg, &args))
goto error;
if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args))
goto error;
dbus_message_iter_get_basic(&args, &status);
if (status != 0) {
printf("IP '%s' was unbanned\n", ip);
} else {
printf("could not unban IP '%s'\n", ip);
}
dbus_message_unref(msg);
return 0;
error:
fprintf(stderr, ERR_SERVER_UNREACHABLE);
if (msg != NULL)
dbus_message_unref(msg);
return 1;
}
int handle_disconnect_user_cmd(dbus_ctx *ctx, const char *arg)
{
DBusMessage *msg;
@@ -520,7 +585,7 @@ int handle_list_users_cmd(dbus_ctx *ctx, const char *arg)
fprintf(out, "%8d %8s %8s %14s %14s %6s ",
(int)id, username, groupname, ip, vpn_ip, device);
print_time_ival7(t, out);
print_time_ival7(time(0), t, out);
if (dtls_ciphersuite != NULL && dtls_ciphersuite[0] != 0) {
if (strlen(dtls_ciphersuite) > 16 && strncmp(dtls_ciphersuite, "(DTLS", 5) == 0 &&
strncmp(&dtls_ciphersuite[8], ")-(RSA)-", 8) == 0)
@@ -554,6 +619,123 @@ int handle_list_users_cmd(dbus_ctx *ctx, const char *arg)
return ret;
}
static
int handle_list_banned_cmd(struct dbus_ctx *ctx, const char *arg, unsigned points)
{
DBusMessage *msg;
DBusMessageIter args, suba, subs;
dbus_int32_t expires = 0;
char *ip = "";
dbus_int32_t score = 0;
time_t t;
struct tm *tm;
int ret = 1;
char str_since[64];
unsigned iteration = 0;
FILE *out;
ip_entries_clear();
out = pager_start();
msg = send_dbus_cmd(ctx, "org.infradead.ocserv",
"/org/infradead/ocserv",
"org.infradead.ocserv", "list_banned", 0, NULL);
if (msg == NULL) {
goto error_server;
}
if (!dbus_message_iter_init(msg, &args))
goto error_server;
if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
goto error_server;
dbus_message_iter_recurse(&args, &suba);
for (;;) {
if (dbus_message_iter_get_arg_type(&suba) != DBUS_TYPE_STRUCT)
goto cleanup;
dbus_message_iter_recurse(&suba, &subs);
if (dbus_message_iter_get_arg_type(&subs) != DBUS_TYPE_INT32)
goto error_parse;
dbus_message_iter_get_basic(&subs, &expires);
if (!dbus_message_iter_next(&subs))
goto error_recv;
if (dbus_message_iter_get_arg_type(&subs) != DBUS_TYPE_STRING)
goto error_parse;
dbus_message_iter_get_basic(&subs, &ip);
if (!dbus_message_iter_next(&subs))
goto error_recv;
if (dbus_message_iter_get_arg_type(&subs) != DBUS_TYPE_INT32)
goto error_parse;
dbus_message_iter_get_basic(&subs, &score);
if (points == 0) {
if (expires > 0) {
t = expires;
tm = localtime(&t);
strftime(str_since, sizeof(str_since), DATE_TIME_FMT, tm);
} else {
continue;
}
/* add header */
if (iteration == 0) {
fprintf(out, "%14s %14s %30s\n",
"IP", "score", "expires");
}
fprintf(out, "%14s %14u %30s (", ip, (unsigned)score, str_since);
print_time_ival7(t, time(0), out);
fputs(")\n", out);
} else {
if (iteration == 0) {
fprintf(out, "%14s %14s\n",
"IP", "score");
}
fprintf(out, "%14s %14u\n",
ip, (unsigned)score);
}
iteration++;
ip_entries_add(ctx, ip, strlen(ip));
}
ret = 0;
goto cleanup;
error_server:
fprintf(stderr, ERR_SERVER_UNREACHABLE);
goto cleanup;
error_parse:
fprintf(stderr, "%s: D-BUS message parsing error\n", __func__);
goto cleanup;
error_recv:
fprintf(stderr, "%s: D-BUS message receiving error\n", __func__);
cleanup:
pager_stop(out);
if (msg != NULL)
dbus_message_unref(msg);
return ret;
}
int handle_list_banned_ips_cmd(struct dbus_ctx *ctx, const char *arg)
{
return handle_list_banned_cmd(ctx, arg, 0);
}
int handle_list_banned_points_cmd(struct dbus_ctx *ctx, const char *arg)
{
return handle_list_banned_cmd(ctx, arg, 1);
}
int print_list_entries(FILE* out, const char* name, DBusMessageIter * subs)
{
DBusMessageIter suba;
@@ -800,7 +982,7 @@ int common_info_cmd(DBusMessageIter * args)
fprintf(out, "\tHostname: %s\n", hostname);
fprintf(out, "\tConnected at: %s (", str_since);
print_time_ival7(t, out);
print_time_ival7(time(0), t, out);
fprintf(out, ")\n");
fprintf(out, "\tTLS ciphersuite: %s\n", tls_ciphersuite);