mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-12 01:26:48 +08:00
dbus: added new commands for ban/list
This commit is contained in:
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user