Skip to content
This repository has been archived by the owner on Mar 15, 2019. It is now read-only.

Commit

Permalink
allow dropping config url as file to ease deployments
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnykv committed Jul 25, 2014
1 parent 422dcac commit 74974ea
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
31 changes: 27 additions & 4 deletions beeswarm/drones/drone.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from zmq.utils.monitor import recv_monitor_message

from beeswarm.shared.message_enum import Messages
from beeswarm.shared.helpers import extract_keys, send_zmq_push
from beeswarm.shared.helpers import extract_keys, send_zmq_push, extract_config_from_api, asciify
from beeswarm.drones.honeypot.honeypot import Honeypot
from beeswarm.drones.client.client import Client

Expand Down Expand Up @@ -60,6 +60,8 @@ def __init__(self, work_dir, config, key='server.key', cert='server.crt', **kwar
self.outgoing_msg_greenlet = None
self.incoming_msg_greenlet = None

self.config_url_dropper_greenlet = None

# messages from server relayed to internal listeners
ctx = zmq.Context()
self.internal_server_relay = ctx.socket(zmq.PUSH)
Expand Down Expand Up @@ -94,13 +96,19 @@ def start(self):
self.incoming_msg_greenlet = gevent.spawn(self.incoming_server_comms, server_public,
client_public, client_secret)

self.config_url_dropper_greenlet = gevent.spawn(self.config_url_drop_poller)

logger.info('Waiting for detailed configuration from Beeswarm server.')
gevent.joinall([self.outgoing_msg_greenlet])

def _start_drone(self):
"""
Tears down the drone and restarts it.
Restarts the drone
"""

with open('beeswarmcfg.json', 'r') as config_file:
self.config = json.load(config_file, object_hook=asciify)

mode = None
if self.config['general']['mode'] == '' or self.config['general']['mode'] == None:
logger.info('Drone has not been configured, awaiting configuration from Beeswarm server.')
Expand All @@ -119,6 +127,7 @@ def stop(self):
logging.debug('Stopping drone, hang on.')
if self.drone is not None:
self.drone.stop()
self.drone = None
# just some time for the drone to powerdown to be nice.
gevent.sleep(2)
if self.drone_greenlet is not None:
Expand Down Expand Up @@ -167,9 +176,9 @@ def incoming_server_comms(self, server_public, client_public, client_secret):
# if we receive a configuration we restart the drone
if command == Messages.CONFIG:
self.config_received.set()
self.config = json.loads(data)
config = json.loads(data)
with open('beeswarmcfg.json', 'w') as local_config:
local_config.write(json.dumps(self.config, indent=4))
local_config.write(json.dumps(config, indent=4))
self.stop()
self._start_drone()
else:
Expand Down Expand Up @@ -245,5 +254,19 @@ def monitor_worker(self, monitor_socket, log_name):
logger.warning('Disconnected from {0}, will reconnect in {1} seconds.'.format(log_name, 5))
gevent.sleep()

# restarts the drone if a new file containing a new config url is dropped in the workdir
def config_url_drop_poller(self):
while True:
gevent.sleep(1)
dropped_config_url_file = os.path.join(self.work_dir, 'API_CONFIG_URL')
if os.path.isfile(dropped_config_url_file):
with open(dropped_config_url_file,'r') as _file:
config_url = open(_file).read()
logger.info('Found dropped api config url in {0}, with content: {1}.'.format(self.work_dir, config_url))
os.remove(dropped_config_url_file)
extract_config_from_api(config_url)
self.stop()
self._start_drone()



11 changes: 11 additions & 0 deletions beeswarm/shared/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
from OpenSSL import crypto
import zmq.green as zmq
import gevent
import requests
from beeswarm.shared.asciify import asciify

from beeswarm.shared.message_enum import Messages

Expand Down Expand Up @@ -215,3 +217,12 @@ def extract_keys(work_dir, config):
key_file.writelines(config['beeswarm_server']['zmq_own_public'])
with open(os.path.join(private_keys, 'client.key'), 'w') as key_file:
key_file.writelines(config['beeswarm_server']['zmq_own_private'])

def extract_config_from_api(config_url):
# meh, MiTM problem here... Acceptable? Workaround?
# maybe print fingerprint on the web ui and let user verify manually?
conf = requests.get(config_url, verify=False)
print conf
config = json.loads(conf.text, object_hook=asciify)
with open('beeswarmcfg.json', 'w') as local_config:
local_config.write(json.dumps(config, indent=4))
9 changes: 2 additions & 7 deletions bin/beeswarm
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ import sys
import os

from gevent import Greenlet
import requests

from beeswarm.drones.drone import Drone
from beeswarm.drones.honeypot.honeypot import Honeypot
from beeswarm.server.server import Server
from beeswarm.drones.client.client import Client
from beeswarm.errors import ConfigNotFound
from beeswarm.shared.asciify import asciify
from beeswarm.shared.helpers import is_url
from beeswarm.shared.helpers import is_url, extract_config_from_api


logger = logging.getLogger()
Expand Down Expand Up @@ -68,7 +67,6 @@ def setuplogging(logfile, verbose):
file_log.setFormatter(formatter)
root_logger.addHandler(file_log)


class LogFilter(logging.Filter):
def filter(self, rec):
if rec.name == 'paramiko.transport':
Expand Down Expand Up @@ -101,10 +99,7 @@ if __name__ == '__main__':
if is_url(args.configurl):
# meh, MiTM problem here... Acceptable? Workaround?
# maybe print fingerprint on the web ui and let user verify manually?
conf = requests.get(args.configurl, verify=False)
config = json.loads(conf.text, object_hook=asciify)
with open('beeswarmcfg.json', 'w') as local_config:
local_config.write(json.dumps(config, indent=4))
extract_config_from_api(args.configurl)

if os.path.isfile('beeswarmcfg.json'):
with open('beeswarmcfg.json', 'r') as config_file:
Expand Down

0 comments on commit 74974ea

Please sign in to comment.