#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # # asrc-server.py # # Copyright 2012 - 2013 Fanir-Thuban # # 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 2 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # # # aSRC (Aliased Server Remote Control) # - SERVER - # # program version: 0.0.0.20130422 # protocol version: 0.2.20130422 # # import sys, os, socket, socketserver, threading, time class ThreadedRequestHandler(socketserver.StreamRequestHandler): def handle(self): # Set time for timeout in seconds self.timeout = TIMEOUT # Print a line with the adress of the connected client if DEBUGLEVEL >=3: print("Client connected: " + str(self.client_address)) # Send MOTD self.request.sendall(bytes(motd + "\r\n", ENCODING)) # Receive data self.data = str(self.rfile.readline().strip(), ENCODING) # Look if the received message is an # valid alias or a predefined command # if it's 'version', return the server and protocol version if self.data == "version": if DEBUGLEVEL >= 2: print("Got valid service command from" + str(self.client_address) + ": ", self.data) # send status code self.request.sendall(bytes("000 Received 'version'", ENCODING)) # send response self.request.sendall(bytes( "Server: " + ServerVersion + "\r\n"\ "Protocol: " + ProtocolVersion + "\r\n", ENCODING)) # if it's 'help', give a little help elif self.data == 'help': if DEBUGLEVEL >= 2: print("Got valid command from" + str(self.client_address) + ": ", self.data) # send status code self.request.sendall(bytes("000 Received 'help'", ENCODING)) # send the list of aliases self.request.sendall(bytes("Aviable aliases:\r\n", ENCODING)) for i in aliases.keys(): self.request.sendall(bytes(str(i) + "\r\n", ENCODING)) self.request.sendall(bytes("\r\n", ENCODING)) # if it's a valid userdefined command elif self.data in aliases: # send status code self.request.sendall(bytes( "<<:0x0130:Received valid command\r\n", ENCODING)) # ohmagawd! a debug message!!1! if DEBUGLEVEL >= 2: print("Got valid command from" + str(self.client_address) + ": ", self.data) # execute the aliased command g_dict, l_dict = {}, {} exec(str(aliases[self.data]), g_dict, l_dict) # send may contain data to send to the client if l_dict["send"]: self.request.sendall(bytes(str( l_dict["send"]) + "\r\n", ENCODING)) else: self.request.sendall(bytes("\r\n", ENCODING)) # ALL IS LOST!!1! this have to be invalid! else: # send status code self.request.sendall(bytes( "<<:0x0230:Received invalid command\r\n", ENCODING)) if DEBUGLEVEL >= 2: print("Got invalid command from", str(self.client_address), ": ", self.data) class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass def main(): print("aSRC Server\r\n"\ "Server version: " + ServerVersion + "\r\n"\ "Protocol version: " + ProtocolVersion + "\r\n\r\n"\ "To stop the server, press Ctrl-C\r\n") try: if DEBUGLEVEL >= 1: print("Initializing server...") # Create server server = ThreadedTCPServer((HOST, PORT), ThreadedRequestHandler) if DEBUGLEVEL >= 1: print("Starting server on", server.server_address[0], "port", server.server_address[1], "...") # Start a thread with the server -- that thread will then start one # more thread for each request ServerThread = threading.Thread(target = server.serve_forever) # Exit the server thread when the main thread terminates ServerThread.daemon = True ServerThread.start() while True: time.sleep(10) except KeyboardInterrupt: print("\r\nGot Ctrl-C, shutting down server...") try: server.shutdown() except: print("Failed to shutdown server correctly, "\ "socket may be still in use or wasn't even started:", sys.exc_info()) except: print("\r\nAn error occured:\r\n", sys.exc_info(), "\r\n") if DEBUGLEVEL >= 3: input("Press Enter to continue\r\n") return 0 if __name__ == '__main__': ServerVersion = "0.0.0" ProtocolVersion = "0.0.0" ############## # SETTINGS # ############## # IP or hostname (use 0.0.0.0 for all interfaces) and port, on which # the server should listen HOST = '127.0.0.1' PORT = 24642 # Timeout of a connection in seconds - obviously still doesn't work... TIMEOUT = 4 # Encoding to be used when communicating with a client ENCODING = 'utf-8' # Dictionary of aliases. Use python syntax. You can use # the variable send for text to send to the client. # # Shell commands can be executed with: # import subprocess # send = subprocess.check_output(["command", "arg", "somemorearg"]) # # You don't have to include sys, os, socket, socketserver, # threading and time, through they are included already. aliases = dict( who = ''' import subprocess send = subprocess.check_output(["whoami"]) ''', where = ''' import subprocess send = subprocess.check_output(["pwd"]) ''', uname = ''' import os send = os.uname() ''', date = ''' import subprocess send = subprocess.check_output(["date"]) ''', ping_fanir = ''' import subprocess send = subprocess.check_output(["ping", "-c 2", "fanir.de"]) ''') # This is sent to the client after the connection is established motd = "Welcome! This is only a test server, for developing purposes.\r\n"\ "Here (may) be more text..." # Verbosity of logging. # Can be from 0 (only default output) to 3 (debug messages) DEBUGLEVEL = 3 ############## main()