def __init__(self, bridge, host_eui64_hex, thread_exit_event, command_queue, event_queue, log_queue, watchdog_delegate): self.host_eui64_hex = host_eui64_hex self.commandProcessingEnabled = True self.eventProcessingEnabled = True self.logProcessingEnabled = True self.thread_exit_event = thread_exit_event self.command_queue = command_queue self.event_queue = event_queue self.log_queue = log_queue self.watchdog_delegate = watchdog_delegate self.current_json_message = None self.bridge = bridge self.networkUp = bridge.networkUp self.handshake_sent = False self.logger = Logger('cloud') self.command_logger = Logger('cloud.command') self.event_logger = Logger('cloud.event') self.logging_logger = Logger('cloud.logging') self.socket_logger = Logger('cloud.socket') self.resolver = simple_caching_resolver.SimpleCachingResolver() self.sm = statistics_monitor.StatisticsMonitor() self.event_sources = {} self.connection_failure_count = 0 self.ip_pool = [] self.last_connected_at = None self.ws = None socket.setdefaulttimeout(HTTP_SOCKET_TIMEOUT)
class BergCloudSocketApi(Singleton): def __init__(self, bridge, host_eui64_hex, thread_exit_event, command_queue, event_queue, log_queue, watchdog_delegate): self.host_eui64_hex = host_eui64_hex self.commandProcessingEnabled = True self.eventProcessingEnabled = True self.logProcessingEnabled = True self.thread_exit_event = thread_exit_event self.command_queue = command_queue self.event_queue = event_queue self.log_queue = log_queue self.watchdog_delegate = watchdog_delegate self.current_json_message = None self.bridge = bridge self.networkUp = bridge.networkUp self.handshake_sent = False self.logger = Logger('cloud') self.command_logger = Logger('cloud.command') self.event_logger = Logger('cloud.event') self.logging_logger = Logger('cloud.logging') self.socket_logger = Logger('cloud.socket') self.resolver = simple_caching_resolver.SimpleCachingResolver() self.sm = statistics_monitor.StatisticsMonitor() self.event_sources = {} self.connection_failure_count = 0 self.ip_pool = [] self.last_connected_at = None self.ws = None socket.setdefaulttimeout(HTTP_SOCKET_TIMEOUT) def start(self): event_state = self.thread_exit_event.wait(THREAD_WAIT_TIMEOUT) while not event_state: if self.watchdog_delegate: self.watchdog_delegate.updateKey('socketThread') try: if self.ws == None or self.ws.connectionState == 'closed': if len(self.ip_pool) == 0: (ip_addresses, expiration_time,) = self.resolver.lookup(WS_HOSTNAME) random.shuffle(ip_addresses) self.logger.info('IP pool now %s with an expiry in %d seconds' % (ip_addresses, expiration_time - time.time())) self.ip_pool = ip_addresses self.connection_expiration_time = expiration_time ip_address = self.ip_pool.pop() if self.connect(ip_address): self.last_connected_at = time.time() self.current_ip_address = ip_address self.socket_logger.debug('Resetting connection_failure_count') self.connection_failure_count = 0 self.handshake_sent = False elif len(self.ip_pool) == 0: self.connection_failure_count += 1 self.socket_logger.debug("Incrementing connection_failure_count (now %d) as we're out of IPs" % self.connection_failure_count) event_state = self.thread_exit_event.wait(5) elif time.time() > self.connection_expiration_time: if self.currentIPIsValid(): self.logger.info('DNS timeout reached: Current IP address is still valid, not dropping') self.connection_expiration_time += 3600 else: self.logger.info("Closing websocket as we're over expiry time and DNS has changed") self.ws.close() else: self.sendPendingData() except: self.socket_logger.exception('Unhandled socket api exception:', sys.exc_info()) self.connection_failure_count += 1 self.handshake_sent = False event_state = self.thread_exit_event.wait(THREAD_WAIT_TIMEOUT) if self.ws != None: self.logger.warning('Closing websocket from bridge side') try: self.ws.close() finally: if self.ws._th.isAlive(): self.ws._th.join() self.ws = None def currentIPIsValid(self): current_ip_address = self.current_ip_address (resolved_ip_addresses, expiration_time,) = self.resolver.lookup(WS_HOSTNAME) return current_ip_address in resolved_ip_addresses def sendPendingData(self): if self.current_json_message != None: self.socket_logger.info('We have pending JSON data to send: %s' % self.current_json_message) if self.sendJson(self.current_json_message): self.current_json_message = None else: self.socket_logger.warning("Still can't send the current JSON") return if not self.handshake_sent: self.onEstablishConnection() if self.eventProcessingEnabled: self.postFromEventQueue() if self.log_queue != None and self.logProcessingEnabled: self.postFromLogQueue() self.assess_active_devices() def endpoint(self): return '%s://%s:%s/' % (WS_SCHEME, WS_HOSTNAME, WS_PORT) def connect(self, ip_address): connect_success = False self.socket_logger.info('Creating websocket client') ssl_options = None ws_protocols = ['bergcloud-bridge-v1'] if WS_SCHEME == 'https': proto = 'wss' ssl_options = {'keyfile': SSL_KEY, 'certfile': SSL_CERT, 'ca_certs': SSL_CA_PEM, 'cert_reqs': ssl.CERT_REQUIRED} else: proto = 'ws' ws_uri = '%s://%s:%s/api/v1/connection' % (proto, ip_address, WS_PORT) try: if ssl_options == None: self.ws = BergCloudStreamingClient(ws_uri, protocols=ws_protocols, heartbeat_freq=5) else: self.ws = BergCloudStreamingClient(ws_uri, ssl_options=ssl_options, protocols=ws_protocols, heartbeat_freq=5) self.ws.daemon = False self.ws.set_command_queue(self.command_queue) self.ws.set_event_queue(self.event_queue) self.ws.set_host_eui64_hex(self.host_eui64_hex) self.socket_logger.debug('Connecting to %s' % ws_uri) self.ws.connect() connect_success = True except socket.error as e: if e.errno == errno.ECONNREFUSED: self.socket_logger.error('Socket connection refused') elif e.errno == errno.ETIMEDOUT: self.socket_logger.error('Socket connection timed out') elif e.errno == errno.EHOSTUNREACH: self.socket_logger.error('No route to host') else: self.socket_logger.error('Socket connection exception %s [%s]' % (e, str(e.errno))) except socket.timeout: self.socket_logger.error('Socket connection timed out') except: self.socket_logger.exception('Unexpected socket connect error:', sys.exc_info()) if not connect_success: self.ws = None return connect_success def isConnected(self): if self.ws == None: return False else: return self.ws.connectionState == 'connected' def onEstablishConnection(self): if self.networkUp(): self.socket_logger.info('Sending bridge power_on handshake') event = bridge_event.BridgeEvent(self.host_eui64_hex, {'name': 'power_on'}) event.append_payload(self.bridge.system_environment) ver_info = version.Version() version_dict = {'firmware_version': ver_info.firmware_version, 'mac_address': ver_info.mac_address, 'ncp_version': ver_info.ncp_stack_version, 'model': ver_info.model} event.append_payload(version_dict) event_json = event.to_json() self.logger.debug('Posting event JSON %s' % event_json) result = self.sendJson(event_json) if result: self.handshake_sent = True self.event_sources = {} def postFromEventQueue(self): try: event = self.event_queue.get(False) if isinstance(event, device_event.DeviceEvent) and event.device_address == None: self.logger.warning('Device Event has no device_address! Cannot post to cloud!') return if isinstance(event, device_event.DeviceEvent): source_eui64_hex = byte_tuple.eui64ToHexString(event.device_address, False) self._register_active_device(source_eui64_hex) event.rssi_stats = self.sm.rssiStatsForEui64(source_eui64_hex) self.current_json_message = event.to_json() self.logger.info('Posting event JSON %s' % self.current_json_message) result = self.sendJson(self.current_json_message) if result: self.current_json_message = None except Queue.Empty: pass def postFromLogQueue(self): log_records = [] try: while True: record = self.log_queue.get(False) clr = cloud_log_record.CloudLogRecord(record) log_records.append(clr) except Queue.Empty: if len(log_records) > 0: self.current_json_message = cloud_log_record.CloudLogRecord.to_json(log_records, self.host_eui64_hex) result = self.sendJson(self.current_json_message) if result: self.current_json_message = None def sendJson(self, json): if self.ws == None: self.logger.error('No socket client to post with!') return False try: self.ws.send(json) return True except socket.error as e: if e.errno == errno.EPIPE: self.logger.error('Broken pipe. Re-stashing event and reconnecting') time.sleep(2) else: self.logger.error('Socket error %s' % e) self.ws.close() self.ws = None return False except: self.logger.exception('socket send exception', sys.exc_info()) return False def assess_active_devices(self): current_time = time.time() nodes = [] for eui64_hex in self.event_sources.keys(): times = self.event_sources[eui64_hex] first_contact_time = times[0] last_contact_time = times[1] if current_time - last_contact_time < HEARTBEAT_TIMEOUT: nodes.append(eui64_hex) else: self._deregister_active_device(eui64_hex) if len(nodes) == 0: return None else: return nodes def active_device_uptime(self, eui64_hex): current_time = time.time() if self.event_sources.has_key(eui64_hex): return current_time - self.event_sources[eui64_hex][0] def _register_active_device(self, eui64_hex): current_time = time.time() if self.event_sources.has_key(eui64_hex): self.event_sources[eui64_hex][1] = current_time else: self.event_sources[eui64_hex] = [current_time, current_time] self.command_logger.info('Issuing device_connect for %s' % eui64_hex) event = bridge_event.BridgeEvent(self.host_eui64_hex, {'name': 'device_connect', 'device_address': eui64_hex}) self.event_queue.put(event, False) def _deregister_active_device(self, eui64_hex): if self.event_sources.has_key(eui64_hex): self.command_logger.info('Issuing device_disconnect for %s' % eui64_hex) event = bridge_event.BridgeEvent(self.host_eui64_hex, {'name': 'device_disconnect', 'device_address': eui64_hex}) self.event_queue.put(event, False) del self.event_sources[eui64_hex]
def __init__(self, *args, **kwargs): self.logger = Logger('cloud.socketclient') self.connectionState = 'connecting' super(BergCloudStreamingClient, self).__init__(*args, **kwargs)
class BergCloudStreamingClient(WebSocketClient): def __init__(self, *args, **kwargs): self.logger = Logger('cloud.socketclient') self.connectionState = 'connecting' super(BergCloudStreamingClient, self).__init__(*args, **kwargs) def set_command_queue(self, queue): self.command_queue = queue def set_event_queue(self, queue): self.event_queue = queue def set_host_eui64_hex(self, value): self.host_eui64_hex = value def opened(self): self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 3) self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 3) self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5) self.connectionState = 'connected' linux_hub.set_led_state('bergcloud', 'on', True) self.logger.info('Websocket open and connected') def closed(self, code, reason = None): self.connectionState = 'closed' linux_hub.set_led_state('bergcloud', 'off', True) self.logger.warning('Closed down websocket, code: %d, reason: %s' % (code, reason)) def received_message(self, m): try: decoded_json_message = json.loads(str(m)) self.process_command(decoded_json_message) except: self.logger.exception('Exception decoding JSON:', sys.exc_info()) def process_command(self, response): if response.has_key('type'): command_type = response['type'] if command_type == 'BridgeCommand': bc = bridge_command.BridgeCommand.from_json(response) self.logger.debug('Queueing %s' % bc) self.command_queue.put(bc, False) elif command_type == 'DeviceCommand': try: dc = device_command.DeviceCommand.from_json(response) dc.bridge_address = self.host_eui64_hex self.logger.debug('Queueing %s' % dc) self.command_queue.put(dc, False) except Queue.Full: self.logger.warning('Ut oh, the command queue is full!') dc.return_code = device_command.RSP_QUEUE_FULL self.event_queue.put(dc, False) except: self.logger.exception('Exception creating command:', sys.exc_info()) dc.return_code = 255 self.event_queue.put(dc, False) else: self.logger.error("Unknown command type '%s'" % command_type) return else: self.logger.error('Required type key missing in command') return
from kivy.uix.button import Button from kivy.uix.label import Label from kivy.uix.textinput import TextInput from kivy.uix.scrollview import ScrollView from kivy.properties import StringProperty import os, json, time import pythoncom, pefile import win32com.client from config.config import Config from config.api_config import ApiConfig from customlogger import Logger from config.config import Config from MSMQCustom import MSMQCustom config = Config() logger = Logger(config) #Window.clearcolor = (1, 1, 1, 1) event_queue_name = config.get_event_queue_name() msmqueue_event = MSMQCustom(event_queue_name) config_queue_name = config.get_config_queue_name() msmqueue_config = MSMQCustom(config_queue_name) def empty_queue(self): if msmqueue_event.open_queue(1, 0): while msmqueue_event.peek(500): msg = msmqueue_event.recv_from_queue() if msg: continue
def main(): #Initialize config config = Config() if not config: print ("[x] Failed to load FriSpy configurations...") return #Initialize logger logger = Logger(config) if not logger: print ("[x] Failed to load FriSpy Logger...") return ContinueExecution = True ExecutionSampleCount = 2 while (ContinueExecution and ExecutionSampleCount): # Initialize Config Queue to receieve configurations from GUI config_queue_name = config.get_config_queue_name() msmqueue_config = MSMQCustom(config_queue_name) if msmqueue_config.open_queue(1, 0):#MQ_RECEIVE_ACCESS msg = msmqueue_config.recv_from_queue() if msg: # Receive Sample Details from FriSpyGUI logger.log("info",str(msg)) logger.log("info","Found new sample:") logger.log("info","Label: %s" % (msg.Label)) logger.log("info","Body : %s" % (msg.Body)) if msg.Label == "start": #Load the configurations sent by GUI gui_config = json.loads(msg.Body) target_process = gui_config["filepath"] config.set_save_api_watch_list_flag_status(gui_config["set_save_api_watch_list_flag_status"]) config.set_save_behavior_flag_status(gui_config["set_save_behavior_flag_status"]) config.set_capture_behavior_report_basic_flag(gui_config["set_capture_behavior_report_basic_flag"]) config.set_capture_behavior_report_complete_flag(gui_config["set_capture_behavior_report_complete_flag"]) start_frispy(config, logger, target_process) ContinueExecution = False msmqueue_config.close_queue() else: logger.log("error","Config queue not found") ExecutionSampleCount = ExecutionSampleCount - 1 return