Development
This commit is contained in:
parent
34abbae32e
commit
a94863e25a
4 changed files with 77 additions and 4 deletions
|
|
@ -69,7 +69,13 @@ def auth_mode_save():
|
||||||
eap_protocol = request.form.get('eap_protocol', 'eap_peap')
|
eap_protocol = request.form.get('eap_protocol', 'eap_peap')
|
||||||
if eap_protocol not in ('eap_peap', 'eap_ttls', 'eap_md5'):
|
if eap_protocol not in ('eap_peap', 'eap_ttls', 'eap_md5'):
|
||||||
eap_protocol = 'eap_peap'
|
eap_protocol = 'eap_peap'
|
||||||
tunneled_reply = 'tunneled_reply' in request.form
|
tunneled_reply = 'tunneled_reply' in request.form
|
||||||
|
inner_protocol = request.form.get('inner_protocol', '')
|
||||||
|
|
||||||
|
_valid_inner = {
|
||||||
|
'eap_peap': {'mschapv2', 'md5', 'gtc'},
|
||||||
|
'eap_ttls': {'md5', 'mschapv2', 'gtc'},
|
||||||
|
}
|
||||||
|
|
||||||
cfg = load_config()
|
cfg = load_config()
|
||||||
before = copy.deepcopy(cfg.get('radius', {}).get('options', {}))
|
before = copy.deepcopy(cfg.get('radius', {}).get('options', {}))
|
||||||
|
|
@ -77,9 +83,14 @@ def auth_mode_save():
|
||||||
if auth_mode == 'eap_password':
|
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')
|
after['tunneled_reply'] = tunneled_reply and eap_protocol in ('eap_peap', 'eap_ttls')
|
||||||
|
if eap_protocol in _valid_inner and inner_protocol in _valid_inner[eap_protocol]:
|
||||||
|
after['inner_protocol'] = inner_protocol
|
||||||
|
else:
|
||||||
|
after.pop('inner_protocol', None)
|
||||||
else:
|
else:
|
||||||
after.pop('eap_protocol', None)
|
after.pop('eap_protocol', None)
|
||||||
after.pop('tunneled_reply', None)
|
after.pop('tunneled_reply', None)
|
||||||
|
after.pop('inner_protocol', None)
|
||||||
cfg.setdefault('radius', {})['options'] = after
|
cfg.setdefault('radius', {})['options'] = after
|
||||||
|
|
||||||
changes = diff_fields(before, after)
|
changes = diff_fields(before, after)
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,23 @@
|
||||||
"options": "%RADIUS_EAP_PROTOCOL_OPTIONS%",
|
"options": "%RADIUS_EAP_PROTOCOL_OPTIONS%",
|
||||||
"hint": "_"
|
"hint": "_"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "raw_html",
|
||||||
|
"html": "<div id=\"eap-inner-row\">"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "field",
|
||||||
|
"label": "Inner Protocol",
|
||||||
|
"name": "inner_protocol",
|
||||||
|
"input_type": "select",
|
||||||
|
"value": "%RADIUS_INNER_PROTOCOL%",
|
||||||
|
"options": "%RADIUS_INNER_PROTOCOL_OPTIONS%",
|
||||||
|
"hint": "_"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "raw_html",
|
||||||
|
"html": "</div>"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "raw_html",
|
"type": "raw_html",
|
||||||
"html": "<div id=\"eap-tunneled-row\">"
|
"html": "<div id=\"eap-tunneled-row\">"
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,21 @@ def collect_tokens(cfg):
|
||||||
{'value': 'eap_ttls', 'label': 'EAP-TTLS'},
|
{'value': 'eap_ttls', 'label': 'EAP-TTLS'},
|
||||||
{'value': 'eap_md5', 'label': 'EAP-MD5'},
|
{'value': 'eap_md5', 'label': 'EAP-MD5'},
|
||||||
])
|
])
|
||||||
|
_eap_proto = fr_opts.get('eap_protocol', 'eap_peap')
|
||||||
|
_inner_opts_peap = [
|
||||||
|
{'value': 'mschapv2', 'label': 'MSCHAPv2 (Default)'},
|
||||||
|
{'value': 'md5', 'label': 'MD5'},
|
||||||
|
{'value': 'gtc', 'label': 'GTC'},
|
||||||
|
]
|
||||||
|
_inner_opts_ttls = [
|
||||||
|
{'value': 'md5', 'label': 'MD5 (Default)'},
|
||||||
|
{'value': 'mschapv2', 'label': 'MSCHAPv2'},
|
||||||
|
{'value': 'gtc', 'label': 'GTC'},
|
||||||
|
]
|
||||||
|
tokens['RADIUS_INNER_PROTOCOL'] = fr_opts.get('inner_protocol', '')
|
||||||
|
tokens['RADIUS_INNER_PROTOCOL_OPTIONS'] = json.dumps(
|
||||||
|
_inner_opts_ttls if _eap_proto == 'eap_ttls' else _inner_opts_peap
|
||||||
|
)
|
||||||
pro_suffix = '' if PRO_LICENSE else ' (PRO REQUIRED)'
|
pro_suffix = '' if PRO_LICENSE else ' (PRO REQUIRED)'
|
||||||
pro_disabled = not PRO_LICENSE
|
pro_disabled = not PRO_LICENSE
|
||||||
tokens['RADIUS_AUTH_MODE_OPTIONS'] = json.dumps([
|
tokens['RADIUS_AUTH_MODE_OPTIONS'] = json.dumps([
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,29 @@ def toggle_freeradius_block(content, block_name, enable):
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def _patch_setting_in_block(content, block_name, key, value):
|
||||||
|
"""Patch `key = value` inside the first occurrence of `block_name { ... }`."""
|
||||||
|
lines = content.splitlines(keepends=True)
|
||||||
|
in_block = False
|
||||||
|
depth = 0
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if not in_block:
|
||||||
|
if re.match(r'\s*' + re.escape(block_name) + r'\s*\{', line):
|
||||||
|
in_block = True
|
||||||
|
depth = 1
|
||||||
|
else:
|
||||||
|
depth += line.count('{') - line.count('}')
|
||||||
|
if depth <= 0:
|
||||||
|
break
|
||||||
|
if re.match(r'\s*' + re.escape(key) + r'\s*=', line):
|
||||||
|
lines[i] = re.sub(
|
||||||
|
r'(' + re.escape(key) + r'\s*=\s*)\S+',
|
||||||
|
rf'\g<1>{value}', line, count=1
|
||||||
|
)
|
||||||
|
return ''.join(lines)
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
def set_freeradius_eap(data):
|
def set_freeradius_eap(data):
|
||||||
"""Patch EAP config for eap_protocol and tunneled_reply settings.
|
"""Patch EAP config for eap_protocol and tunneled_reply settings.
|
||||||
Returns True if the file was modified, False if unchanged or not found.
|
Returns True if the file was modified, False if unchanged or not found.
|
||||||
|
|
@ -265,10 +288,17 @@ def set_freeradius_eap(data):
|
||||||
# Inner blocks (e.g. peap's tunneled default) must not be touched.
|
# 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)
|
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', use_md5)
|
content4 = toggle_freeradius_block(content3, 'md5', use_md5)
|
||||||
|
|
||||||
|
inner_protocol = opts.get('inner_protocol', '')
|
||||||
|
_valid_inner = {'eap_peap': {'mschapv2', 'md5', 'gtc'}, 'eap_ttls': {'md5', 'mschapv2', 'gtc'}}
|
||||||
|
if eap_protocol in _valid_inner and inner_protocol in _valid_inner[eap_protocol]:
|
||||||
|
inner_block = 'peap' if eap_protocol == 'eap_peap' else 'ttls'
|
||||||
|
content4 = _patch_setting_in_block(content4, inner_block, 'default_eap_type', inner_protocol)
|
||||||
|
|
||||||
if content4 == content:
|
if content4 == content:
|
||||||
return False
|
return False
|
||||||
RADIUS_EAP_FILE.write_text(content4)
|
RADIUS_EAP_FILE.write_text(content4)
|
||||||
print(f"EAP: default_eap_type={eap_type}, tunneled_reply={tr_val}")
|
print(f"EAP: default_eap_type={eap_type}, inner={inner_protocol or '(default)'}, tunneled_reply={tr_val}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue