예제 #1
0
def setup_dnsmasq():
    if get_dnsmasq_setup_status():
        return

    print("Installing Dnsmasq...")
    os.system('apt-get -yq install dnsmasq')
    print("... done!")

    print("Setting up dnsmasq config...")

    interface = env.var("ONEIOT_C_NETWORK_INTERFACE")
    static_ip = env.var("ONEIOT_C_STATIC_IP")
    static_ip_split = static_ip.split(".")

    dnsmasq = Parsers.DNSMasqParser("/etc/dnsmasq.conf")
    dnsmasq.set_options(
        {
            'interface':
            interface,
            'server':
            '8.8.8.8',
            'dhcp-range':
            f'{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.2,{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.254,255.255.255.0,24h',
        }, ['bind-interfaces', 'domain-needed', 'bogus-priv'])
    dnsmasq.save()

    print(".. done!")
예제 #2
0
def get_dnsmasq_setup_status():
    interface = env.var("ONEIOT_C_NETWORK_INTERFACE")
    static_ip = env.var("ONEIOT_C_STATIC_IP")
    static_ip_split = static_ip.split(".")

    if not path.exists("/etc/dnsmasq.conf"):
        return False

    dnsmasq = Parsers.DNSMasqParser("/etc/dnsmasq.conf")

    result = 'interface' in dnsmasq.option_dict
    result = result and 'server' in dnsmasq.option_dict
    result = result and 'dhcp-range' in dnsmasq.option_dict
    if not result:
        return result

    result = dnsmasq.option_dict['interface'] == interface
    result = result and dnsmasq.option_dict['server'] == '8.8.8.8'
    result = result and dnsmasq.option_dict[
        'dhcp-range'] == f'{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.2,{static_ip_split[0]}.{static_ip_split[1]}.{static_ip_split[2]}.254,255.255.255.0,24h'
    result = result and 'bind-interfaces' in dnsmasq.option_list
    result = result and 'domain-needed' in dnsmasq.option_list
    result = result and 'bogus-priv' in dnsmasq.option_list

    return result
예제 #3
0
def setup_hostapd():
    if get_hostapd_setup_status():
        print(get_hostapd_setup_status())
        return

    print("Installing Hostapd...")
    os.system('apt-get -yq install hostapd')
    print("... done!")

    print("Setting up hostapd config...")

    interface = env.var("ONEIOT_C_NETWORK_INTERFACE")
    ssid = env.var("ONEIOT_C_NETWORK_SSID")
    psk = prompt.query(
        'Network Password (8-63 alphanumeric chars)',
        validators=[
            validators.RegexValidator(
                regex=r"([a-z]|[0-9]){8,63}",
                message="Password must be 8 to 63 alphanumeric characters")
        ])

    if not path.exists("/etc/hostapd"):
        os.mkdir("/etc/hostapd")

    hostapd = Parsers.HostAPDParser("/etc/hostapd/hostapd.conf",
                                    "/etc/default/hostapd")
    hostapd.set_options({
        'interface': interface,
        'driver': 'nl80211',
        'ssid': ssid,
        'hw_mode': 'g',
        'channel': '6',
        'ieee80211n': '1',
        'wmm_enabled': '1',
        'ht_capab': '[HT40][SHORT-GI-20][DSSS_CCK-40]',
        'macaddr_acl': '0',
        'auth_algs': '1',
        'ignore_broadcast_ssid': '0',
        'wpa': '2',
        'wpa_key_mgmt': 'WPA-PSK',
        'wpa_passphrase': psk,
        'rsn_pairwise': 'CCMP'
    })
    hostapd.save()

    hostapd.set_master_options({
        'DAEMON_CONF': '"/etc/hostapd/hostapd.conf"',
    })
    hostapd.save_master()

    os.system('systemctl unmask hostapd')
    os.system('update-rc.d hostapd enable')

    print(".. done!")
예제 #4
0
def setup_static_ip():
    if get_static_ip_set_up_status():
        return
    print("Setting up DHCPCD config...")
    dhcpcd = Parsers.DHCPDParser("/etc/dhcpcd.conf")
    interface = env.var("ONEIOT_C_NETWORK_INTERFACE")
    static_ip = env.var("ONEIOT_C_STATIC_IP")
    dhcpcd.modifyInterface(interface,
                           [['static', f'ip_address={static_ip}/24'],
                            ['nohook', 'wpa_supplicant']])
    dhcpcd.save()
    print(".. done!")
예제 #5
0
def get_static_ip_respected_status():
    interface = env.var("ONEIOT_C_NETWORK_INTERFACE")
    ifconfig = netifaces.ifaddresses(interface)

    if netifaces.AF_INET in ifconfig:
        if len(ifconfig[netifaces.AF_INET]) > 0:
            return ifconfig[netifaces.AF_INET][0]['addr'] == env.var(
                "ONEIOT_C_STATIC_IP")
        else:
            return False
    else:
        return False
예제 #6
0
def get_static_ip_set_up_status():
    dhcpcd = Parsers.DHCPDParser("/etc/dhcpcd.conf")
    interface = env.var("ONEIOT_C_NETWORK_INTERFACE")
    static_ip = env.var("ONEIOT_C_STATIC_IP")
    if interface in dhcpcd.interfaces:
        static_present = False
        nohook_present = False
        for option in dhcpcd.interfaces[interface]:
            if option[0] == "static":
                static_present = option[1] == f"ip_address={static_ip}/24"
            if option[0] == "nohook":
                nohook_present = option[1] == f"wpa_supplicant"
        return static_present and nohook_present
    else:
        return False
예제 #7
0
def main():
    HOST, PORT = "localhost", int(env.var("ONEIOT_C_PORT", 1102))
    server = ThreadedTCPServer((HOST, PORT), service)
    try:
        server.serve_forever()
    except Exception as e:
        server.shutdown()
예제 #8
0
def get_hostapd_setup_status():
    interface = env.var("ONEIOT_C_NETWORK_INTERFACE")
    ssid = env.var("ONEIOT_C_NETWORK_SSID")

    if not path.exists("/etc/hostapd/hostapd.conf"):
        return False
    if not path.exists("/etc/default/hostapd"):
        return False

    hostapd = Parsers.HostAPDParser("/etc/hostapd/hostapd.conf",
                                    "/etc/default/hostapd")

    options = hostapd.options
    print(options)
    print(ssid)
    result = options['interface'] == interface
    result = result and options['driver'] == 'nl80211'
    result = result and options['ssid'] == ssid
    result = result and options['hw_mode'] == 'g'
    result = result and options['channel'] == '6'
    result = result and options['ieee80211n'] == '1'
    result = result and options['wmm_enabled'] == '1'
    result = result and options[
        'ht_capab'] == '[HT40][SHORT-GI-20][DSSS_CCK-40]'
    result = result and options['macaddr_acl'] == '0'
    result = result and options['auth_algs'] == '1'
    result = result and options['ignore_broadcast_ssid'] == '0'
    result = result and options['wpa'] == '2'
    result = result and options['wpa_key_mgmt'] == 'WPA-PSK'
    result = result and options['wpa_passphrase'] == env.network_password()
    result = result and len(env.network_password()) >= 8
    result = result and len(env.network_password()) <= 63
    result = result and options['rsn_pairwise'] == 'CCMP'

    options_master = hostapd.options_master
    if 'DAEMON_CONF' not in options_master:
        return False
    result = result and options_master[
        'DAEMON_CONF'] == '"/etc/hostapd/hostapd.conf"'

    return result
예제 #9
0
def get_interface_selected_status():
    interfaces = netifaces.interfaces()
    return env.var("ONEIOT_C_NETWORK_INTERFACE") in interfaces
예제 #10
0
def addDevice(id, data, eb):
    stage = id.split('.')[-1]
    token = id.split('.')[-2]
    if token not in addDeviceRequests:
        return
    requestData = addDeviceRequests[token]
    if stage == 'unplug_device':
        requestData['ports'] = [
            x.name for x in serial.tools.list_ports.comports()
        ]
        eb.send(f'device_manager.add_device.{token}.log', {
            'type': 'info',
            'message': f'Found COM ports: {requestData["ports"]}'
        })
        eb.send(f'device_manager.add_device.{token}.confirm',
                {'next_step': steps[2]})
    if stage == 'plug_in_device':
        success = False
        newPorts = [x.name for x in serial.tools.list_ports.comports()]
        portsDiff = list(set(newPorts) - set(requestData['ports']))

        if len(portsDiff) == 0:
            eb.send(
                f'device_manager.add_device.{token}.log', {
                    'type': 'error',
                    'message': f'Could not find device. Resetting to step 1'
                })
            eb.send(f'device_manager.add_device.{token}.confirm',
                    {'next_step': steps[1]})
        elif len(portsDiff) > 1:
            eb.send(
                f'device_manager.add_device.{token}.log', {
                    'type':
                    'error',
                    'message':
                    f'Other devices have been plugged in alongside target device. Resetting to step 1'
                })
            eb.send(f'device_manager.add_device.{token}.confirm',
                    {'next_step': steps[1]})
        else:
            requestData['port'] = portsDiff[0]
            eb.send(
                f'device_manager.add_device.{token}.log', {
                    'type': 'info',
                    'message': f'Found device on {requestData["port"]}'
                })
            # Flash Device
            try:
                # Connect
                logToEB(eb, f'device_manager.add_device.{token}.log', 'info',
                        f'Connecting to device on {requestData["port"]}...')
                conn = serial.Serial('/dev/' + requestData['port'],
                                     115200,
                                     timeout=1)
                logToEB(eb, f'device_manager.add_device.{token}.log', 'info',
                        f'Connected')

                # Setup WebRepl config file
                logToEB(eb, f'device_manager.add_device.{token}.log', 'info',
                        f'Setting up WebREPL config file')
                passw = uuid.uuid1().hex
                requestData['webREPLPasswd'] = passw
                conn.writelines([
                    str.encode(
                        'webreplConf = open("webrepl_cfg.py", "wb")\r\n')
                ])
                conn.writelines(
                    [str.encode(f'webreplConf.write("PASS=\'{passw}\'")\r\n')])
                conn.writelines([str.encode('webreplConf.close()\r\n')])

                # Setup boot file
                logToEB(eb, f'device_manager.add_device.{token}.log', 'info',
                        f'Setting up boot.py')
                ssid = env.var('ONEIOT_C_NETWORK_SSID')
                passw = env.network_password()
                conn.writelines(
                    [str.encode('boot = open("boot.py", "wb")\r\n')])
                conn.writelines(
                    [str.encode('boot.write("import network\\n")\r\n')])
                conn.writelines([
                    str.encode(
                        'boot.write("wlan=network.WLAN(network.STA_IF)\\n")\r\n'
                    )
                ])
                conn.writelines(
                    [str.encode('boot.write("wlan.active(True)\\n")\r\n')])
                conn.writelines([
                    str.encode(
                        f'boot.write("wlan.connect(\'{ssid}\', \'{passw}\')\\n")\r\n'
                    )
                ])
                #conn.writelines([str.encode('boot.write("wlan.ifconfig((\'' + device.ip + '\',\'255.255.255.0\',\'192.168.4.1\',\'8.8.8.8\'))\\n")\r\n')])
                conn.writelines(
                    [str.encode('boot.write("import webrepl\\n")\r\n')])
                conn.writelines(
                    [str.encode('boot.write("webrepl.start()\\n")\r\n')])
                conn.writelines([str.encode('boot.close()\r\n')])

                # Reset
                logToEB(eb, f'device_manager.add_device.{token}.log', 'info',
                        f'Resetting device on {requestData["port"]}')
                conn.writelines([str.encode('import machine\r\n')])
                conn.writelines([str.encode('machine.reset()\r\n')])
                success = True
            except Exception as err:
                logToEB(eb, f'device_manager.add_device.{token}.log', 'error',
                        str(err))
            finally:
                # Close Serial Connection
                logToEB(eb, f'device_manager.add_device.{token}.log', 'info',
                        f'Closing connection on {requestData["port"]}...')
                conn.close()
                logToEB(eb, f'device_manager.add_device.{token}.log', 'info',
                        f'Closed')
        if success:
            eb.send(f'device_manager.add_device.{token}.confirm',
                    {'next_step': steps[3]})
    if stage == "naming":
        if not path.exists(f'{path.expanduser("~")}/.oneIot/devices'):
            os.mkdir(f'{path.expanduser("~")}/.oneIot/devices')

        if 'id' not in data:
            logToEB(eb, f'device_manager.add_device.{token}.log', 'error',
                    'Device ID not provided')
            eb.send(f'device_manager.add_device.{token}.confirm',
                    {'next_step': steps[3]})
        elif not re.match("^[a-z_-]*$", data['id']):
            logToEB(
                eb, f'device_manager.add_device.{token}.log', 'error',
                f'Device ID can only contain a-z (lowercase), dashes and underscores.'
            )
            eb.send(f'device_manager.add_device.{token}.confirm',
                    {'next_step': steps[3]})
        elif path.exists(
                f'{path.expanduser("~")}/.oneIot/devices/{data["id"]}.json'):
            logToEB(eb, f'device_manager.add_device.{token}.log', 'error',
                    f'Device ID "{data["id"]}" already taken')
            eb.send(f'device_manager.add_device.{token}.confirm',
                    {'next_step': steps[3]})
        else:
            with open(
                    f'{path.expanduser("~")}/.oneIot/devices/{data["id"]}.json',
                    'w') as deviceFile:
                json.dump(
                    {
                        'id': data["id"],
                        'webprel_password': requestData['webREPLPasswd']
                    }, deviceFile)
            eb.send(f'device_manager.add_device.{token}.complete')
            del addDeviceRequests[token]