-
-
Notifications
You must be signed in to change notification settings - Fork 33
Add IPv6 configuration support #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,9 +11,12 @@ | |
| restart_card_network, | ||
| restart_routing_and_dhcp, | ||
| start_static_network, | ||
| start_static_ipv6_network, | ||
| enable_slaac, | ||
| disable_slaac, | ||
| wait_inet | ||
| ) | ||
| from NetworkMgr.query import get_interface_settings | ||
| from NetworkMgr.query import get_interface_settings, get_interface_settings_ipv6 | ||
| from subprocess import run | ||
|
|
||
| rcconf = open('/etc/rc.conf', 'r').read() | ||
|
|
@@ -46,20 +49,28 @@ def edit_ipv4_setting(self, widget): | |
| self.saveButton.set_sensitive(True) | ||
|
|
||
| def edit_ipv6_setting(self, widget, value): | ||
| if value == "SLAAC": | ||
| self.ipInputAddressEntry6.set_sensitive(False) | ||
| self.ipInputMaskEntry6.set_sensitive(False) | ||
| self.ipInputGatewayEntry6.set_sensitive(False) | ||
| self.prymary_dnsEntry6.set_sensitive(False) | ||
| self.searchEntry6.set_sensitive(False) | ||
| self.saveButton.set_sensitive(False) | ||
| else: | ||
| self.ipInputAddressEntry6.set_sensitive(True) | ||
| self.ipInputMaskEntry6.set_sensitive(True) | ||
| self.ipInputGatewayEntry6.set_sensitive(True) | ||
| self.prymary_dnsEntry6.set_sensitive(True) | ||
| self.searchEntry6.set_sensitive(True) | ||
| self.saveButton.set_sensitive(True) | ||
| if widget.get_active(): | ||
| self.method6 = value | ||
| # Check if GUI elements exist (may be called during init) | ||
| if not hasattr(self, 'ipInputAddressEntry6'): | ||
| return | ||
| if value == "SLAAC": | ||
| self.ipInputAddressEntry6.set_sensitive(False) | ||
| self.ipInputMaskEntry6.set_sensitive(False) | ||
| self.ipInputGatewayEntry6.set_sensitive(False) | ||
| self.prymary_dnsEntry6.set_sensitive(False) | ||
| self.searchEntry6.set_sensitive(False) | ||
| else: | ||
| self.ipInputAddressEntry6.set_sensitive(True) | ||
| self.ipInputMaskEntry6.set_sensitive(True) | ||
| self.ipInputGatewayEntry6.set_sensitive(True) | ||
| self.prymary_dnsEntry6.set_sensitive(True) | ||
| self.searchEntry6.set_sensitive(True) | ||
| # Enable save button if method changed | ||
| if self.method6 == self.currentSettings6["Assignment Method"]: | ||
| self.saveButton.set_sensitive(False) | ||
| else: | ||
| self.saveButton.set_sensitive(True) | ||
|
|
||
| def entry_trigger_save_button(self, widget, event): | ||
| self.saveButton.set_sensitive(True) | ||
|
|
@@ -92,6 +103,9 @@ def __init__(self, selected_nic=None): | |
| interfaceComboBox.set_active(active_index) | ||
| self.currentSettings = get_interface_settings(DEFAULT_NIC) | ||
| self.method = self.currentSettings["Assignment Method"] | ||
| # IPv6 settings | ||
| self.currentSettings6 = get_interface_settings_ipv6(DEFAULT_NIC) | ||
| self.method6 = self.currentSettings6["Assignment Method"] | ||
| interfaceComboBox.connect("changed", self.cbox_config_refresh, self.NICS) | ||
|
|
||
| # Build Label to sit in front of the ComboBox | ||
|
|
@@ -267,31 +281,37 @@ def __init__(self, selected_nic=None): | |
| interfaceBox6.pack_start(labelOne6, False, False, 0) | ||
| interfaceBox6.pack_end(interfaceComboBox6, True, True, 0) | ||
|
|
||
| # Add radio button to toggle DHCP or not | ||
| rb_slaac6 = Gtk.RadioButton.new_with_label(None, "SLAAC") | ||
| rb_slaac6.set_margin_top(15) | ||
| rb_slaac6.connect("toggled", self.edit_ipv6_setting, "SLAAC") | ||
| rb_manual6 = Gtk.RadioButton.new_with_label_from_widget( | ||
| rb_slaac6, "Manual") | ||
| rb_manual6.set_margin_top(15) | ||
| rb_manual6.join_group(rb_slaac6) | ||
| rb_manual6.connect("toggled", self.edit_ipv6_setting, "Manual") | ||
|
|
||
| radioButtonLabel6 = Gtk.Label(label="IPv4 Method:") | ||
| # Add radio button to toggle SLAAC or Manual | ||
| self.rb_slaac6 = Gtk.RadioButton.new_with_label(None, "SLAAC") | ||
| self.rb_slaac6.set_margin_top(15) | ||
| self.rb_slaac6.connect("toggled", self.edit_ipv6_setting, "SLAAC") | ||
| self.rb_manual6 = Gtk.RadioButton.new_with_label_from_widget( | ||
| self.rb_slaac6, "Manual") | ||
| self.rb_manual6.set_margin_top(15) | ||
| self.rb_manual6.join_group(self.rb_slaac6) | ||
| self.rb_manual6.connect("toggled", self.edit_ipv6_setting, "Manual") | ||
|
|
||
| # Set initial state based on current settings | ||
| if self.method6 == "Manual": | ||
| self.rb_manual6.set_active(True) | ||
| else: | ||
| self.rb_slaac6.set_active(True) | ||
|
|
||
| radioButtonLabel6 = Gtk.Label(label="IPv6 Method:") | ||
| radioButtonLabel6.set_margin_top(15) | ||
| radioButtonLabel6.set_margin_start(30) | ||
|
|
||
| radioBox6 = Gtk.Box(orientation=0, spacing=50) | ||
| radioBox6.set_homogeneous(False) | ||
| radioBox6.pack_start(radioButtonLabel6, False, False, 0) | ||
| radioBox6.pack_start(rb_slaac6, True, False, 0) | ||
| radioBox6.pack_end(rb_manual6, True, True, 0) | ||
| radioBox6.pack_start(self.rb_slaac6, True, False, 0) | ||
| radioBox6.pack_end(self.rb_manual6, True, True, 0) | ||
|
|
||
| # Add Manual Address Field | ||
| ipInputAddressLabel6 = Gtk.Label(label="Address") | ||
| ipInputAddressLabel6.set_margin_top(15) | ||
|
|
||
| ipInputMaskLabel6 = Gtk.Label(label="Subnet Mask") | ||
| ipInputMaskLabel6 = Gtk.Label(label="Prefix Length") | ||
| ipInputMaskLabel6.set_margin_top(15) | ||
|
|
||
| ipInputGatewayLabel6 = Gtk.Label(label="Gateway") | ||
|
|
@@ -301,7 +321,7 @@ def __init__(self, selected_nic=None): | |
| self.ipInputAddressEntry6.set_margin_start(15) | ||
| self.ipInputAddressEntry6.connect("key-release-event", self.entry_trigger_save_button) | ||
| self.ipInputMaskEntry6 = Gtk.Entry() | ||
| self.ipInputAddressEntry6.connect("key-release-event", self.entry_trigger_save_button) | ||
| self.ipInputMaskEntry6.connect("key-release-event", self.entry_trigger_save_button) | ||
| self.ipInputGatewayEntry6 = Gtk.Entry() | ||
| self.ipInputGatewayEntry6.set_margin_end(15) | ||
| self.ipInputGatewayEntry6.connect("key-release-event", self.entry_trigger_save_button) | ||
|
|
@@ -353,11 +373,13 @@ def __init__(self, selected_nic=None): | |
| searchBox6.pack_start(searchLabel6, False, False, 0) | ||
| searchBox6.pack_end(self.searchEntry6, True, True, 0) | ||
|
|
||
| self.ipInputAddressEntry6.set_sensitive(False) | ||
| self.ipInputMaskEntry6.set_sensitive(False) | ||
| self.ipInputGatewayEntry6.set_sensitive(False) | ||
| self.prymary_dnsEntry6.set_sensitive(False) | ||
| self.searchEntry6.set_sensitive(False) | ||
| # Set initial sensitivity based on current method (SLAAC = disabled, Manual = enabled) | ||
| manual_enabled = (self.method6 == "Manual") | ||
| self.ipInputAddressEntry6.set_sensitive(manual_enabled) | ||
| self.ipInputMaskEntry6.set_sensitive(manual_enabled) | ||
| self.ipInputGatewayEntry6.set_sensitive(manual_enabled) | ||
| self.prymary_dnsEntry6.set_sensitive(manual_enabled) | ||
| self.searchEntry6.set_sensitive(manual_enabled) | ||
|
|
||
| gridOne6 = Gtk.Grid() | ||
| gridOne6.set_column_homogeneous(True) | ||
|
|
@@ -370,7 +392,6 @@ def __init__(self, selected_nic=None): | |
| gridOne6.attach(ipEntryBox6, 0, 3, 4, 1) | ||
| gridOne6.attach(dnsEntryBox6, 0, 4, 4, 1) | ||
| gridOne6.attach(searchBox6, 0, 5, 4, 1) | ||
| gridOne6.set_sensitive(False) | ||
|
|
||
| # Build Notebook | ||
|
|
||
|
|
@@ -401,7 +422,7 @@ def __init__(self, selected_nic=None): | |
|
|
||
| # Apply Tab 2 content and formatting to the notebook | ||
| nb.append_page(gridOne6) | ||
| nb.set_tab_label_text(gridOne6, "IPv6 Settings WIP") | ||
| nb.set_tab_label_text(gridOne6, "IPv6 Settings") | ||
| # Put all the widgets together into one window | ||
| mainBox = Gtk.Box(orientation=1, spacing=0) | ||
| mainBox.pack_start(nb, True, True, 0) | ||
|
|
@@ -412,8 +433,11 @@ def __init__(self, selected_nic=None): | |
| # for the newly selected active interface. | ||
| def cbox_config_refresh(self, widget, nics): | ||
| # actions here need to refresh the values on the first two tabs. | ||
| self.currentSettings = get_interface_settings(nics[widget.get_active()]) | ||
| selected_nic = nics[widget.get_active()] | ||
| self.currentSettings = get_interface_settings(selected_nic) | ||
| self.currentSettings6 = get_interface_settings_ipv6(selected_nic) | ||
| self.update_interface_settings() | ||
| self.update_interface_settings_ipv6() | ||
|
|
||
| def update_interface_settings(self): | ||
| self.ipInputAddressEntry.set_text(self.currentSettings["Interface IP"]) | ||
|
|
@@ -427,6 +451,28 @@ def update_interface_settings(self): | |
| else: | ||
| self.rb_manual4.set_active(True) | ||
|
|
||
| def update_interface_settings_ipv6(self): | ||
| self.ipInputAddressEntry6.set_text(self.currentSettings6.get("Interface IPv6", "")) | ||
| self.ipInputMaskEntry6.set_text(str(self.currentSettings6.get("Prefix Length", "64"))) | ||
| self.ipInputGatewayEntry6.set_text(self.currentSettings6.get("Default Gateway", "")) | ||
| self.prymary_dnsEntry6.set_text(self.currentSettings6.get("DNS Server 1", "")) | ||
| self.searchEntry6.set_text(self.currentSettings6.get("Search Domain", "")) | ||
| self.method6 = self.currentSettings6.get("Assignment Method", "SLAAC") | ||
| if self.method6 == "Manual": | ||
| self.rb_manual6.set_active(True) | ||
| self.ipInputAddressEntry6.set_sensitive(True) | ||
| self.ipInputMaskEntry6.set_sensitive(True) | ||
| self.ipInputGatewayEntry6.set_sensitive(True) | ||
| self.prymary_dnsEntry6.set_sensitive(True) | ||
| self.searchEntry6.set_sensitive(True) | ||
| else: | ||
| self.rb_slaac6.set_active(True) | ||
| self.ipInputAddressEntry6.set_sensitive(False) | ||
| self.ipInputMaskEntry6.set_sensitive(False) | ||
| self.ipInputGatewayEntry6.set_sensitive(False) | ||
| self.prymary_dnsEntry6.set_sensitive(False) | ||
| self.searchEntry6.set_sensitive(False) | ||
|
|
||
| def commit_pending_changes(self, widget): | ||
| self.hide_window() | ||
| GLib.idle_add(self.update_system) | ||
|
|
@@ -479,8 +525,81 @@ def update_system(self): | |
| wait_inet(nic) | ||
| restart_routing_and_dhcp(nic) | ||
|
|
||
| # Apply IPv6 configuration | ||
| self.update_system_ipv6(nic) | ||
|
|
||
| self.destroy() | ||
|
|
||
| def update_system_ipv6(self, nic): | ||
| """Apply IPv6 configuration changes.""" | ||
| inet6 = self.ipInputAddressEntry6.get_text() | ||
| prefixlen = self.ipInputMaskEntry6.get_text() or "64" | ||
| gateway6 = self.ipInputGatewayEntry6.get_text() | ||
| dns6 = self.prymary_dnsEntry6.get_text() | ||
|
|
||
| if self.method6 == 'Manual': | ||
| # Static IPv6 configuration | ||
| ifconfig_ipv6 = f'ifconfig_{nic}_ipv6="inet6 {inet6} prefixlen {prefixlen}"' | ||
| self.update_rc_conf(ifconfig_ipv6) | ||
|
|
||
| # Disable rtsold for static configuration | ||
| self.update_rc_conf('rtsold_enable="NO"') | ||
|
|
||
| # Apply the static IPv6 address | ||
| if inet6: | ||
| disable_slaac(nic) | ||
| start_static_ipv6_network(nic, inet6, prefixlen) | ||
|
|
||
| # Set IPv6 default gateway if provided | ||
| if gateway6: | ||
| # Link-local addresses (fe80::) need interface suffix | ||
| if gateway6.lower().startswith('fe80:') and '%' not in gateway6: | ||
| gateway6_full = f'{gateway6}%{nic}' | ||
| else: | ||
| gateway6_full = gateway6 | ||
| # Save with interface suffix in rc.conf for persistence | ||
| self.update_rc_conf(f'ipv6_defaultrouter="{gateway6_full}"') | ||
| # Apply gateway immediately | ||
| run('route delete -inet6 default 2>/dev/null', shell=True) | ||
| run(f'route add -inet6 default {gateway6_full}', shell=True) | ||
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Add IPv6 DNS to resolv.conf if provided | ||
| if dns6: | ||
| self.add_ipv6_dns(dns6) | ||
| else: | ||
| # SLAAC configuration | ||
| ifconfig_ipv6 = f'ifconfig_{nic}_ipv6="inet6 accept_rtadv"' | ||
| self.update_rc_conf(ifconfig_ipv6) | ||
|
|
||
| # Enable rtsold for SLAAC | ||
| self.update_rc_conf('rtsold_enable="YES"') | ||
|
|
||
| # Remove static IPv6 gateway if switching to SLAAC | ||
| try: | ||
| self.remove_rc_conf_var('ipv6_defaultrouter') | ||
| except Exception: | ||
| pass # Variable may not exist | ||
|
|
||
| # Enable SLAAC | ||
| enable_slaac(nic) | ||
|
|
||
| def add_ipv6_dns(self, dns6): | ||
| """Add IPv6 DNS server to resolv.conf without removing existing entries.""" | ||
| resolv_path = '/etc/resolv.conf' | ||
| try: | ||
| with open(resolv_path, 'r') as f: | ||
| content = f.read() | ||
| # Check if this IPv6 DNS is already present | ||
| if f'nameserver {dns6}' not in content: | ||
| with open(resolv_path, 'a') as f: | ||
| f.write(f'nameserver {dns6}\n') | ||
|
Comment on lines
+586
to
+595
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (bug_risk): add_ipv6_dns blindly appends Because this only checks for exact text matches, changing the IPv6 DNS leaves the old entry in place and appends a new one. There’s also no validation of Suggested implementation: def add_ipv6_dns(self, dns6):
"""
Ensure resolv.conf has a single, valid IPv6 DNS nameserver entry.
- Validate dns6 as an IPv6 address.
- Replace the first existing IPv6 nameserver with dns6 and remove any
additional IPv6 nameserver entries.
- If no IPv6 nameserver exists, append one.
"""
resolv_path = '/etc/resolv.conf'
try:
# Validate that dns6 is a well-formed IPv6 address
try:
import ipaddress
ip = ipaddress.ip_address(dns6)
if ip.version != 6:
return # Not IPv6, do nothing
except Exception:
# Invalid IP or ipaddress not available; avoid writing bad entries
return
try:
with open(resolv_path, 'r') as f:
lines = f.readlines()
except FileNotFoundError:
lines = []
new_lines = []
ipv6_replaced = False
for line in lines:
stripped = line.strip()
if not stripped.startswith('nameserver'):
new_lines.append(line)
continue
parts = stripped.split()
if len(parts) != 2:
# Keep malformed or unexpected lines as-is
new_lines.append(line)
continue
_, addr = parts
# Try to classify existing nameserver IP (IPv4 vs IPv6)
try:
existing_ip = ipaddress.ip_address(addr)
except ValueError:
# If it doesn't parse, preserve it
new_lines.append(line)
continue
if existing_ip.version == 4:
# Always keep IPv4 nameservers untouched
new_lines.append(line)
else:
# IPv6 nameserver: replace the first, drop the rest
if not ipv6_replaced:
new_lines.append(f'nameserver {dns6}\n')
ipv6_replaced = True
# Subsequent IPv6 nameservers are skipped (pruned)
if not ipv6_replaced:
# No existing IPv6 nameserver: append a new one
new_lines.append(f'nameserver {dns6}\n')
with open(resolv_path, 'w') as f:
f.writelines(new_lines)
except Exception:
# resolv.conf may be managed by dhclient or be otherwise immutable
passTo keep imports clean and avoid importing inside the function, consider adding at the top of <<<<<<< SEARCH existing imports...======= existing imports...import ipaddress
If you make this top-level import, remove the inner |
||
| except Exception: | ||
| pass # resolv.conf may be managed by dhclient | ||
|
|
||
| def remove_rc_conf_var(self, varname): | ||
| """Remove a variable from rc.conf using sysrc.""" | ||
| run(f'sysrc -x {varname}', shell=True) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. Source: opengrep
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| def hide_window(self): | ||
| self.hide() | ||
| return False | ||
|
|
@@ -492,13 +611,17 @@ def update_rc_conf(self, line): | |
| run(f'sysrc {line}', shell=True) | ||
|
|
||
| def remove_rc_conf_line(self, line): | ||
| with open('/etc/rc.conf', "r+") as rc_conf: | ||
| lines = rc_conf.readlines() | ||
| rc_conf.seek(0) | ||
| idx = lines.index(line) | ||
| lines.pop(idx) | ||
| rc_conf.truncate() | ||
| rc_conf.writelines(lines) | ||
| try: | ||
| with open('/etc/rc.conf', "r+") as rc_conf: | ||
| lines = rc_conf.readlines() | ||
| if line in lines: | ||
| rc_conf.seek(0) | ||
| idx = lines.index(line) | ||
| lines.pop(idx) | ||
| rc_conf.truncate() | ||
| rc_conf.writelines(lines) | ||
| except (ValueError, FileNotFoundError): | ||
| pass # Line doesn't exist, nothing to remove | ||
|
|
||
|
|
||
| def network_card_configuration(default_int): | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -317,6 +317,67 @@ def start_static_network(netcard, inet, netmask): | |||||
| run('service routing restart', shell=True) | ||||||
|
|
||||||
|
|
||||||
| # IPv6 configuration functions | ||||||
|
|
||||||
| def start_static_ipv6_network(netcard, inet6, prefixlen): | ||||||
| """Configure a static IPv6 address on the given interface.""" | ||||||
| run(f'ifconfig {netcard} inet6 {inet6} prefixlen {prefixlen}', shell=True) | ||||||
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| sleep(1) | ||||||
| run('service routing restart', shell=True) | ||||||
|
|
||||||
|
|
||||||
| def enable_slaac(netcard): | ||||||
| """Enable SLAAC (Stateless Address Autoconfiguration) on the interface | ||||||
| by toggling accept_rtadv and soliciting router advertisements.""" | ||||||
| # First disable, then re-enable to ensure clean state | ||||||
| run(f'ifconfig {netcard} inet6 -accept_rtadv', shell=True) | ||||||
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| sleep(0.5) | ||||||
| # Enable accept_rtadv for SLAAC | ||||||
| run(f'ifconfig {netcard} inet6 accept_rtadv', shell=True) | ||||||
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| # Start rtsold to solicit router advertisements | ||||||
| run(f'rtsol {netcard}', shell=True) | ||||||
sourcery-ai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.subprocess-shell-true): Found 'subprocess' function 'run' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead.
Suggested change
Source: opengrep |
||||||
|
|
||||||
|
|
||||||
| def disable_slaac(netcard): | ||||||
| """Disable SLAAC on the interface.""" | ||||||
| run(f'ifconfig {netcard} inet6 -accept_rtadv', shell=True) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. Source: opengrep
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.subprocess-shell-true): Found 'subprocess' function 'run' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead.
Suggested change
Source: opengrep |
||||||
|
|
||||||
|
|
||||||
| def get_ipv6_addresses(netcard): | ||||||
| """Get all IPv6 addresses configured on the interface. | ||||||
| Returns list of tuples: (address, prefixlen).""" | ||||||
| try: | ||||||
| output = check_output(f'ifconfig {netcard}', shell=True, universal_newlines=True) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'check_output' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. Source: opengrep
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| # Match all inet6 addresses with their prefix lengths | ||||||
| addresses = re.findall(r'inet6 ([0-9a-fA-F:]+)%?\S* prefixlen (\d+)', output) | ||||||
| return [(addr, int(prefixlen)) for addr, prefixlen in addresses] | ||||||
| except Exception: | ||||||
| return [] | ||||||
|
|
||||||
|
|
||||||
| def has_slaac_enabled(netcard): | ||||||
| """Check if SLAAC (accept_rtadv) is enabled on the interface.""" | ||||||
| try: | ||||||
| output = check_output(f'ifconfig {netcard}', shell=True, universal_newlines=True) | ||||||
ericbsd marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.subprocess-shell-true): Found 'subprocess' function 'check_output' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead.
Suggested change
Source: opengrep |
||||||
| return 'ACCEPT_RTADV' in output | ||||||
| except Exception: | ||||||
| return False | ||||||
|
|
||||||
|
|
||||||
| def get_ipv6_gateway(): | ||||||
| """Get the default IPv6 gateway from routing table.""" | ||||||
| try: | ||||||
| output = check_output('netstat -rn -f inet6', shell=True, universal_newlines=True) | ||||||
| for line in output.splitlines(): | ||||||
| if line.startswith('default'): | ||||||
| parts = line.split() | ||||||
| if len(parts) >= 2: | ||||||
| return parts[1] | ||||||
| except Exception: | ||||||
| pass | ||||||
| return "" | ||||||
|
|
||||||
|
|
||||||
| def startnetworkcard(netcard): | ||||||
| run(f'service netif start {netcard}', shell=True) | ||||||
| sleep(1) | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.