summaryrefslogtreecommitdiffstats
path: root/src/verify.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/verify.c')
-rw-r--r--src/verify.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/verify.c b/src/verify.c
new file mode 100644
index 0000000..fb592bd
--- /dev/null
+++ b/src/verify.c
@@ -0,0 +1,111 @@
+/*
+ Copyright (c) 2012-2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ 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.
+*/
+
+
+#include "verify.h"
+#include "async.h"
+#include "shell.h"
+
+#include <pthread.h>
+
+
+static bool do_verify(const fastd_shell_env_t *env) {
+ int ret;
+ if (!fastd_shell_command_exec_sync(&conf.on_verify, env, &ret))
+ return false;
+
+ if (WIFSIGNALED(ret)) {
+ pr_error("verify command exited with signal %i", WTERMSIG(ret));
+ return false;
+ }
+ else if (WEXITSTATUS(ret)) {
+ pr_debug("verify command exited with status %i", WEXITSTATUS(ret));
+ return false;
+ }
+
+ return true;
+}
+
+typedef struct verify_arg {
+ fastd_shell_env_t *env;
+ size_t ret_len;
+ fastd_async_verify_return_t ret;
+} verify_arg_t;
+
+static void * do_verify_thread(void *p) {
+ verify_arg_t *arg = p;
+
+ arg->ret.ok = do_verify(arg->env);
+ fastd_shell_env_free(arg->env);
+
+ fastd_async_enqueue(ASYNC_TYPE_VERIFY_RETURN, &arg->ret, arg->ret_len);
+
+ free(arg);
+
+ return NULL;
+}
+
+fastd_tristate_t fastd_verify_peer(fastd_peer_t *peer, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, const fastd_method_info_t *method, const void *data, size_t data_len) {
+ if (!fastd_shell_command_isset(&conf.on_verify))
+ exit_bug("tried to verify peer without on-verify command");
+
+ fastd_peer_set_verifying(peer);
+
+ fastd_shell_env_t *env = fastd_shell_env_alloc();
+ fastd_peer_set_shell_env(env, peer, local_addr, remote_addr);
+
+ if (conf.on_verify.sync) {
+ bool ret = do_verify(env);
+ fastd_shell_env_free(env);
+ fastd_peer_set_verified(peer, ret);
+ return (fastd_tristate_t){.set = true, .state = ret};
+ }
+ else {
+ verify_arg_t *arg = calloc(1, sizeof(verify_arg_t) + data_len);
+
+ arg->env = env;
+ arg->ret_len = sizeof(fastd_async_verify_return_t) + data_len;
+
+ arg->ret.peer_id = peer->id;
+ arg->ret.method = method;
+ arg->ret.sock = sock;
+ arg->ret.local_addr = *local_addr;
+ arg->ret.remote_addr = *remote_addr;
+ memcpy(arg->ret.protocol_data, data, data_len);
+
+ pthread_t thread;
+ if ((errno = pthread_create(&thread, NULL, do_verify_thread, arg)) != 0) {
+ pr_error_errno("unable to create verify thread");
+
+ fastd_shell_env_free(env);
+ free(arg);
+
+ return (fastd_tristate_t){.set = true, .state = false};
+ }
+
+ pthread_detach(thread);
+ return (fastd_tristate_t){.set = false};
+ }
+}