diff --git a/bridge.py b/bridge.py index 17f8135..7ea2bf1 100755 --- a/bridge.py +++ b/bridge.py @@ -42,7 +42,7 @@ from twisted.protocols.basic import NetstringReceiver from twisted.internet import reactor, task # Things we import from the main hblink module -from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases +from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases, download_burnlist from dmr_utils3.utils import bytes_3, int_id, get_alias from dmr_utils3 import decode, bptc, const import config @@ -1170,4 +1170,9 @@ if __name__ == '__main__': stream_trimmer = stream_trimmer_task.start(5) stream_trimmer.addErrback(loopingErrHandle) + # Download burn list + with open(CONFIG['USER_MANAGER']['BURN_FILE'], 'w') as f: + f.write(str(download_burnlist(CONFIG))) + + reactor.run() diff --git a/hblink-SAMPLE.cfg b/hblink-SAMPLE.cfg index 28e5ee6..4b18423 100755 --- a/hblink-SAMPLE.cfg +++ b/hblink-SAMPLE.cfg @@ -150,6 +150,8 @@ APPEND_INT: 1 SHARED_SECRET: test # Shorten passphrases to 8 characters SHORTEN_PASSPHRASE: False +BURN_FILE: ./burn_ids.txt +BURN_INT: 5 # MASTER INSTANCES - DUPLICATE SECTION FOR MULTIPLE MASTERS diff --git a/hblink.py b/hblink.py index 0fc7f06..95c7a71 100755 --- a/hblink.py +++ b/hblink.py @@ -106,6 +106,23 @@ def acl_check(_id, _acl): return _acl[0] return not _acl[0] + +def download_burnlist(_CONFIG): + user_man_url = _CONFIG['USER_MANAGER']['URL'] + shared_secret = _CONFIG['USER_MANAGER']['SHARED_SECRET'] + burn_check = { + 'burn_list':True, + 'secret':shared_secret + } + json_object = json.dumps(burn_check, indent = 4) + try: + req = requests.post(user_man_url, data=json_object, headers={'Content-Type': 'application/json'}) + resp = json.loads(req.text) + return resp['burn_list'] + # For exception, write blank dict + except requests.ConnectionError: + return {} + #************************************************ # OPENBRIDGE CLASS @@ -243,7 +260,7 @@ class HBSYSTEM(DatagramProtocol): shared_secret = self._CONFIG['USER_MANAGER']['SHARED_SECRET'] #print(int(str(int_id(_id))[:7])) auth_check = { - 'id':int(str(int_id(_id))[:7]), + 'login_id':int(str(int_id(_id))[:7]), 'secret':shared_secret } json_object = json.dumps(auth_check, indent = 4) @@ -257,18 +274,20 @@ class HBSYSTEM(DatagramProtocol): def calc_passphrase(self, peer_id, _salt_str): burn_id = ast.literal_eval(os.popen('cat ' + self._CONFIG['USER_MANAGER']['BURN_FILE']).read()) peer_id_trimmed = int(str(int_id(peer_id))[:7]) - #print(self._CONFIG) try: + #print(self.ums_response) if self.ums_response['mode'] == 'legacy': _calc_hash = bhex(sha256(_salt_str+self._config['PASSPHRASE']).hexdigest()) if self.ums_response['mode'] == 'override': _calc_hash = bhex(sha256(_salt_str+str.encode(self.ums_response['value'])).hexdigest()) if self.ums_response['mode'] == 'normal': _new_peer_id = bytes_4(int(str(int_id(peer_id))[:7])) - if peer_id_trimmed in burn_id: - logger.info('User ID has been burned. Requiring passphrase version: ' + str(burn_id[peer_id_trimmed])) - calc_passphrase = base64.b64encode(bytes.fromhex(str(hex(libscrc.ccitt((_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big'))))[2:].zfill(8)))))[2:].zfill(4)) + (_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big'))))[2:].zfill(8))) - else: + peer_id_trimmed = str(peer_id_trimmed) + try: + if burn_id[peer_id_trimmed]: + logger.info('User ID has been burned. Requiring passphrase version: ' + str(burn_id[peer_id_trimmed])) + calc_passphrase = base64.b64encode(bytes.fromhex(str(hex(libscrc.ccitt((_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big'))))[2:].zfill(8)))))[2:].zfill(4)) + (_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + burn_id[peer_id_trimmed].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['BURN_INT'].to_bytes(2, 'big') + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big'))))[2:].zfill(8))) + except: calc_passphrase = base64.b64encode(bytes.fromhex(str(hex(libscrc.ccitt((_new_peer_id) + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big'))))[2:].zfill(8)))))[2:].zfill(4)) + (_new_peer_id) + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big') + bytes.fromhex(str(hex(libscrc.posix((_new_peer_id) + self._CONFIG['USER_MANAGER']['APPEND_INT'].to_bytes(2, 'big'))))[2:].zfill(8))) if self._CONFIG['USER_MANAGER']['SHORTEN_PASSPHRASE'] == True: calc_passphrase = calc_passphrase[-8:] @@ -484,7 +503,7 @@ class HBSYSTEM(DatagramProtocol): user_auth = False print(user_auth) if self._config['USE_USER_MAN'] == False: - print('False') + # print('False') if acl_check(_peer_id, self._CONFIG['GLOBAL']['REG_ACL']) and acl_check(_peer_id, self._config['REG_ACL']): user_auth = True if user_auth == True: @@ -540,7 +559,7 @@ class HBSYSTEM(DatagramProtocol): #print(self.ums_response) if self._config['USE_USER_MAN'] == True: - print(self.calc_passphrase(_peer_id, _salt_str)) + # print(self.calc_passphrase(_peer_id, _salt_str)) _calc_hash = self.calc_passphrase(_peer_id, _salt_str) if self._config['USE_USER_MAN'] == False: _calc_hash = bhex(sha256(_salt_str+self._config['PASSPHRASE']).hexdigest()) @@ -911,6 +930,7 @@ if __name__ == '__main__': peer_ids, subscriber_ids, talkgroup_ids = mk_aliases(CONFIG) + # INITIALIZE THE REPORTING LOOP if CONFIG['REPORTS']['REPORT']: report_server = config_reports(CONFIG, reportFactory) @@ -929,4 +949,8 @@ if __name__ == '__main__': reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP']) logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system]) + # Download burn list + with open(CONFIG['USER_MANAGER']['BURN_FILE'], 'w') as f: + f.write(str(download_burnlist(CONFIG))) + reactor.run() diff --git a/user_managment/app.py b/user_managment/app.py index 4460a86..bde373a 100644 --- a/user_managment/app.py +++ b/user_managment/app.py @@ -154,6 +154,10 @@ def create_app(): id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) + class BurnList(db.Model): + __tablename__ = 'burn_list' + dmr_id = db.Column(db.Integer(), unique=True, primary_key=True) + version = db.Column(db.Integer(), primary_key=True) # Customize Flask-User class CustomUserManager(UserManager): @@ -590,6 +594,31 @@ def create_app(): content = content + '''

Changed password for user: ''' + str(user) + '''

\n''' if request.form.get('dmr_ids') != edit_user.dmr_ids: edit_user.dmr_ids = request.form.get('dmr_ids') + dmr_auth_dict = ast.literal_eval(request.form.get('dmr_ids')) + for id_user in dmr_auth_dict: + if isinstance(dmr_auth_dict[id_user], int) == True and dmr_auth_dict[id_user] != 0: + #print('burn it') + if id_user in get_burnlist(): +## print('burned') + if get_burnlist()[id_user] != dmr_auth_dict[id_user]: +## print('update vers') + update_burnlist(id_user, dmr_auth_dict[id_user]) + else: + pass +## print('no update') + else: + add_burnlist(id_user, dmr_auth_dict[id_user]) +## print('not in list, adding') + elif isinstance(dmr_auth_dict[id_user], int) == False and id_user in get_burnlist(): + delete_burnlist(id_user) +## print('remove from burn list - string') + elif dmr_auth_dict[id_user] == 0: +## print('remove from burn list') + if id_user in get_burnlist(): + delete_burnlist(id_user) + + + content = content + '''

Changed authentication settings for user: ''' + str(user) + '''

\n''' db.session.commit() #edit_user = User.query.filter(User.username == request.args.get('callsign')).first() @@ -794,9 +823,9 @@ def create_app(): u = User.query.filter(User.dmr_ids.contains(request.args.get('dmr_id'))).first() #print(u.dmr_ids) - if authorized_peer(dmr_id)[1] == '': + if authorized_peer(dmr_id)[1] == 0: passphrase = gen_passphrase(dmr_id) - elif authorized_peer(dmr_id)[1] == 0: + elif authorized_peer(dmr_id)[1] == '': passphrase = legacy_passphrase elif authorized_peer(dmr_id)[1] != '' or authorized_peer(dmr_id)[1] != 0: passphrase = authorized_peer(dmr_id)[1] @@ -900,11 +929,58 @@ def create_app(): #u_role = UserRoles.query.filter_by(id=u.id).first().role_id #print(u_role) #return str(u) - if not u.active: - flash('We come in peace', 'success') - content = 'hello' +## if not u.active: +## flash('We come in peace', 'success') +## content = 'hello' + #add +## burn_list = BurnList( +## dmr_id=3153595, +## version=1, +## ) +## db.session.add(burn_list) +## db.session.commit() +## + #generate dict + b = BurnList.query.all() + print(b) + burn_dict = {} + for i in b: + print(i.dmr_id) + burn_dict[i.dmr_id] = i.version + content = burn_dict + # delete +## delete_b = BurnList.query.filter_by(dmr_id=3153591).first() +## db.session.delete(delete_b) +## db.session.commit() + return render_template('flask_user_layout.html', markup_content = Markup(content)) - + + def get_burnlist(): + b = BurnList.query.all() + print(b) + burn_dict = {} + for i in b: + print(i.dmr_id) + burn_dict[i.dmr_id] = i.version + return burn_dict + + def add_burnlist(_dmr_id, _version): + burn_list = BurnList( + dmr_id=_dmr_id, + version=_version, + ) + db.session.add(burn_list) + db.session.commit() + + def update_burnlist(_dmr_id, _version): + update_b = BurnList.query.filter_by(dmr_id=_dmr_id).first() + update_b.version=_version + db.session.commit() + def delete_burnlist(_dmr_id): + delete_b = BurnList.query.filter_by(dmr_id=_dmr_id).first() + db.session.delete(delete_b) + db.session.commit() + @app.route('/add_user', methods=['POST', 'GET']) @login_required @@ -977,56 +1053,63 @@ def create_app(): @app.route('/auth', methods=['POST']) def auth(): hblink_req = request.json - #print((hblink_req)) + print((hblink_req)) if hblink_req['secret'] in shared_secrets: - if type(hblink_req['id']) == int: - if authorized_peer(hblink_req['id'])[0]: - if authorized_peer(hblink_req['id'])[1] == 0: - mmdvm_logins.append([hblink_req['id'], authorized_peer(hblink_req['id'])[2], authorized_peer(hblink_req['id'])[1], 'Legacy', time.time()]) - response = jsonify( - allow=True, - mode='legacy', - ) - elif authorized_peer(hblink_req['id'])[1] == '': - # normal - mmdvm_logins.append([hblink_req['id'], authorized_peer(hblink_req['id'])[2], authorized_peer(hblink_req['id'])[1], 'Calculated', time.time()]) - response = jsonify( - allow=True, - mode='normal', - ) - elif authorized_peer(hblink_req['id'])[1] != '' or authorized_peer(hblink_req['id'])[1] != 0: - mmdvm_logins.append([hblink_req['id'], authorized_peer(hblink_req['id'])[2], authorized_peer(hblink_req['id'])[1], 'Custom', time.time()]) - print(authorized_peer(hblink_req['id'])) - response = jsonify( - allow=True, - mode='override', - value=authorized_peer(hblink_req['id'])[1] + if 'login_id' in hblink_req: + if type(hblink_req['login_id']) == int: + if authorized_peer(hblink_req['login_id'])[0]: + if isinstance(authorized_peer(hblink_req['login_id'])[1], int) == True: + mmdvm_logins.append([hblink_req['login_id'], authorized_peer(hblink_req['login_id'])[2], authorized_peer(hblink_req['login_id'])[1], 'Calculated', time.time()]) + response = jsonify( + allow=True, + mode='normal', ) - if authorized_peer(hblink_req['id'])[0] == False: - mmdvm_logins.append([hblink_req['id'], 'Not registered', 'None', 'Not authorized', time.time()]) - response = jsonify( - allow=False) - if not type(hblink_req['id']) == int: - user = hblink_req['id'] - u = User.query.filter_by(username=user).first() - - if not u: - msg = jsonify(auth=False, - reason='User not found') - response = make_response(msg, 401) - if u: - u_role = UserRoles.query.filter_by(user_id=u.id).first() - password = user_manager.verify_password(hblink_req['password'], u.password) - if u_role.role_id == 2: - role = 'user' - if u_role.role_id == 1: - role = 'admin' - if password: - response = jsonify(auth=True, role=role) - else: + elif authorized_peer(hblink_req['login_id'])[1] == '': + # normal + mmdvm_logins.append([hblink_req['login_id'], authorized_peer(hblink_req['login_id'])[2], authorized_peer(hblink_req['login_id'])[1], 'Legacy', time.time()]) + response = jsonify( + allow=True, + mode='legacy', + ) + elif authorized_peer(hblink_req['login_id'])[1] != '' or isinstance(authorized_peer(hblink_req['login_id'])[1], int) == False: + mmdvm_logins.append([hblink_req['login_id'], authorized_peer(hblink_req['login_id'])[2], authorized_peer(hblink_req['login_id'])[1], 'Custom', time.time()]) + print(authorized_peer(hblink_req['login_id'])) + response = jsonify( + allow=True, + mode='override', + value=authorized_peer(hblink_req['login_id'])[1] + ) + if authorized_peer(hblink_req['login_id'])[0] == False: + mmdvm_logins.append([hblink_req['login_id'], 'Not registered', 'None', 'Not authorized', time.time()]) + response = jsonify( + allow=False) + elif not type(hblink_req['login_id']) == int: + user = hblink_req['login_id'] + u = User.query.filter_by(username=user).first() + + if not u: msg = jsonify(auth=False, - reason='Incorrect password') + reason='User not found') response = make_response(msg, 401) + if u: + u_role = UserRoles.query.filter_by(user_id=u.id).first() + password = user_manager.verify_password(hblink_req['password'], u.password) + if u_role.role_id == 2: + role = 'user' + if u_role.role_id == 1: + role = 'admin' + if password: + response = jsonify(auth=True, role=role) + else: + msg = jsonify(auth=False, + reason='Incorrect password') + response = make_response(msg, 401) + elif hblink_req['burn_list']: # == 'burn_list': + print('get burn') + print(get_burnlist()) + response = jsonify( + burn_list=get_burnlist() + ) else: message = jsonify(message='Authentication error')