commit
f8ffbcfd0f
@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Script to reset a forgotten root password (SSH/TELNET).
|
||||
Attempts to connect via SSH (if password is saved in config) or via TELNET,
|
||||
then sets a new password.
|
||||
|
||||
Usage:
|
||||
./run.sh reset_password.py [new_password]
|
||||
./run.sh reset_password.py --ip 192.168.31.1 new_password
|
||||
|
||||
Requirements:
|
||||
- The device must be on the same network
|
||||
- Either SSH (with known password) OR TELNET (usually password "root") must be accessible
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
|
||||
import xmir_base
|
||||
import gateway
|
||||
from gateway import die
|
||||
|
||||
|
||||
def reset_password_via_gateway(gw, new_passw):
|
||||
"""Resets the password using an already connected gateway (SSH or TELNET)."""
|
||||
gw.run_cmd('echo -e "{new_passw}\\n{new_passw}" | passwd root'.format(new_passw=new_passw))
|
||||
time.sleep(0.5)
|
||||
if gw.use_ssh:
|
||||
gw.ssh_close()
|
||||
else:
|
||||
gw.shutdown()
|
||||
if gw.check_ssh(gw.ip_addr, gw.ssh_port, new_passw) != 0:
|
||||
die('Failed to verify the new password via SSH')
|
||||
gw.passw = new_passw
|
||||
print("Root password successfully changed.")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1 and sys.argv[1] == '--ip':
|
||||
if len(sys.argv) < 4:
|
||||
die("Usage: reset_password.py --ip <IP> <new_password>")
|
||||
ip_addr = sys.argv[2]
|
||||
new_passw = sys.argv[3]
|
||||
elif len(sys.argv) > 1:
|
||||
new_passw = sys.argv[1]
|
||||
ip_addr = None
|
||||
else:
|
||||
new_passw = input("Enter new password for root user: ")
|
||||
ip_addr = None
|
||||
|
||||
new_passw = new_passw.strip()
|
||||
if len(new_passw) == 0:
|
||||
die('Password cannot be empty!')
|
||||
|
||||
# Create gateway without automatic SSH detection
|
||||
gw = gateway.Gateway(detect_ssh=False)
|
||||
|
||||
if ip_addr:
|
||||
gw.ip_addr = ip_addr
|
||||
print("Using IP: {}".format(ip_addr))
|
||||
|
||||
if gw.status < 1:
|
||||
gw.detect_device()
|
||||
if gw.status < 1:
|
||||
die("Xiaomi device not found (IP: {})".format(gw.ip_addr))
|
||||
|
||||
print("Device: {}".format(gw.device_name))
|
||||
print("IP: {} SSH port: {}".format(gw.ip_addr, gw.ssh_port))
|
||||
|
||||
# 1. Try SSH with saved password (if present in memcfg)
|
||||
if gw.passw:
|
||||
ret = gw.check_ssh(gw.ip_addr, gw.ssh_port, gw.passw)
|
||||
if ret >= 0:
|
||||
print("SSH connection with saved password — OK")
|
||||
gw.use_ssh = True
|
||||
reset_password_via_gateway(gw, new_passw)
|
||||
return
|
||||
|
||||
# 2. Try TELNET (password is usually "root" after unlock)
|
||||
if not gw.check_telnet(timeout=3):
|
||||
die("Neither SSH (with known password) nor TELNET is accessible.\n"
|
||||
"Ensure TELNET is enabled on the device (telnet_en=1).")
|
||||
|
||||
print("TELNET detected. Attempting to connect...")
|
||||
|
||||
telnet_passwords = ['root']
|
||||
if gw.passw and gw.passw != 'root':
|
||||
telnet_passwords.insert(0, gw.passw)
|
||||
if gw.xqpassword and gw.xqpassword not in telnet_passwords:
|
||||
telnet_passwords.append(gw.xqpassword)
|
||||
|
||||
tn = None
|
||||
used_passw = None
|
||||
for psw in telnet_passwords:
|
||||
tn = gw.get_telnet(verbose=0, password=psw)
|
||||
if tn:
|
||||
used_passw = psw
|
||||
break
|
||||
|
||||
if not tn:
|
||||
die("Failed to connect via TELNET.\n"
|
||||
"Tried passwords: " + ", ".join(repr(p) for p in telnet_passwords) +
|
||||
"\nTry the default password: root")
|
||||
|
||||
print("TELNET connection — OK (password: {})".format(repr(used_passw)))
|
||||
gw.use_ssh = False
|
||||
gw.passw = used_passw
|
||||
gw.ping(verbose=0)
|
||||
|
||||
reset_password_via_gateway(gw, new_passw)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
XMiR Patcher environment diagnostic test.
|
||||
Checks imports, configuration, and device availability.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
def main():
|
||||
print("=" * 50)
|
||||
print("XMiR Patcher — Environment Diagnostic")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Import tests
|
||||
print("\n[1] Imports...")
|
||||
try:
|
||||
import xmir_base
|
||||
print(" xmir_base — OK")
|
||||
except Exception as e:
|
||||
print(" xmir_base — ERROR:", e)
|
||||
return 1
|
||||
|
||||
try:
|
||||
import gateway
|
||||
print(" gateway — OK")
|
||||
except Exception as e:
|
||||
print(" gateway — ERROR:", e)
|
||||
return 1
|
||||
|
||||
try:
|
||||
import xqmodel
|
||||
print(" xqmodel — OK")
|
||||
except Exception as e:
|
||||
print(" xqmodel — ERROR:", e)
|
||||
return 1
|
||||
|
||||
try:
|
||||
import read_info
|
||||
print(" read_info — OK")
|
||||
except Exception as e:
|
||||
print(" read_info — ERROR:", e)
|
||||
|
||||
# 2. Configuration
|
||||
print("\n[2] Configuration...")
|
||||
try:
|
||||
gw = gateway.Gateway(detect_device=False, detect_ssh=False)
|
||||
print(" Device IP: {}".format(gw.ip_addr))
|
||||
print(" SSH port: {}".format(gw.ssh_port))
|
||||
if gw.passw:
|
||||
print(" Password (memcfg): saved")
|
||||
else:
|
||||
print(" Password (memcfg): not set")
|
||||
except PermissionError as e:
|
||||
print(" Shared memory error (possibly sandboxed): {}".format(e))
|
||||
gw = None
|
||||
except Exception as e:
|
||||
print(" Initialization error: {}".format(e))
|
||||
gw = None
|
||||
|
||||
# 3. Device detection (without SSH)
|
||||
print("\n[3] Device detection...")
|
||||
if gw:
|
||||
try:
|
||||
gw.detect_device()
|
||||
if gw.status >= 1:
|
||||
print(" Device found: {}".format(gw.device_name))
|
||||
print(" ROM: {} {}".format(gw.rom_version or "?", gw.rom_channel or ""))
|
||||
else:
|
||||
print(" Device not found (IP: {})".format(gw.ip_addr))
|
||||
except SystemExit:
|
||||
print(" Device unavailable or requires initial setup via WEB UI")
|
||||
except Exception as e:
|
||||
print(" Error: {}".format(e))
|
||||
else:
|
||||
print(" Skipped (Gateway not initialized)")
|
||||
|
||||
# 4. Supported models
|
||||
print("\n[4] Known models (examples): R3G, R3P, RM2100, R4A, WR30...")
|
||||
print(" Total in xqmodel: {} models".format(len(xqmodel.xqModelList)))
|
||||
|
||||
# 5. Unsupported models
|
||||
print("\n[5] Unsupported features:")
|
||||
print(" BE3600, BE2600 2.5G and other Wi-Fi 7 (BE-series) routers:")
|
||||
print(" — Reason: use Qualcomm IPQ (ARM), not MediaTek MT7621 (MIPS)")
|
||||
print(" — Breed bootloader and certain features are designed only for MIPS")
|
||||
print(" — Supported models: R3G, R3P, RM2100")
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("Diagnostic completed.")
|
||||
print("=" * 50)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Reference in New Issue