summaryrefslogtreecommitdiff |
diff options
-rwxr-xr-x | jabberhive-two-way-replace.py | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/jabberhive-two-way-replace.py b/jabberhive-two-way-replace.py new file mode 100755 index 0000000..af4aed3 --- /dev/null +++ b/jabberhive-two-way-replace.py @@ -0,0 +1,168 @@ +#!/bin/env python3 +import argparse +import re +import sys + +import socket +import _thread + +replacements = [ + ["!", " !"], + ["?", " ?"], + [".", " ."], + [",", " ,"], + [":", " :"], + [";", " ;"], + [")", " )"], + ["(", "( "], + [">", " >"], + ["<", "< "], + ["]", " ]"], + ["[", "[ "], + ["}", " }"], + ["{", "{ "], +] + +class ClientState: + CLIENT_IS_SENDING_DOWNSTREAM = 1 + CLIENT_IS_SENDING_UPSTREAM = 2 + CLIENT_IS_CONNECTING = 3 + CLIENT_IS_TERMINATING = 4 + +def replace_client_to_server (string): + prefix_size = (string.find(' ') + 1) + prefix = string[:prefix_size] + content = string[prefix_size:] + + for entry in replacements: + content = content.replace(entry[0], entry[1]) + + return (prefix + content) + +def replace_server_to_client (string): + prefix_size = (string.find(' ') + 1) + prefix = string[:prefix_size] + content = string[prefix_size:] + + for entry in replacements: + content = content.replace(entry[1], entry[0]) + + return (prefix + content) + +def client_main (source, params): + state = ClientState.CLIENT_IS_CONNECTING + connect = None + + try: + while True: + if (state == ClientState.CLIENT_IS_SENDING_DOWNSTREAM): + try: + in_data = b"" + + while True: + in_char = source.recv(1) + in_data = (in_data + in_char) + + if (in_char == b"\n"): + break + elif (in_char == b''): + raise Exception("Disconnected client") + + up_data = in_data.decode("UTF-8") + valid = 1 + except UnicodeDecodeError: + print("Could not decode UTF-8...") + valid = 0 + + if (valid == 1): + up_data = replace_client_to_server(up_data) + connect.sendall(up_data.encode("UTF-8")) + state = ClientState.CLIENT_IS_SENDING_UPSTREAM + else: + connect.sendall(in_data) + state = ClientState.CLIENT_IS_SENDING_UPSTREAM + elif (state == ClientState.CLIENT_IS_SENDING_UPSTREAM): + in_data = b"" + matched = 0 + c = b"\0" + + try: + while True: + in_char = connect.recv(1) + in_data = (in_data + in_char) + + if (in_char == b"\n"): + break + elif (in_char == b''): + raise Exception("Disconnected server") + + + if ((in_data == b"!P \n") or (in_data == b"!N \n")): + print("Sending downstream without touching...") + state = ClientState.CLIENT_IS_SENDING_DOWNSTREAM + elif ((in_data.startswith(b"!GR "))): + print("Sending downstream, after checking...") + up_data = in_data.decode("UTF-8") + up_data = replace_server_to_client(up_data) + in_data = up_data.encode("UTF-8") + + except UnicodeDecodeError: + print("Could not decode UTF-8...") + + source.sendall(in_data) + + + elif (state == ClientState.CLIENT_IS_CONNECTING): + print("Connecting to downstream...") + connect = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + connect.connect(params.destination) + + print("Sending downstream...") + state = ClientState.CLIENT_IS_SENDING_DOWNSTREAM + else: + break + except: + print("Unexpected error:", sys.exc_info()) + print("Closing") + source.close() + connect.close() + +################################################################################ +## ARGUMENTS HANDLING ########################################################## +################################################################################ + +parser = argparse.ArgumentParser( + description = ( + "Performs replacements both ways" + ) +) + +parser.add_argument( + '-s', + '--socket-name', + type = str, + required = True, + help = 'Name of the UNIX socket for this filter.' +) + +parser.add_argument( + '-d', + '--destination', + type = str, + help = 'UNIX socket this filter sends to when a match is found.', +) + +args = parser.parse_args() + +################################################################################ +## MAIN ######################################################################## +################################################################################ +server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + +server_socket.bind(args.socket_name) +server_socket.listen(5) + +while True: + (client, client_address) = server_socket.accept() + _thread.start_new_thread(client_main, (client, args)) + |