This repository has been archived by the owner on Jun 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #31 from FCG-LLC/feature/aucote_status
Add REST API to the Aucote
- Loading branch information
Showing
51 changed files
with
1,163 additions
and
186 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
""" | ||
Handler abstract class | ||
""" | ||
import hashlib | ||
|
||
from tornado.web import RequestHandler | ||
|
||
from aucote_cfg import cfg | ||
|
||
|
||
class Handler(RequestHandler): | ||
""" | ||
Defines common properties for handler | ||
""" | ||
def initialize(self, aucote): | ||
""" | ||
Integrates Handlers with aucote | ||
Args: | ||
aucote (Aucote): | ||
Returns: | ||
None | ||
""" | ||
self.aucote = aucote | ||
|
||
@staticmethod | ||
def auth(handler_class): | ||
""" | ||
Handler for authorization | ||
Args: | ||
handler_class: | ||
Returns: | ||
""" | ||
def wrap_execute(handler_execute): | ||
def require_auth(handler, kwargs): | ||
auth_header = handler.request.headers.get('Authorization') | ||
|
||
if auth_header is None or not auth_header.startswith('Bearer '): | ||
handler.set_status(401) | ||
handler._transforms = [] | ||
handler.finish() | ||
return False | ||
|
||
password = auth_header[7:] | ||
hash = hashlib.sha512(password.encode()).hexdigest() | ||
correct = cfg.get('service.api.password') | ||
|
||
if hash != correct: | ||
handler.set_status(401) | ||
handler._transforms = [] | ||
handler.finish() | ||
return False | ||
|
||
return True | ||
|
||
def _execute(self, transforms, *args, **kwargs): | ||
if not require_auth(self, kwargs): | ||
return False | ||
return handler_execute(self, transforms, *args, **kwargs) | ||
|
||
return _execute | ||
|
||
handler_class._execute = wrap_execute(handler_class._execute) | ||
return handler_class |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
""" | ||
Handler responsible for exit aucote application immediately | ||
""" | ||
import hashlib | ||
|
||
from api.handler import Handler | ||
from aucote_cfg import cfg | ||
|
||
@Handler.auth | ||
class KillHandler(Handler): | ||
""" | ||
Kills aucote | ||
""" | ||
def post(self): | ||
""" | ||
Kills aucote. Require password POST argument | ||
Returns: | ||
None - kill application | ||
""" | ||
|
||
self.aucote.kill() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
""" | ||
Handler responsible for returning status of aucote | ||
""" | ||
import time | ||
|
||
from api.handler import Handler | ||
from aucote_cfg import cfg | ||
from scans.executor import Executor | ||
from tools.base import Tool | ||
from tools.common.port_task import PortTask | ||
from utils.task import Task | ||
|
||
|
||
class MainHandler(Handler): | ||
""" | ||
Handler responsible for returning status of aucote | ||
""" | ||
def get(self): | ||
""" | ||
Handle get method and returns aucote status in JSON | ||
Returns: | ||
None - writes aucote status in JSON | ||
""" | ||
self.write(self.aucote_status()) | ||
|
||
def aucote_status(self): | ||
""" | ||
Get current status of aucote tasks | ||
Returns: | ||
dict | ||
""" | ||
stats = self.thread_pool_status(self.aucote.thread_pool) | ||
stats['scanner'] = self.scanning_status(self.aucote.scan_thread) | ||
stats['meta'] = self.metadata() | ||
return stats | ||
|
||
@classmethod | ||
def metadata(cls): | ||
""" | ||
Meta of API request | ||
Returns: | ||
dict | ||
""" | ||
return { | ||
'timestamp': time.time() | ||
} | ||
|
||
@classmethod | ||
def scanning_status(cls, scan_thread): | ||
""" | ||
Information about scan | ||
Args: | ||
scan_thread (ScanThread): | ||
Returns: | ||
dict | ||
""" | ||
return { | ||
'nodes': [str(node.ip) for node in scan_thread.current_scan], | ||
'scheduler': [cls.scheduler_task_status(task) for task in scan_thread.tasks], | ||
'networks': cfg.get('service.scans.networks').cfg, | ||
'ports': cfg.get('service.scans.ports'), | ||
'previous_scan': scan_thread.previous_scan | ||
} | ||
|
||
@classmethod | ||
def scheduler_task_status(cls, task): | ||
""" | ||
Returns information about schedulers task | ||
Args: | ||
task : named tuple representing scheduler task | ||
Returns: | ||
dict | ||
""" | ||
return { | ||
'action': task.action.__name__, | ||
'time': task.time | ||
} | ||
|
||
@classmethod | ||
def thread_pool_status(cls, thread_pool): | ||
""" | ||
Obtain status of thread pool | ||
Args: | ||
thread_pool (ThreadPool): | ||
Returns: | ||
dict | ||
""" | ||
return_value = {'queue': [], 'threads': []} | ||
|
||
for thread in thread_pool.threads: | ||
return_value['threads'].append(cls.thread_pool_thread_status(thread)) | ||
|
||
for task in thread_pool.task_queue: | ||
return_value['queue'].append(cls.task_status(task)) | ||
|
||
return_value['threads_limit'] = thread_pool.num_threads | ||
|
||
return return_value | ||
|
||
@classmethod | ||
def thread_pool_thread_status(cls, thread): | ||
""" | ||
Returns dict with info about thread | ||
Args: | ||
thread(Thread): | ||
Returns: | ||
dict | ||
""" | ||
task = thread.task | ||
if task is None: | ||
return {} | ||
|
||
return_value = cls.task_status(thread.task) | ||
|
||
return return_value | ||
|
||
@classmethod | ||
def task_status(cls, task): | ||
""" | ||
Returns information about task | ||
Args: | ||
task (Task): | ||
Returns: | ||
dict | ||
""" | ||
return_value = {} | ||
|
||
if isinstance(task, Task): | ||
return_value['start_time'] = task.start_time | ||
return_value['creation_time'] = task.creation_time | ||
return_value['name'] = task.name | ||
|
||
if isinstance(task, (Tool, PortTask)): | ||
return_value['port'] = str(task.port) | ||
|
||
if isinstance(task, Executor): | ||
return_value['nodes'] = [str(node) for node in task.ports] | ||
|
||
if isinstance(task, PortTask): | ||
return_value['exploits'] = [exploit.name for exploit in task.current_exploits] | ||
|
||
return return_value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
pyaml | ||
argparse | ||
nanomsg | ||
netaddr | ||
pyaml==15.8.2 | ||
nanomsg==1.0 | ||
netaddr==0.7.18 | ||
python-dateutil | ||
netifaces | ||
requests | ||
croniter | ||
pytz | ||
inotify | ||
netifaces==0.10.5 | ||
requests==2.11.1 | ||
croniter==0.3.13 | ||
pytz==2016.10 | ||
inotify==0.2.8 | ||
tornado==4.4.2 |
Oops, something went wrong.