From 4a98bc288f1e82c057fd9fdd8f92367c66e062e3 Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Sat, 1 Oct 2022 15:02:45 +0900 Subject: [PATCH] utils: Add interceptor and injector for IPC PubSub messages Because the IPC module uses the file system to exchange messages, remote systems cannot communicate without a shared file system such as NFS. However, NFS may not be an option due to resource and security constraints. This commit adds the ipc-tap and ipc-inject utilities, which can be used to bridge messages over an SSH connection. As the name suggests, the ipc-tap utility taps into topics and outputs messages published on those topics to standard output. The ipc-inject reads messages from standard input and injects them into local PubSub topics. --- Makefile | 5 +++ utils/ipc-inject.sh | 71 +++++++++++++++++++++++++++++ utils/ipc-tap.sh | 107 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100755 utils/ipc-inject.sh create mode 100755 utils/ipc-tap.sh diff --git a/Makefile b/Makefile index 1f060d5..e84b654 100644 --- a/Makefile +++ b/Makefile @@ -17,14 +17,19 @@ install: mkdir -p $(DESTDIR)/var/lib/toolbox/ipc cp toolbox.sh $(DESTDIR)/$(PREFIX)/share/toolbox/. cp -r include $(DESTDIR)/$(PREFIX)/share/toolbox/. + cp -r utils $(DESTDIR)/$(PREFIX)/share/toolbox/. chown -R root.root $(DESTDIR)/$(PREFIX)/share/toolbox find $(DESTDIR)/$(PREFIX)/share/toolbox -type d -exec chmod 755 {} \; find $(DESTDIR)/$(PREFIX)/share/toolbox -type f -exec chmod 644 {} \; chmod -R 755 $(DESTDIR)/$(PREFIX)/share/toolbox ln -sf $(PREFIX)/share/toolbox/toolbox.sh $(DESTDIR)/$(PREFIX)/bin/toolbox.sh + ln -sf $(PREFIX)/share/toolbox/utils/ipc-tap.sh $(DESTDIR)/$(PREFIX)/bin/ipc-tap + ln -sf $(PREFIX)/share/toolbox/utils/ipc-inject.sh $(DESTDIR)/$(PREFIX)/bin/ipc-inject uninstall: rm $(DESTDIR)/$(PREFIX)/bin/toolbox.sh + rm $(DESTDIR)/$(PREFIX)/bin/ipc-tap + rm $(DESTDIR)/$(PREFIX)/bin/ipc-inject rm -rf $(DESTDIR)/$(PREFIX)/share/toolbox .PHONY: $(PHONY) diff --git a/utils/ipc-inject.sh b/utils/ipc-inject.sh new file mode 100755 index 0000000..b0f418d --- /dev/null +++ b/utils/ipc-inject.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# ipc-inject.sh - Injector for toolbox IPC PubSub messages +# Copyright (C) 2022 Matthias Kruk +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +signal_handler() { + signal_received=1 +} + +main() { + local endpoint + local message + declare -gi signal_received + + signal_received=0 + + if ! opt_parse "$@"; then + return 1 + fi + + if ! endpoint=$(ipc_endpoint_open); then + return 1 + fi + + log_info "Using endpoint $endpoint" + trap signal_handler INT TERM ABRT ALRM USR1 USR2 + + while (( signal_received == 0 )) && read -r message; do + local topic + + if ! topic=$(ipc_msg_get_topic "$message"); then + log_warn "Dropping message without topic" + continue + fi + + if ! ipc_endpoint_publish "$endpoint" "$topic" "$message"; then + log_error "Could not publish message for $topic on $endpoint" + fi + done + + log_info "Closing endpoint $endpoint" + ipc_endpoint_close "$endpoint" + + return 0 +} + +{ + if ! . toolbox.sh; then + exit 1 + fi + + if ! include "log" "opt" "ipc"; then + exit 1 + fi + + main "$@" + exit "$?" +} diff --git a/utils/ipc-tap.sh b/utils/ipc-tap.sh new file mode 100755 index 0000000..45279b0 --- /dev/null +++ b/utils/ipc-tap.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +# ipc-tap.sh - Interceptor for toolbox IPC PubSub messages +# Copyright (C) 2022 Matthias Kruk +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +add_topic() { + # local name="$1" # not needed + local value="$2" + + # topics is inherited from main() via opt_parse() + topics+=("$value") + return 0 +} + +signal_handler() { + signal_received=1 +} + +tap_topics() { + local topics=("$@") + + local endpoint + local topic + local -i err + local -ig signal_received + + err=0 + signal_received=0 + + if ! endpoint=$(ipc_endpoint_open); then + return 1 + fi + + log_info "Using endpoint $endpoint" + trap signal_handler INT HUP TERM ABRT ALRM USR1 USR2 PIPE + + for topic in "${topics[@]}"; do + log_info "Subscribing $endpoint to $topic" + + if ! ipc_endpoint_subscribe "$endpoint" "$topic"; then + log_error "Could not subscribe $endpoint to $topic" + err=1 + break + fi + done + + if (( err == 0 )); then + log_info "Waiting for messages" + + while (( signal_received == 0 )); do + local message + + if message=$(ipc_endpoint_recv "$endpoint" 5); then + printf '%s\n' "$message" + fi + done + fi + + log_info "Closing endpoint $endpoint" + ipc_endpoint_close "$endpoint" + + return "$err" +} + +main() { + local topics + + topics=() + + opt_add_arg "t" "topic" "rv" "" "A topic to tap into" "" add_topic + + if ! opt_parse "$@"; then + return 1 + fi + + if ! tap_topics "${topics[@]}"; then + return 1 + fi + + return 0 +} + +{ + if ! . toolbox.sh; then + exit 1 + fi + + if ! include "log" "opt" "ipc"; then + exit 1 + fi + + main "$@" + exit "$?" +} -- 2.47.3