diff --git a/docker/routlin-dash/app/pages/radius/action.py b/docker/routlin-dash/app/pages/radius/action.py index 61c56e9..019ec1c 100644 --- a/docker/routlin-dash/app/pages/radius/action.py +++ b/docker/routlin-dash/app/pages/radius/action.py @@ -69,14 +69,17 @@ def auth_mode_save(): eap_protocol = request.form.get('eap_protocol', 'eap_peap') if eap_protocol not in ('eap_peap', 'eap_ttls', 'eap_md5'): eap_protocol = 'eap_peap' + tunneled_reply = 'tunneled_reply' in request.form cfg = load_config() before = copy.deepcopy(cfg.get('radius', {}).get('options', {})) after = {**before, 'auth_mode': auth_mode} if auth_mode == 'eap_password': - after['eap_protocol'] = eap_protocol + after['eap_protocol'] = eap_protocol + after['tunneled_reply'] = tunneled_reply and eap_protocol in ('eap_peap', 'eap_ttls') else: - after.pop('eap_protocol', None) + after.pop('eap_protocol', None) + after.pop('tunneled_reply', None) cfg.setdefault('radius', {})['options'] = after changes = diff_fields(before, after) @@ -134,21 +137,6 @@ def default_vlan_save(): return redirect(f'/{_PAGE}') -@bp.route('/action/radius/eap_save', methods=['POST']) -@require_level('administrator') -def eap_save(): - allow_weak_eap = 'allow_weak_eap' in request.form - tunneled_reply = 'tunneled_reply' in request.form - - cfg = load_config() - before = copy.deepcopy(cfg.get('radius', {}).get('eap', {})) - after = {'allow_weak_eap': allow_weak_eap, 'tunneled_reply': tunneled_reply} - cfg.setdefault('radius', {})['eap'] = after - - changes = diff_fields(before, after) - flash(record_group(cfg, 'radius.eap', 'setting', 'radius', changes, 'core apply'), 'success') - return redirect(f'/{_PAGE}') - @bp.route('/action/radius/logging_save', methods=['POST']) @require_level('administrator') diff --git a/docker/routlin-dash/app/pages/radius/content.json b/docker/routlin-dash/app/pages/radius/content.json index 2dd1181..772042b 100644 --- a/docker/routlin-dash/app/pages/radius/content.json +++ b/docker/routlin-dash/app/pages/radius/content.json @@ -238,53 +238,6 @@ "options": "%RADIUS_EAP_PROTOCOL_OPTIONS%", "hint": "_" }, - { - "type": "raw_html", - "html": "" - }, - { - "type": "button_row", - "items": [ - { - "type": "button_primary", - "text": "Save" - }, - { - "type": "button_cancel", - "text": "Cancel" - } - ] - } - ] - } - ] - }, - { - "type": "card", - "label": "EAP Settings", - "client_requirement": "client_is_administrator+", - "items": [ - { - "type": "p", - "text": "These settings are required for MAC-based 802.1X authentication on managed switches." - }, - { - "type": "hr" - }, - { - "type": "form", - "action": "/action/radius/eap_save", - "method": "post", - "items": [ - { - "type": "field", - "label": "", - "name": "allow_weak_eap", - "input_type": "checkbox", - "checkbox_label": "Allow weak EAP types", - "value": "%RADIUS_ALLOW_WEAK_EAP%", - "hint": "Enables EAP-MD5. Required for switch port MAC-based 802.1X authentication." - }, { "type": "raw_html", "html": "
" diff --git a/docker/routlin-dash/app/pages/radius/view.py b/docker/routlin-dash/app/pages/radius/view.py index 52b886a..649b998 100644 --- a/docker/routlin-dash/app/pages/radius/view.py +++ b/docker/routlin-dash/app/pages/radius/view.py @@ -104,9 +104,7 @@ def collect_tokens(cfg): tokens['RADIUS_LOGGING_HINT'] = 'Unchecking will clear logs.' if fr_gen.get('logging', False) else '' tokens['RADIUS_GEN_LOG_MAX_KB'] = str(fr_gen.get('log_max_kb', 1024)) - fr_eap = fr.get('eap', {}) - tokens['RADIUS_ALLOW_WEAK_EAP'] = 'true' if fr_eap.get('allow_weak_eap', False) else '' - tokens['RADIUS_TUNNELED_REPLY'] = 'true' if fr_eap.get('tunneled_reply', False) else '' + tokens['RADIUS_TUNNELED_REPLY'] = 'true' if fr_opts.get('tunneled_reply', False) else '' vlans = cfg.get('vlans', []) default_vlan = next((v['name'] for v in vlans if v.get('radius_default') is True), '') diff --git a/routlin/config.json b/routlin/config.json index 64f3259..610942a 100644 --- a/routlin/config.json +++ b/routlin/config.json @@ -838,10 +838,6 @@ "mac_format": "aabbccddeeff", "apply_to": "all", "ap_ips": [] - }, - "eap": { - "allow_weak_eap": false, - "tunneled_reply": false } } } diff --git a/routlin/mod_radius.py b/routlin/mod_radius.py index 9ea6e3e..01011ee 100644 --- a/routlin/mod_radius.py +++ b/routlin/mod_radius.py @@ -248,26 +248,27 @@ def toggle_freeradius_block(content, block_name, enable): def set_freeradius_eap(data): - """Patch EAP config for tunneled_reply and allow_weak_eap settings. + """Patch EAP config for eap_protocol and tunneled_reply settings. Returns True if the file was modified, False if unchanged or not found. """ if not RADIUS_EAP_FILE.exists(): return False - eap_cfg = data.get('radius', {}).get('eap', {}) - tunneled_reply = eap_cfg.get('tunneled_reply', False) - allow_weak_eap = eap_cfg.get('allow_weak_eap', False) + opts = data.get('radius', {}).get('options', {}) + eap_protocol = opts.get('eap_protocol', 'eap_peap') + tunneled_reply = opts.get('tunneled_reply', False) + use_md5 = eap_protocol == 'eap_md5' + eap_type = {'eap_peap': 'peap', 'eap_ttls': 'ttls', 'eap_md5': 'md5'}.get(eap_protocol, 'peap') content = RADIUS_EAP_FILE.read_text() tr_val = 'yes' if tunneled_reply else 'no' - eap_type = 'md5' if allow_weak_eap else 'peap' content2 = re.sub(r'(?m)^(\s*use_tunneled_reply\s*=\s*)(yes|no)', rf'\g<1>{tr_val}', content) # Only replace the first occurrence -- that is the outer eap{} block's default. # Inner blocks (e.g. peap's tunneled default) must not be touched. content3 = re.sub(r'(?m)^(\s*default_eap_type\s*=\s*)\w+', rf'\g<1>{eap_type}', content2, count=1) - content4 = toggle_freeradius_block(content3, 'md5', allow_weak_eap) + content4 = toggle_freeradius_block(content3, 'md5', use_md5) if content4 == content: return False RADIUS_EAP_FILE.write_text(content4) - print(f"EAP: default_eap_type={eap_type}, tunneled_reply={tr_val}, allow_weak_eap={allow_weak_eap}") + print(f"EAP: default_eap_type={eap_type}, tunneled_reply={tr_val}") return True