esp8266/scripts/webrepl: Add "first connection" mode to setup password.

If there's no port_config.py file, or it lacks WEBREPL_PASS variable,
"initial setup mode" will be entered on first WebREPLconnection. User
will be asked for password, which will be written to
port_config.WEBREPL_PASS, and system restarted to work in normal mode
with password active.
This commit is contained in:
Paul Sokolovsky 2016-04-30 20:41:09 +03:00
parent 962d5a987f
commit c1d1c562f3
2 changed files with 88 additions and 3 deletions

View File

@ -9,7 +9,7 @@ import _webrepl
listen_s = None
client_s = None
def setup_conn(port):
def setup_conn(port, accept_handler):
global listen_s, client_s
listen_s = socket.socket()
listen_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@ -19,7 +19,7 @@ def setup_conn(port):
listen_s.bind(addr)
listen_s.listen(1)
listen_s.setsockopt(socket.SOL_SOCKET, 20, accept_conn)
listen_s.setsockopt(socket.SOL_SOCKET, 20, accept_handler)
for i in (network.AP_IF, network.STA_IF):
iface = network.WLAN(i)
if iface.active():
@ -51,4 +51,12 @@ def stop():
def start(port=8266):
stop()
setup_conn(port)
try:
import port_config
_webrepl.password(port_config.WEBREPL_PASS)
setup_conn(port, accept_conn)
print("Started webrepl in normal mode")
except:
import webrepl_setup
setup_conn(port, webrepl_setup.handle_conn)
print("Started webrepl in setup mode")

View File

@ -0,0 +1,77 @@
import sys
import socket
import time
from websocket import *
import websocket_helper
def setup_server():
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ai = socket.getaddrinfo("0.0.0.0", 8266)
addr = ai[0][4]
s.bind(addr)
s.listen(1)
return s
def getpass(stream, prompt):
stream.write(prompt)
passwd = b""
while 1:
c = stream.read(1)
if c in (b"\r", b"\n"):
stream.write("\r\n")
return passwd
passwd += c
# stream.write("*")
def handle_conn(listen_sock):
cl, remote_addr = listen_sock.accept()
print("""
First-time WebREPL connection has been received. WebREPL initial setup
will now start over this connection. During setup, UART REPL will be
non-responsive. After setup finishes, the board will be rebooted. In
case of error during setup, current session will continue.
If you receive this message unexpectedly, it may mean that your WebREPL
connection is being hacked (power off board if unsure).
""")
websocket_helper.server_handshake(cl)
ws = websocket(cl)
ws.write("""\
Welcome to MicroPython WebREPL!\r
\r
This is the first time you connect to WebREPL, so please set a password\r
to use for the following WebREPL sessions. Once you enter the password\r
twice, your board will reboot with WebREPL running in active mode. On\r
some boards, you may need to press reset button or reconnect power.\r
\r
""")
while 1:
passwd1 = getpass(ws, "New password: ")
passwd2 = getpass(ws, "Confirm password: ")
if passwd1 == passwd2:
break
ws.write("Passwords do not match\r\n")
with open("port_config.py", "w") as f:
f.write("WEBREPL_PASS = %r\n" % passwd1.decode("ascii"))
ws.write("Password successfully set, restarting...\r\n")
cl.close()
time.sleep(2)
import machine
machine.reset()
def test():
s = setup_server()
handle_conn(s)