From ecc4a8eb46dd34780dc67fa044617f4300627676 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 22 Sep 2021 10:19:54 -0700 Subject: [PATCH] testing data routing for GPS --- bridge_master.py | 25 ++++++++++++++++++++++++ config.py | 4 +++- const.py | 4 ++++ hblink.py | 51 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index c1fbb8f..4469add 100755 --- a/bridge_master.py +++ b/bridge_master.py @@ -76,6 +76,9 @@ logger = logging.getLogger(__name__) import re +##from hmac import new as hmac_new, compare_digest +##from hashlib import sha256, sha1 + # 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' @@ -472,6 +475,16 @@ def stream_trimmer_loop(): else: logger.debug('(%s) Attemped to remove OpenBridge Stream ID %s not in the Stream ID list: %s', system, int_id(stream_id), [id for id in systems[system].STATUS]) +# Send SVRD packets to all OBP connections where ENCRYPTION_KEY is defined +def svrd_send_all(_svrd_data): + _svrd_packet = SVRD + for system in CONFIG['SYSTEMS']: + if CONFIG['SYSTEMS'][system]['ENABLED']: + if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE': + if CONFIG['SYSTEMS'][system]['ENCRYPTION_KEY'] != b'': + systems[system].send_system(_svrd_packet + _svrd_data) + + def sendVoicePacket(self,pkt,_source_id,_dest_id,_slot): _stream_id = pkt[16:20] _pkt_time = time() @@ -1758,6 +1771,16 @@ class routerHBP(HBSYSTEM): _lang = CONFIG['SYSTEMS'][self._system]['ANNOUNCEMENT_LANGUAGE'] _int_dst_id = int_id(_dst_id) + + print(_call_type) + print(_dtype_vseq) + print(_frame_type) + if (_dtype_vseq == 3 or _dtype_vseq == 6 or _dtype_vseq == 7) and _call_type == 'unit': +## if _dtype_vseq == [3, 6, 7] and _call_type == 'unit': +## print('data packet') + print((_data)) + print(systems['OBP-TEST']) + systems['OBP-TEST'].send_system(b'SVRDDATA' + _data) #Handle private calls (for reflectors) if _call_type == 'unit': @@ -1921,6 +1944,8 @@ class routerHBP(HBSYSTEM): # This is a new call stream self.STATUS[_slot]['RX_START'] = pkt_time + # Send SVRD packet to update other servers where this subscriber is + svrd_send_all(b'UNIT' + _rf_src) logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \ self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot) if CONFIG['REPORTS']['REPORT']: diff --git a/config.py b/config.py index 51b6c4e..6c03909 100755 --- a/config.py +++ b/config.py @@ -333,7 +333,9 @@ def build_config(_config_file): 'TG1_ACL': config.get(section, 'TGID_ACL'), 'TG2_ACL': 'PERMIT:ALL', 'RELAX_CHECKS': config.getboolean(section, 'RELAX_CHECKS'), - 'ENHANCED_OBP': config.getboolean(section, 'ENHANCED_OBP') + 'ENHANCED_OBP': config.getboolean(section, 'ENHANCED_OBP'), + 'ENCRYPTION_KEY': bytes(config.get(section, 'ENCRYPTION_KEY'), 'utf-8'), + 'USE_ENCRYPTION': config.getboolean(section, 'USE_ENCRYPTION'), }}) try: diff --git a/const.py b/const.py index c491223..e177d81 100755 --- a/const.py +++ b/const.py @@ -69,6 +69,10 @@ RPTA = b'RPTA' RPTO = b'RPTO' DMRA = b'DMRA' +# Sever Data and Encrypted OBP +SVRD = b'SVRD' +EOBP = b'EOBP' + #Bridge Control commands BC = b'BC' BCKA = b'BCKA' diff --git a/hblink.py b/hblink.py index 2610323..64c07bb 100755 --- a/hblink.py +++ b/hblink.py @@ -55,6 +55,9 @@ from reporting_const import * import logging logger = logging.getLogger(__name__) +# Encryption library +from cryptography.fernet import Fernet + # 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' @@ -67,6 +70,21 @@ __email__ = 'simon@gb7fr.org.uk' # Global variables used whether we are a module or __main__ systems = {} +# Functions that provide a basic symetrical encryption using Fernet +def encrypt_packet(key, message): + f = Fernet(key) + token = f.encrypt(message) + + return token + +def decrypt_packet(key, message): + f = Fernet(key) + token = f.decrypt(message) + + return token + + + # Timed loop used for reporting HBP status def config_reports(_config, _factory): def reporting_loop(_logger, _server): @@ -131,14 +149,34 @@ class OPENBRIDGE(DatagramProtocol): logger.info('(%s) is mode OPENBRIDGE. No De-Registration required, continuing shutdown', self._system) def send_system(self, _packet): - if _packet[:4] == DMRD and self._config['TARGET_IP']: + print('----') + print(_packet) + if _packet[:4] == DMRD and self._config['TARGET_IP'] or _packet[:4] == EOBP and self._config['TARGET_IP']: + print(ahex(_packet)) #_packet = _packet[:11] + self._config['NETWORK_ID'] + _packet[15:] _packet = b''.join([_packet[:11], self._CONFIG['GLOBAL']['SERVER_ID'], _packet[15:]]) #_packet += hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest() + #print(hmac_new(self._config['PASSPHRASE'],_packet,sha1)) _packet = b''.join([_packet, (hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest())]) +## print(ahex(hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest())) +## print(len(hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest())) + if self._config['USE_ENCRYPTION'] == True or _packet[:4] == EOBP: + _enc_pkt = encrypt_packet(self._config['ENCRYPTION_KEY'], _packet) + _packet = b'EOBP' + _enc_pkt + print('Use EOBP') + print(_packet) self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! - #logger.debug('(%s) TX Packet to OpenBridge %s:%s -- %s', self._system, self._config['TARGET_IP'], self._config['TARGET_PORT'], ahex(_packet)) + #logger.debug('(%s) TX Packet to OpenBridge %s:%s -- %s', self._system, self._config['TARGET_IP'], self._config['TARGET_PORT'], ahex(_packet)) + +## elif _packet[:4] == EOBP and self._config['TARGET_IP']: + + elif _packet[:4] == SVRD: + print(_packet) + _enc_pkt = encrypt_packet(self._config['ENCRYPTION_KEY'], _packet) + _packet = b'SVRD' + _enc_pkt + self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) + logger.info('SVRD packet') else: if not self._config['TARGET_IP']: @@ -174,7 +212,14 @@ class OPENBRIDGE(DatagramProtocol): # Keep This Line Commented Unless HEAVILY Debugging! #logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_packet)) - if _packet[:4] == DMRD: # DMRData -- encapsulated DMR data frame + # DMRData -- encapsulated DMR data frame + if _packet[:4] == DMRD or _packet[:4] == EOBP: + if _packet[:4] == EOBP: + print(_packet) + print('Decrypt') + _d_pkt = decrypt_packet(self._config['ENCRYPTION_KEY'], _packet[4:]) + _packet = _d_pkt + print(_packet) _data = _packet[:53] _hash = _packet[53:] _ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest()