def set_wifi_config(ssid: str, psk: str, bssid: str) -> None: run_set_cmd(settings.system.net.wifi.set_cmd, cmd_name='WiFi config', exc_class=NetError, log_values=False, ssid=ssid, psk=psk, bssid=bssid)
def set_ip_config(address: str, netmask: str, gateway: str, dns: str) -> None: run_set_cmd(settings.system.net.ip.set_cmd, cmd_name='IP config', exc_class=NetError, address=address, netmask=netmask, gateway=gateway, dns=dns)
def set_ip_config(ip: str, mask: str, gw: str, dns: str) -> None: run_set_cmd(settings.system.net.ip.set_cmd, cmd_name='IP config', exc_class=NetError, ip=ip, mask=mask, gw=gw, dns=dns)
def set_attrs(attrs: Attributes, ignore_extra: bool = False) -> bool: core_device_attrs = sys.modules[__name__] reboot_required = False attrdefs = get_attrdefs() wifi_attrs = {} ip_attrs = {} for n, value in attrs.items(): # A few attributes may carry sensitive information, so treat them separately and do not log their values if n.count('password') or n == 'wifi_key': logger.debug('setting device attribute %s', n) else: logger.debug('setting device attribute %s = %s', n, json_utils.dumps(value)) try: attrdef = attrdefs[n] except KeyError: if ignore_extra: continue else: raise if not attrdef.get('modifiable'): if not ignore_extra: raise DeviceAttributeError('attribute-not-modifiable', n) # Treat passwords separately, as they are not persisted as given, but hashed first if n.endswith('_password') and hasattr(core_device_attrs, f'{n}_hash'): # Call password set command, if available if settings.core.passwords.set_cmd: run_set_cmd(settings.core.passwords.set_cmd, cmd_name='password', log_values=False, username=n[:-9], password=value) value = hashlib.sha256(value.encode()).hexdigest() n += '_hash' setattr(core_device_attrs, n, value) continue elif n.endswith('_password_hash') and hasattr(core_device_attrs, n): # FIXME: Password set command cannot be called with hash and we don't have clear-text password here. # A solution would be to use sha256 crypt algorithm w/o salt for Unix password (watch for the special # alphabet and for number of rounds defaulting to 5000) setattr(core_device_attrs, n, value) continue persisted = attrdef.get('persisted', attrdef.get('modifiable')) if persisted: setattr(core_device_attrs, n, value) if n == 'name' and settings.core.device_name.set_cmd: run_set_cmd(settings.core.device_name.set_cmd, cmd_name='device name', name=value) elif n == 'date' and system.date.has_set_date_support(): date = datetime.datetime.utcfromtimestamp(value) system.date.set_date(date) elif n == 'timezone' and system.date.has_timezone_support(): system.date.set_timezone(value) elif n in ('wifi_ssid', 'wifi_key', 'wifi_bssid') and system.net.has_wifi_support(): k = n[5:] k = {'key': 'psk'}.get(k, k) wifi_attrs[k] = value elif n in ('ip_address', 'ip_netmask', 'ip_gateway', 'ip_dns') and system.net.has_ip_support(): k = n[3:] ip_attrs[k] = value if wifi_attrs: wifi_config = system.net.get_wifi_config() for k, v in wifi_attrs.items(): wifi_config[k] = v wifi_config = { k: v for k, v in wifi_config.items() if not k.endswith('_current') } system.net.set_wifi_config(**wifi_config) reboot_required = True if ip_attrs: ip_config = system.net.get_ip_config() for k, v in ip_attrs.items(): ip_config[k] = v ip_config = { k: v for k, v in ip_config.items() if not k.endswith('_current') } ip_config['netmask'] = str(ip_config['netmask']) system.net.set_ip_config(**ip_config) reboot_required = True return reboot_required
def set_timezone(timezone: str) -> None: run_set_cmd(settings.system.timezone.set_cmd, cmd_name='timezone', exc_class=DateError, timezone=timezone)
def set_date(date: datetime.datetime) -> None: date_str = date.strftime(settings.system.date.set_format) run_set_cmd(settings.system.date.set_cmd, cmd_name='date', exc_class=DateError, date=date_str)
def set_attrs(attrs: Attributes) -> bool: core_device_attrs = sys.modules[__name__] reboot_required = False for name, value in attrs.items(): # A few attributes may carry sensitive information, so treat them separately and do not log their values if name.count('password'): logger.debug('setting device attribute %s', name) elif name == 'network_wifi': logger.debug('setting device attribute %s = [hidden]', name) else: logger.debug('setting device attribute %s = %s', name, json_utils.dumps(value)) attrdef = ATTRDEFS[name] if not attrdef.get('modifiable'): raise DeviceAttributeError(f'attribute not modifiable: {name}') # Treat passwords separately, as they are not persisted as given, but hashed first if name.endswith('_password') and hasattr(core_device_attrs, name + '_hash'): # Call password set command, if available if settings.password_set_cmd: run_set_cmd(settings.password_set_cmd, cmd_name='password', log_values=False, username=name[:-9], password=value) value = hashlib.sha256(value.encode()).hexdigest() name += '_hash' setattr(core_device_attrs, name, value) continue persisted = attrdef.get('persisted', attrdef.get('modifiable')) if callable(persisted): persisted = persisted() if persisted: setattr(core_device_attrs, name, value) if name == 'name' and settings.device_name.set_cmd: run_set_cmd(settings.device_name.set_cmd, cmd_name='device name', name=value) elif name == 'date' and system.date.has_date_support(): try: date = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%SZ') except ValueError: raise DeviceAttributeError(f'invalid field: {name}') system.date.set_date(date) elif name == 'timezone' and system.date.has_timezone_support(): system.date.set_timezone(value) elif name == 'network_wifi' and system.net.has_network_wifi_support(): parts = value.split(':') i = 0 while i < len(parts): if len(parts[i]) and parts[i][-1] == '\\': parts[i] = parts[i][:-1] + ':' + parts[i + 1] del parts[i + 1] i += 1 parts = [p.replace('\\\\', '\\') for p in parts] while len(parts) < 3: parts.append('') ssid, psk, bssid = parts[:3] bssid = bssid.lower() bssid = re.sub('([a-f0-9]{2})', '\\1:', bssid).strip(':') # Add colons system.net.set_wifi_config(ssid, psk, bssid) reboot_required = True elif name == 'network_ip' and system.net.has_network_ip_support(): if value: parts = value.split(':') ip_mask, gw, dns = parts ip, mask = ip_mask.split('/') system.net.set_ip_config(ip, mask, gw, dns) else: system.net.set_ip_config(ip='', mask='', gw='', dns='') reboot_required = True return reboot_required