Пример #1
0
 def shutdown(self):
     """ Shutdown minestorm server """
     logging.getLogger('minestorm').info('Shutting down minestorm...')
     minestorm.get('server.networking').stop(
     )  # Stop the networking and close the port
     minestorm.get('server.servers').stop_all()  # Stop all servers
     logging.getLogger('minestorm').info('Waiting for threads shutdown...')
Пример #2
0
 def boot_3_requests(self):
     """ Boot the requests parser """
     # Setup the resource
     validator = lambda resource: resource.name != '__base__'
     minestorm.get('resources').add('server.request_processors',
                                    subclass_of = minestorm.server.requests.BaseProcessor,
                                    name_attribute = 'name',
                                    validator = validator )
     # Create the sorter
     manager = minestorm.server.requests.RequestSorter()
     minestorm.bind('server.requests', manager)
     # Register differend requests
     manager.register( minestorm.server.requests.PingProcessor() )
     manager.register( minestorm.server.requests.NewSessionProcessor() )
     manager.register( minestorm.server.requests.RemoveSessionProcessor() )
     manager.register( minestorm.server.requests.StartServerProcessor() )
     manager.register( minestorm.server.requests.StopServerProcessor() )
     manager.register( minestorm.server.requests.StartAllServersProcessor() )
     manager.register( minestorm.server.requests.StopAllServersProcessor() )
     manager.register( minestorm.server.requests.CommandProcessor() )
     manager.register( minestorm.server.requests.StatusProcessor() )
     manager.register( minestorm.server.requests.RetrieveLinesProcessor() )
     # Listen for events
     listener = lambda event: manager.sort(event.data['request'])
     minestorm.get('events').listen('server.networking.request_received', listener, 100)
Пример #3
0
 def retrieve_lines(self, start, stop):
     """ Retrieve a specified amount of lines """
     # Raise an error if the server is not running
     if self.status not in ("STARTING", "STARTED", "STOPPING"):
         raise SyncError("Unable to retrieve lines when the server is not running!")
     # Retrieve lines
     response = minestorm.get("console.networking").request(
         {
             "status": "retrieve_lines",
             "start": start,
             "stop": stop,
             "server": self.name,
             "sid": minestorm.get("console.networking").sid,
         }
     )
     # Raise an exception if lines are not provided
     if response["status"] != "retrieve_lines_response":
         raise SyncError("Unable to retrieve lines")
     # Iterate over lines to check them and add to the lines list
     for identifier, line in response["lines"].items():
         identifier = int(identifier)  # Convert the identifier to the correct type
         # First check if the line was already downloaded
         if identifier in self._lines:
             continue
         self._lines[identifier] = line
         # Update the last line identifier if it greater than the actual one
         if identifier > self._last_line_identifier:
             self._last_line_identifier = identifier
Пример #4
0
 def execute(self, arguments):
     # Try to switch server
     if arguments[0] in minestorm.get('console.servers').all():
         minestorm.get('console.ui').focus = arguments[0]
         return 'Server switched'
     else:
         return 'Unknow server'
Пример #5
0
 def process(self, request):
     try:
         minestorm.get('server.servers').start_all()
     except RuntimeError:
         request.reply({ 'status': 'failed', 'reason': str(e) })
     else:
         request.reply({'status': 'ok'})
Пример #6
0
 def _load_configuration(self, file_name):
     """ Handler for the -c option """
     # If the path exists load it
     if os.path.exists(file_name):
         minestorm.get('configuration').load(file_name)
     else:
         print('Error: configuration file not found: {}'.format(file_name))
         minestorm.shutdown()
Пример #7
0
 def process(self, request):
     try:
         minestorm.get('server.servers').get( request.data['server'] ).start()
     except NameError:
         request.reply({ 'status': 'failed', 'reason': 'Server {} does not exist'.format(request.data['server']) })
     except RuntimeError as e:
         request.reply({ 'status': 'failed', 'reason': str(e) })
     else:
         request.reply({'status':'ok'})
Пример #8
0
 def process(self, request):
     # Get the stop message
     stop_message = request.data['message'] if 'message' in request.data else None
     try:
         minestorm.get('server.servers').stop_all(stop_message)
     except RuntimeError:
         request.reply({ 'status': 'failed', 'reason': str(e) })
     else:
         request.reply({'status': 'ok'})
Пример #9
0
 def boot_2_networking(self):
     """ Boot the networking """
     # Create events
     minestorm.get('events').create('server.networking.request_received')
     # Boot the networking
     manager = minestorm.server.networking.Listener()
     minestorm.bind('server.networking', manager)
     # Bind the console port
     manager.bind( minestorm.get('configuration').get('networking.port') )
Пример #10
0
 def run(self, args):
     try:
         console = minestorm.console.MinestormConsole()
         if args.server:
             if args.server in minestorm.get('console.servers').all():
                 minestorm.get('console.ui').focus = args.server
         console.start()
     finally:
         curses.endwin()
Пример #11
0
 def process(self, request):
     # Get the stop message
     stop_message = request.data['message'] if 'message' in request.data else None
     try:
         minestorm.get('server.servers').get( request.data['server'] ).stop(stop_message)
     except NameError:
         request.reply({ 'status': 'failed', 'reason': 'Server {} does not exist'.format(request.data['server']) })
     except RuntimeError as e:
         request.reply({ 'status': 'failed', 'reason': str(e) })
     else:
         request.reply({'status':'ok'})
Пример #12
0
 def process(self, request):
     start, stop = int(request.data['start']), int(request.data['stop'])
     # Check if the server exists
     if request.data['server'] in minestorm.get('server.servers').servers:
         # Get requested lines
         lines = minestorm.get('server.servers').get( request.data['server'] ).retrieve_lines( start, stop )
         # Build response
         result = { 'status': 'retrieve_lines_response' }
         result['lines'] = lines
         request.reply(result)
     else:
         request.reply({ 'status': 'failed', 'reason': 'Invalid server' })
Пример #13
0
 def _render_server(self, line, name):
     """ Render a single server """
     server = minestorm.get('console.servers').get(name)
     # Get the bullet colour
     if server.status in ('STARTING', 'STARTED', 'STOPPING'):
         bullet_colour = self.colours['green'] | curses.A_BOLD
     else:
         bullet_colour = self.colours['red'] | curses.A_BOLD
     # Render!
     if minestorm.get('console.ui').focus == name:
         self.component.addstr(line, 1, '>', self.colours['blue'] | curses.A_BOLD)
     self.component.addstr(line, 3, name)
     self.component.addstr(line, self.width-2, '⚫', bullet_colour)
Пример #14
0
 def _update_boxes(self):
     """ Update boxes """
     boxes = [( "RAM", "-" ), ( "Uptime", "-" )]
     focus = minestorm.get("console.ui").focus
     if focus:
         server = minestorm.get("console.servers").get(focus)
         if server.status in ('STARTING', 'STARTED', 'STOPPING'):
             ram = str(round(server.ram_used, 2))+"%"
             uptime = minestorm.common.seconds_to_string(round(server.uptime))
             boxes = [( "RAM", ram ), ( "Uptime", uptime )]
     line = 1
     for key, value in boxes:
         self._render_box(line, key, value)
         line += 1
Пример #15
0
 def process(self, request):
     # If the passed server exists pick it
     if 'server' in request.data and request.data['server'] in minestorm.get('server.servers').servers:
         server = minestorm.get('server.servers').get(request.data['server'])
     # Else return an error
     else:
         request.reply({ 'status': 'failed', 'reason': 'Please specify a valid server' })
         return
     # Execute the command only if the server is running
     if server.status == server.STATUS_STARTED:
         server.command( request.data['command'] ) # Execute the command
         request.reply({ 'status': 'ok' })
     else:
         request.reply({ 'status': 'failed', 'reason': 'Server {} is not running'.format(server.details['name']) })
Пример #16
0
 def _process(self, request):
     """ Procesor entry point """
     # Check if sid is required but not passed
     if self.require_sid and 'sid' not in request.data:
         request.reply({'status': 'failed', 'reason': 'SID not provided'})
     # Check if the sid is required but invalid (badly formatted or expired or never created)
     elif self.require_sid and not minestorm.get('server.sessions').is_valid( request.data['sid'] ):
         request.reply({'status': 'failed', 'reason': 'Invalid SID'})
     else:
         # If a SID was provided, touch the relative session
         # to avoid expiration of it
         if 'sid' in request.data and minestorm.get('server.sessions').is_valid( request.data['sid'] ):
             minestorm.get('server.sessions').get( request.data['sid'] ).touch()
         self.process(request)
Пример #17
0
 def update(self):
     """ Update the screen """
     focus = minestorm.get('console.ui').focus
     if focus:
         lines = list( minestorm.get('console.servers').get( focus ).all_lines().values() )
     else:
         lines = []
     self.position = len(lines) # temp fix
     max_lines = self.height
     # If the number of lines is lower than the max number of lines
     # display all of them
     # Else display only the desidered chunk
     if ( len(lines) < max_lines ) or self.position-max_lines < 0:
         chunk = lines
     else:
         chunk = lines[ (self.position-max_lines) : self.position ]
     # Split lines into small parts
     # Needed to avoid lines truncating
     new_chunk = []
     for line in chunk:
         # If the length of the line is greater than the screen size
         # split the line
         if len(line) > (self.width - 1):
             position = 0
             while 1:
                 position_max = position + self.width - 1
                 # If the expected part of the line is lower than the
                 # total line length add the remaining part and break
                 # the loop
                 if position_max > len(line):
                     new_chunk.append( line[ position: ] )
                     break
                 # Else add the expected part
                 else:
                     new_chunk.append( line[ position:position_max ] )
                     position += self.width - 1
         # If the line length is lower than the stream width
         # simply add it
         else:
             new_chunk.append( line )
     # Now get only the last part of the chunk
     chunk = new_chunk[ :max_lines ]
     # Display the chunk
     i = 0
     for line in chunk:
         self.erase(i)
         self.component.addstr(i, 0, line, self.colours['white']) # Add the line
         i += 1
     self.refresh() # Refresh the screen
Пример #18
0
 def _init_commands(self):
     """ Initialize the console manager """
     # Setup the resource
     validator = lambda resource: resource.name != "__base__"
     minestorm.get("resources").add(
         "console.commands",
         subclass_of=minestorm.console.commands.Command,
         name_attribute="name",
         validator=validator,
     )
     # Setup the manager
     commands = minestorm.console.commands.CommandsManager()
     commands.register(minestorm.console.commands.SwitchCommand())
     commands.register(minestorm.console.commands.StartCommand())
     commands.register(minestorm.console.commands.StopCommand())
     minestorm.bind("console.commands", commands)
Пример #19
0
 def boot_4_servers(self):
     """ Boot the servers manager """
     manager = minestorm.server.servers.ServersManager()
     minestorm.bind('server.servers', manager)
     # Register all servers
     for section in minestorm.get('configuration').get('available_servers'):
         manager.register( section ) # Register the server
Пример #20
0
 def execute(self, arguments):
     # Try to start the server
     result = minestorm.get('console.networking').request({'status': 'start_server', 'server': arguments[0], 'sid': minestorm.get('console.networking').sid })
     if result['status'] == 'ok':
         return 'Server started'
     elif result['status'] == 'failed':
         return result['reason']
     else:
         return 'Unknow reply from minestorm'
Пример #21
0
 def listen_keys(self, key):
     """ Listen for keys """
     if key == curses.KEY_BACKSPACE:
         # Don't remove the last character if the content is empty
         if self.content != "":
             before_part = self.content[:(self.cursor_position-1)]
             after_part = self.content[self.cursor_position:]
             self.content = before_part + after_part
             self.cursor_position -= 1
             self.erase(0)
     elif key == 10: # Enter key
         if self.content != "":
             # It the command starts with "!", it's a console command
             if self.content[0] == "!":
                 # Execute the command
                 result = minestorm.get("console.commands").route( self.content )
                 if result:
                     # If the command returned a result, display it
                     minestorm.get("console.ui").infobar.message(result)
             else:
                 # Send command to the backend
                 sid = minestorm.get("console.networking").sid
                 try:
                     response = minestorm.get("console.networking").request({ 'status': 'command', 'server': minestorm.get("console.ui").focus, 'command': self.content, 'sid': sid })
                 except Exception as e:
                     # If an exception occured display it in the infobar
                     minestorm.get("console.ui").infobar.message("Exception: {!s}".format(e))
                 # If the request failed and a reason is returned display it
                 if response['status'] == 'failed' and 'reason' in response:
                     minestorm.get("console.ui").infobar.message(response['reason'])
         self.content = ""
         self.cursor_position = 0
         self.erase(0)
     # Move the cursor back
     elif key == curses.KEY_LEFT:
         if self.cursor_position > 0:
             self.cursor_position -= 1
     # Move the cursor forward
     elif key == curses.KEY_RIGHT:
         if self.cursor_position < len(self.content):
             self.cursor_position += 1
     elif key <= 255:
         before_part = self.content[:self.cursor_position]
         after_part = self.content[self.cursor_position:]
         self.content = before_part+chr(key)+after_part
         self.cursor_position += 1 # Move the cursor
     self.screen.screen.addstr(self.start_y, 0, self.content, self.colours['white'])
     self.screen.screen.move(self.start_y, self.cursor_position)
     self.refresh()
Пример #22
0
 def boot_1_cli(self):
     """ Boot the cli """
     # Setup the resource
     validator = lambda resource: resource.name != '__base__'
     minestorm.get('resources').add('cli.commands',
                                    subclass_of = minestorm.cli.Command,
                                    name_attribute = 'name',
                                    validator = validator )
     # Setup the manager
     manager = minestorm.cli.CommandsManager()
     minestorm.bind("cli", manager)
     # Register commands
     manager.register( minestorm.cli.ExecuteCommand() )
     manager.register( minestorm.cli.StartCommand() )
     manager.register( minestorm.cli.StopCommand() )
     manager.register( minestorm.cli.StartAllCommand() )
     manager.register( minestorm.cli.StopAllCommand() )
     manager.register( minestorm.cli.CommandCommand() )
     manager.register( minestorm.cli.ConsoleCommand() )
     manager.register( minestorm.cli.StatusCommand() )
     manager.register( minestorm.cli.TestCommand() )
     manager.register( minestorm.cli.ConfigureCommand() )
Пример #23
0
 def is_valid(self, sid):
     """ Check if a SID is valid """
     # Get the expiration time
     expire_at = time.time() - minestorm.get('configuration').get('sessions.expiration.time')
     # First check if the SID exists
     if sid in self.sessions:
         # Now check if it isn't expired
         if self.sessions[sid].last_packet > expire_at:
             return True
         else:
             return False
     else:
         return False
Пример #24
0
 def sync(self):
     """ Sync local copies of the servers objects with the backend """
     new_servers = set()  # Set of new servers
     response = minestorm.get("console.networking").request(
         {"status": "status", "sid": minestorm.get("console.networking").sid}
     )
     # Raise an exception if the servers list was not provided
     if response["status"] != "status_response":
         raise SyncError("Unable to get servers list")
     # Iterate over received servers to
     for name, informations in response["servers"].items():
         new_servers.add(name)  # Append the server name to the synched servers list
         # If the server wasn't loaded create it
         if name not in self._servers:
             self._servers[name] = Server(name)
         # Update server informations
         self._servers[name].update(informations)
     # If there are servers in the servers list not present in the status
     # remove them
     diff = set(self._servers.keys()) - new_servers
     if len(diff) > 0:
         for server in diff:
             del self._servers[name]
Пример #25
0
 def boot_1_logging(self):
     """ Boot the logging system """
     logger = logging.getLogger('minestorm')
     # Get the logging level
     level = getattr( logging, str(minestorm.get('configuration').get('logging.level')).upper() )
     logger.setLevel( level )
     # Prepare the formatter
     formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
     # Set the stream handler
     stream = logging.StreamHandler()
     stream.setLevel( level )
     stream.setFormatter( formatter )
     # Register all
     logger.addHandler( stream )
Пример #26
0
 def run(self):
     while not self.stop:
         minestorm.get("console.servers").sync()  # Sync the local cache
         # Retrieve last lines
         for server in minestorm.get("console.servers").all().values():
             try:
                 server.retrieve_last_lines()
             except SyncError:
                 pass
         # Update the UI
         minestorm.get("console.ui").sidebar.update()  # Update the sidebar
         minestorm.get("console.ui").stream.update()  # Update the stream
         time.sleep(0.5)
Пример #27
0
 def run(self, args):
     # Get the content of the default file bundled with setuptools
     content = pkg_resources.resource_string('minestorm', '_samples/configuration.json').decode('utf-8')
     # Get the destination directory
     destination = minestorm.get('configuration').default_file_path()
     # Copy it to its destination
     if not os.path.exists(destination):
         # Create base directories if needed
         os.makedirs( os.path.dirname(destination), exist_ok=True)
         # Save the configuration file
         with open(destination, 'w') as f:
             f.write(content)
         print('The minestorm configuration file is now at {}'.format(destination))
     else:
         print('Error: minestorm: a file already exists at {}'.format(destination))
Пример #28
0
 def _update_server_list(self):
     """ Update the server list """
     servers_list = minestorm.get('console.servers').all()
     if len(servers_list) > 0:
         top = self.height-len(servers_list)-2 # Calculate the top line
     else:
         top = self.height-3
     self.component.addstr(top, 3, 'Available servers:', curses.A_BOLD)
     # Get servers list
     servers = list(servers_list.keys())
     servers.sort()
     servers.sort(key=lambda s: servers_list[s].status in ('STARTING', 'STARTED', 'STOPPING'), reverse=True)
     # Render each server
     if len(servers_list) > 0:
         i = 1
         for server in servers:
             self._render_server(top+i, server )
             i += 1
     else:
         self.component.addstr(top+1, 3, "No server available")
Пример #29
0
 def request(self, data):
     """ Make a request to the server """
     try:
         # Create a new socket
         s = socket.socket()
         s.connect(( socket.gethostname(), minestorm.get('configuration').get('networking.port') ))
         # Prepare data
         to_send = json.dumps(data).encode('utf-8')
         length = struct.pack('I', len(to_send))
         # Send the request
         minestorm.common.send_packet(s, length)
         minestorm.common.send_packet(s, to_send)
         # Receive response
         length = struct.unpack('I', minestorm.common.receive_packet( s, 4 ))[0]
         raw = minestorm.common.receive_packet( s, length )
         # Load the response
         response = json.loads(raw.decode('utf-8'))
         # Shutdown the socket
         s.shutdown(socket.SHUT_RD)
         s.close()
         return response
     except socket.error:
         return
Пример #30
0
 def start(self):
     """ Start minestorm server """
     minestorm.get('server.networking').listen()