From 4ca991f98b1a012e2f6062dde46b01e27e69b467 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 16 Aug 2023 17:37:30 +0100 Subject: [PATCH] working on it --- API.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ api_client.py | 23 ++++++++++++++++++ bridge_master.py | 23 +++++++++++++++--- hblink.py | 2 +- 4 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 API.py create mode 100644 api_client.py diff --git a/API.py b/API.py new file mode 100644 index 0000000..68af08d --- /dev/null +++ b/API.py @@ -0,0 +1,62 @@ +from xmlrpc.client import Fault + +from twisted.web import xmlrpc + +from hashlib import blake2b + +class FD_API_HELPERS(): + def __init__(self,CONFIG,APIQUEUE): + self._CONFIG = CONFIG + self._APIQUEUE = APIQUEUE + + def connected(self,_id): + for system in self._CONFIG['SYSTEMS']: + for peerid in self._CONFIG['SYSTEMS'][self._system]['PEERS']: + if peerid == _id: + return(system) + return(False) + + + def validateHMAC(_hmac,_system): + self._config = self._CONFIG['SYSTEMS'][_system] + _h = blake2b(key=self._config['_opt_key'], digest_size=16) + _h.update('validate') + _hash = _h.digest() + if _hash == _hmac: + return(True) + else: + return(False) + + +class FD_API(xmlrpc.XMLRPC(allow_none=True)): + + def __init__(self,CONFIG,APIQUEUE): + self._CONFIG = CONFIG + self._APIQUEUE = APIQUEUE + self.helpers = FD_API_HELPERS(self._CONFIG,self._APIQUEUE) + + def reset(self,_id,_hmac): + return('') + system = self.helpers.connected(_id) + if result: + if self.helpers.validateHMAC(_hmac,_system): + self._CONFIG['SYSTEMS'][system]['_reset'] = True + else: + return Fault(2, "Authentication failed") + else: + return Fault(1, "ID not connected to this server") + + return('Z') + + +def main(): + from twisted.internet import reactor + from twisted.web import server + + r = FD_API({},{}) + reactor.listenTCP(7080, server.Site(r)) + reactor.run() + + +if __name__ == "__main__": + main() diff --git a/api_client.py b/api_client.py new file mode 100644 index 0000000..19dbc25 --- /dev/null +++ b/api_client.py @@ -0,0 +1,23 @@ + +from twisted.internet import reactor +from twisted.web.xmlrpc import Proxy + + +def printValue(value): + print(repr(value)) + reactor.stop() + + +def printError(error): + print("error", error) + reactor.stop() + + +def capitalize(value): + print(value) + + +proxy = Proxy(b"http://localhost:7080/xmlrpc") +# The callRemote method accepts a method name and an argument list. +proxy.callRemote("FD_API.reset", '2', '55555').addCallbacks(capitalize, printError) +reactor.run() diff --git a/bridge_master.py b/bridge_master.py index 35f4974..25cd87e 100644 --- a/bridge_master.py +++ b/bridge_master.py @@ -50,6 +50,7 @@ from hashlib import blake2b from twisted.internet.protocol import Factory, Protocol from twisted.protocols.basic import NetstringReceiver from twisted.internet import reactor, task +from twisted.web import server # Things we import from the main hblink module from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases, acl_check @@ -80,6 +81,7 @@ import re from binascii import b2a_hex as ahex from AMI import AMI +from API import FD_API # Does anybody read this stuff? There's a PEP somewhere that says I should do this. @@ -134,6 +136,14 @@ def config_reports(_config, _factory): return report_server +# Start API server +def config_API(_config, _apiqueue): + + r = FD_API(_config,_apiqueue) + reactor.listenTCP(7080, server.Site(r)) + + return r + # Import Bridging rules # Note: A stanza *must* exist for any MASTER or CLIENT configured in the main @@ -844,9 +854,6 @@ def options_config(): else: logger.debug('(OPTIONS) %s, _opt_key not set and no key sent. Generate random key',_system) CONFIG['SYSTEMS'][_system]['_opt_key'] = randint(0,65535) - - - if 'DIAL' in _options: _options['DEFAULT_REFLECTOR'] = _options.pop('DIAL') @@ -2611,6 +2618,7 @@ if __name__ == '__main__': ID_MAX = 16776415 + #Set process title early setproctitle(__file__) @@ -2845,6 +2853,15 @@ if __name__ == '__main__': logger.error('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error in timed loop.\n %s', failure) reactor.stop() + + #Initialize API + APIQUEUE = {} + api = config_API(CONFIG,APIQUEUE) + if api: + logger.info('(API) API running') + else: + logger.info('(API) API not started') + # Initialize the rule timer -- this if for user activated stuff rule_timer_task = task.LoopingCall(rule_timer_loop) rule_timer = rule_timer_task.start(52) diff --git a/hblink.py b/hblink.py index 0ea75ef..5de6895 100755 --- a/hblink.py +++ b/hblink.py @@ -76,7 +76,7 @@ logging.trace = partial(logging.log, logging.TRACE) # Does anybody read this stuff? There's a PEP somewhere that says I should do this. __author__ = 'Cortney T. Buffington, N0MJS, Forked by Simon Adlem - G7RZU' -__copyright__ = 'Copyright (c) 2016-2019 Cortney T. Buffington, N0MJS and the K0USY Group, Simon Adlem, G7RZU 2020,2021,2022' +__copyright__ = 'Copyright (c) 2016-2019 Cortney T. Buffington, N0MJS and the K0USY Group, Simon Adlem, G7RZU 2020,2021,2022,2023' __credits__ = 'Colin Durbridge, G4EML, Steve Zingman, N4IRS; Mike Zingman, N4IRR; Jonathan Naylor, G4KLX; Hans Barthen, DL5DI; Torsten Shultze, DG1HT; Jon Lee, G4TSN; Norman Williams, M6NBP' __license__ = 'GNU GPLv3' __maintainer__ = 'Simon Adlem G7RZU'