From a45a313422efa33f261cb1b53a08646a6b3ab947 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 11 Apr 2014 15:50:43 +0200 Subject: Improve shell command config handling --- src/config.c | 22 +++++------- src/config.y | 42 ++++------------------- src/fastd.c | 20 +++-------- src/fastd.h | 31 +++++------------ src/options.c | 42 ++++------------------- src/peer.c | 16 +++------ src/peer.h | 4 --- src/protocols/ec25519_fhmqvc/handshake.c | 6 +++- src/receive.c | 2 +- src/shell.c | 13 ++++--- src/shell.h | 59 ++++++++++++++++++++++++++++++++ src/types.h | 5 +-- 12 files changed, 116 insertions(+), 146 deletions(-) create mode 100644 src/shell.h (limited to 'src') diff --git a/src/config.c b/src/config.c index 7876f75..58327a5 100644 --- a/src/config.c +++ b/src/config.c @@ -691,25 +691,19 @@ void fastd_config_release(fastd_context_t *ctx, fastd_config_t *conf) { fastd_mac_config_free(conf->macs); fastd_cipher_config_free(conf->ciphers); + fastd_shell_command_unset(&conf->on_pre_up); + fastd_shell_command_unset(&conf->on_up); + fastd_shell_command_unset(&conf->on_down); + fastd_shell_command_unset(&conf->on_post_down); + fastd_shell_command_unset(&conf->on_establish); + fastd_shell_command_unset(&conf->on_disestablish); + fastd_shell_command_unset(&conf->on_verify); + free(conf->user); free(conf->group); free(conf->groups); free(conf->ifname); free(conf->secret); - free(conf->on_pre_up); - free(conf->on_pre_up_dir); - free(conf->on_up); - free(conf->on_up_dir); - free(conf->on_down); - free(conf->on_down_dir); - free(conf->on_post_down); - free(conf->on_post_down_dir); - free(conf->on_establish); - free(conf->on_establish_dir); - free(conf->on_disestablish); - free(conf->on_disestablish_dir); - free(conf->on_verify); - free(conf->on_verify_dir); free(conf->protocol_config); free(conf->log_syslog_ident); } diff --git a/src/config.y b/src/config.y index e6688d6..70ee4a2 100644 --- a/src/config.y +++ b/src/config.y @@ -374,65 +374,37 @@ secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); } ; on_pre_up: TOK_STRING { - free(conf->on_pre_up); - free(conf->on_pre_up_dir); - - conf->on_pre_up = strdup($1->str); - conf->on_pre_up_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_pre_up, $1->str); } ; on_up: TOK_STRING { - free(conf->on_up); - free(conf->on_up_dir); - - conf->on_up = strdup($1->str); - conf->on_up_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_up, $1->str); } ; on_down: TOK_STRING { - free(conf->on_down); - free(conf->on_down_dir); - - conf->on_down = strdup($1->str); - conf->on_down_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_down, $1->str); } ; on_post_down: TOK_STRING { - free(conf->on_post_down); - free(conf->on_post_down_dir); - - conf->on_post_down = strdup($1->str); - conf->on_post_down_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_post_down, $1->str); } ; on_establish: TOK_STRING { - free(conf->on_establish); - free(conf->on_establish_dir); - - conf->on_establish = strdup($1->str); - conf->on_establish_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_establish, $1->str); } ; on_disestablish: TOK_STRING { - free(conf->on_disestablish); - free(conf->on_disestablish_dir); - - conf->on_disestablish = strdup($1->str); - conf->on_disestablish_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_disestablish, $1->str); } ; on_verify: TOK_STRING { - free(conf->on_verify); - free(conf->on_verify_dir); - - conf->on_verify = strdup($1->str); - conf->on_verify_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_verify, $1->str); } ; diff --git a/src/fastd.c b/src/fastd.c index 6807ca5..c6fec8b 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -270,31 +270,19 @@ void fastd_handle_receive(fastd_context_t *ctx, fastd_peer_t *peer, fastd_buffer } static inline void on_pre_up(fastd_context_t *ctx) { - if (!ctx->conf->on_pre_up) - return; - - fastd_shell_exec(ctx, ctx->conf->on_pre_up, ctx->conf->on_pre_up_dir, NULL, NULL, NULL, NULL); + fastd_shell_command_exec(ctx, &ctx->conf->on_pre_up, NULL, NULL, NULL, NULL); } static inline void on_up(fastd_context_t *ctx) { - if (!ctx->conf->on_up) - return; - - fastd_shell_exec(ctx, ctx->conf->on_up, ctx->conf->on_up_dir, NULL, NULL, NULL, NULL); + fastd_shell_command_exec(ctx, &ctx->conf->on_up, NULL, NULL, NULL, NULL); } static inline void on_down(fastd_context_t *ctx) { - if (!ctx->conf->on_down) - return; - - fastd_shell_exec(ctx, ctx->conf->on_down, ctx->conf->on_down_dir, NULL, NULL, NULL, NULL); + fastd_shell_command_exec(ctx, &ctx->conf->on_down, NULL, NULL, NULL, NULL); } static inline void on_post_down(fastd_context_t *ctx) { - if (!ctx->conf->on_post_down) - return; - - fastd_shell_exec(ctx, ctx->conf->on_post_down, ctx->conf->on_post_down_dir, NULL, NULL, NULL, NULL); + fastd_shell_command_exec(ctx, &ctx->conf->on_post_down, NULL, NULL, NULL, NULL); } static fastd_peer_group_t* init_peer_group(const fastd_peer_group_config_t *config, fastd_peer_group_t *parent) { diff --git a/src/fastd.h b/src/fastd.h index 9412116..c117cdc 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -26,11 +26,11 @@ #pragma once -#include "compat.h" #include "types.h" #include "dlist.h" #include "buffer.h" #include "log.h" +#include "shell.h" #include #include @@ -205,26 +205,13 @@ struct fastd_config { fastd_protocol_config_t *protocol_config; - char *on_pre_up; - char *on_pre_up_dir; - - char *on_up; - char *on_up_dir; - - char *on_down; - char *on_down_dir; - - char *on_post_down; - char *on_post_down_dir; - - char *on_establish; - char *on_establish_dir; - - char *on_disestablish; - char *on_disestablish_dir; - - char *on_verify; - char *on_verify_dir; + fastd_shell_command_t on_pre_up; + fastd_shell_command_t on_up; + fastd_shell_command_t on_down; + fastd_shell_command_t on_post_down; + fastd_shell_command_t on_establish; + fastd_shell_command_t on_disestablish; + fastd_shell_command_t on_verify; bool daemon; char *pid_file; @@ -317,8 +304,6 @@ void fastd_tuntap_close(fastd_context_t *ctx); void fastd_cap_init(fastd_context_t *ctx); void fastd_cap_drop(fastd_context_t *ctx); -bool fastd_shell_exec(fastd_context_t *ctx, const char *command, const char *dir, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr, int *ret); - void fastd_random_bytes(fastd_context_t *ctx, void *buffer, size_t len, bool secure); static inline int fastd_rand(fastd_context_t *ctx, int min, int max) { diff --git a/src/options.c b/src/options.c index 1e469a0..03f50ae 100644 --- a/src/options.c +++ b/src/options.c @@ -270,59 +270,31 @@ static void option_forward(fastd_context_t *ctx UNUSED, fastd_config_t *conf) { #ifdef WITH_CMDLINE_COMMANDS static void option_on_pre_up(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - free(conf->on_pre_up); - free(conf->on_pre_up_dir); - - conf->on_pre_up = strdup(arg); - conf->on_pre_up_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_pre_up, arg); } static void option_on_up(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - free(conf->on_up); - free(conf->on_up_dir); - - conf->on_up = strdup(arg); - conf->on_up_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_up, arg); } static void option_on_down(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - free(conf->on_down); - free(conf->on_down_dir); - - conf->on_down = strdup(arg); - conf->on_down_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_down, arg); } static void option_on_post_down(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - free(conf->on_post_down); - free(conf->on_post_down_dir); - - conf->on_post_down = strdup(arg); - conf->on_post_down_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_post_down, arg); } static void option_on_establish(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - free(conf->on_establish); - free(conf->on_establish_dir); - - conf->on_establish = strdup(arg); - conf->on_establish_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_establish, arg); } static void option_on_disestablish(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - free(conf->on_disestablish); - free(conf->on_disestablish_dir); - - conf->on_disestablish = strdup(arg); - conf->on_disestablish_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_disestablish, arg); } static void option_on_verify(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) { - free(conf->on_verify); - free(conf->on_verify_dir); - - conf->on_verify = strdup(arg); - conf->on_verify_dir = get_current_dir_name(); + fastd_shell_command_set(&conf->on_verify, arg); } #endif diff --git a/src/peer.c b/src/peer.c index 82d5fa4..07354df 100644 --- a/src/peer.c +++ b/src/peer.c @@ -31,17 +31,11 @@ static inline void on_establish(fastd_context_t *ctx, const fastd_peer_t *peer) { - if (!ctx->conf->on_establish) - return; - - fastd_shell_exec(ctx, ctx->conf->on_establish, ctx->conf->on_establish_dir, peer, &peer->local_address, &peer->address, NULL); + fastd_shell_command_exec(ctx, &ctx->conf->on_establish, peer, &peer->local_address, &peer->address, NULL); } static inline void on_disestablish(fastd_context_t *ctx, const fastd_peer_t *peer) { - if (!ctx->conf->on_disestablish) - return; - - fastd_shell_exec(ctx, ctx->conf->on_disestablish, ctx->conf->on_disestablish_dir, peer, &peer->local_address, &peer->address, NULL); + fastd_shell_command_exec(ctx, &ctx->conf->on_disestablish, peer, &peer->local_address, &peer->address, NULL); } static inline void free_socket(fastd_context_t *ctx, fastd_peer_t *peer) { @@ -558,7 +552,7 @@ fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *peer_con } fastd_peer_t* fastd_peer_add_temporary(fastd_context_t *ctx) { - if (!ctx->conf->on_verify) + if (!fastd_shell_command_isset(&ctx->conf->on_verify)) exit_bug(ctx, "tried to add temporary peer without on-verify command"); fastd_peer_t *peer = calloc(1, sizeof(fastd_peer_t)); @@ -577,11 +571,11 @@ fastd_peer_t* fastd_peer_add_temporary(fastd_context_t *ctx) { } bool fastd_peer_verify_temporary(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr) { - if (!ctx->conf->on_verify) + if (!fastd_shell_command_isset(&ctx->conf->on_verify)) exit_bug(ctx, "tried to verify temporary peer without on-verify command"); int ret; - if (!fastd_shell_exec(ctx, ctx->conf->on_verify, ctx->conf->on_verify_dir, peer, local_addr, peer_addr, &ret)) + if (!fastd_shell_command_exec(ctx, &ctx->conf->on_verify, peer, local_addr, peer_addr, &ret)) return false; if (WIFSIGNALED(ret)) { diff --git a/src/peer.h b/src/peer.h index 6deeacb..7e3bf08 100644 --- a/src/peer.h +++ b/src/peer.h @@ -160,10 +160,6 @@ static inline bool fastd_peer_handshake_scheduled(fastd_context_t *ctx UNUSED, f fastd_eth_addr_t fastd_get_source_address(const fastd_context_t *ctx, fastd_buffer_t buffer); fastd_eth_addr_t fastd_get_dest_address(const fastd_context_t *ctx, fastd_buffer_t buffer); -static inline bool fastd_peer_allow_unknown(fastd_context_t *ctx) { - return ctx->conf->on_verify; -} - static inline bool fastd_peer_config_is_floating(const fastd_peer_config_t *config) { return (!config->remotes || config->floating); } diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c index a8bde30..6de47ef 100644 --- a/src/protocols/ec25519_fhmqvc/handshake.c +++ b/src/protocols/ec25519_fhmqvc/handshake.c @@ -486,8 +486,12 @@ bool fastd_protocol_ec25519_fhmqvc_peer_check_temporary(fastd_context_t *ctx, fa return true; } +static inline bool allow_unknown(fastd_context_t *ctx) { + return fastd_shell_command_isset(&ctx->conf->on_verify); +} + static inline fastd_peer_t* add_temporary(fastd_context_t *ctx, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, const unsigned char key[32]) { - if (!fastd_peer_allow_unknown(ctx)) { + if (!allow_unknown(ctx)) { pr_debug(ctx, "ignoring handshake from %I (unknown key)", remote_addr); return NULL; } diff --git a/src/receive.c b/src/receive.c index d0e38a2..f53b263 100644 --- a/src/receive.c +++ b/src/receive.c @@ -131,7 +131,7 @@ static inline void handle_socket_receive_known(fastd_context_t *ctx, fastd_socke } static inline bool allow_unknown_peers(fastd_context_t *ctx) { - return ctx->conf->has_floating || ctx->conf->on_verify; + return ctx->conf->has_floating || fastd_shell_command_isset(&ctx->conf->on_verify); } static inline void handle_socket_receive_unknown(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_buffer_t buffer) { diff --git a/src/shell.c b/src/shell.c index 7acfa48..6d60a07 100644 --- a/src/shell.c +++ b/src/shell.c @@ -24,6 +24,7 @@ */ +#include "shell.h" #include "peer.h" #include @@ -31,12 +32,16 @@ #include -bool fastd_shell_exec(fastd_context_t *ctx, const char *command, const char *dir, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr, int *ret) { +bool fastd_shell_command_exec(fastd_context_t *ctx, const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr, int *ret) { + if (!fastd_shell_command_isset(command)) + return true; + int result = -1; bool ok = false; char *cwd = get_current_dir_name(); - if(!chdir(dir)) { + + if(!chdir(command->dir)) { /* both INET6_ADDRSTRLEN and IFNAMESIZE already include space for the zero termination, so there is no need to add space for the '%' here. */ char buf[INET6_ADDRSTRLEN+IF_NAMESIZE]; @@ -128,7 +133,7 @@ bool fastd_shell_exec(fastd_context_t *ctx, const char *command, const char *dir ctx->conf->protocol->set_shell_env(ctx, peer); - result = system(command); + result = system(command->command); if (ret) { *ret = result; @@ -147,7 +152,7 @@ bool fastd_shell_exec(fastd_context_t *ctx, const char *command, const char *dir pr_error(ctx, "can't chdir to `%s': %s", cwd, strerror(errno)); } else { - pr_error(ctx, "can't chdir to `%s': %s", dir, strerror(errno)); + pr_error(ctx, "can't chdir to `%s': %s", command->dir, strerror(errno)); } free(cwd); diff --git a/src/shell.h b/src/shell.h new file mode 100644 index 0000000..18ceb2a --- /dev/null +++ b/src/shell.h @@ -0,0 +1,59 @@ +/* + Copyright (c) 2012-2014, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#pragma once + +#include "types.h" + +#include +#include + + +struct fastd_shell_command { + char *command; + char *dir; +}; + +static inline void fastd_shell_command_unset(fastd_shell_command_t *command) { + free(command->command); + command->command = NULL; + + free(command->dir); + command->dir = NULL; +} + +static inline void fastd_shell_command_set(fastd_shell_command_t *command, const char *val) { + fastd_shell_command_unset(command); + + command->command = strdup(val); + command->dir = get_current_dir_name(); +} + +static inline bool fastd_shell_command_isset(const fastd_shell_command_t *command) { + return command->command; +} + +bool fastd_shell_command_exec(fastd_context_t *ctx, const fastd_shell_command_t *command, const fastd_peer_t *peer, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *peer_addr, int *ret); diff --git a/src/types.h b/src/types.h index a474b78..37560b1 100644 --- a/src/types.h +++ b/src/types.h @@ -32,11 +32,10 @@ #pragma once -#include +#include "compat.h" #include #include -#include #define UNUSED __attribute__((unused)) @@ -132,6 +131,8 @@ typedef struct fastd_handshake fastd_handshake_t; typedef struct fastd_lex fastd_lex_t; typedef struct fastd_string_stack fastd_string_stack_t; +typedef struct fastd_shell_command fastd_shell_command_t; + typedef struct fastd_async_resolve_return fastd_async_resolve_return_t; -- cgit v1.2.3