Skip to content

Commit 5291090

Browse files
authored
Version 2.4.2
2 parents 6febeec + 16f7165 commit 5291090

8 files changed

Lines changed: 29 additions & 16 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM phusion/baseimage:0.11
1+
FROM phusion/baseimage:master
22

33
RUN apt-get update && apt-get install -y sudo iproute2 iputils-ping
44

docker/bin/stop

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
#!/bin/bash
2-
cd /usr/bin/tuya-convert
3-
./stop_flash.sh
2+
pkill -SIGINT -f start_flash.sh

install_prereq.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ set -e
55
sudo apt-get update
66
sudo apt-get install -y git iw dnsmasq hostapd screen curl build-essential python3-pip python3-setuptools python3-wheel python3-dev mosquitto haveged net-tools libssl-dev
77

8-
sudo -H python3 -m pip install paho-mqtt tornado git+https://github.com/drbild/sslpsk.git@use-byte-string-for-identity-hints pycryptodomex
8+
sudo -H python3 -m pip install --upgrade paho-mqtt tornado git+https://github.com/drbild/sslpsk.git@use-byte-string-for-identity-hints pycryptodomex
99

1010
echo "Ready to start upgrade"

scripts/fake-registration-server.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ def exit_cleanly(signal, frame):
2727
from Cryptodome.Cipher import AES
2828
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
2929
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
30-
encrypt = lambda msg, key: AES.new(key.encode(), AES.MODE_ECB).encrypt(pad(msg).encode())
31-
decrypt = lambda msg, key: unpad(AES.new(key.encode(), AES.MODE_ECB).decrypt(msg.encode()))
30+
encrypt = lambda msg, key: AES.new(key, AES.MODE_ECB).encrypt(pad(msg).encode())
31+
decrypt = lambda msg, key: unpad(AES.new(key, AES.MODE_ECB).decrypt(msg)).decode()
3232

3333
from base64 import b64encode
3434
import hashlib
@@ -84,7 +84,7 @@ def reply(self, result=None, encrypted=False):
8484
't': ts,
8585
'success': True }
8686
answer = jsonstr(answer)
87-
payload = b64encode(encrypt(answer, options.secKey)).decode()
87+
payload = b64encode(encrypt(answer, options.secKey.encode())).decode()
8888
signature = "result=%s||t=%d||%s" % (payload, ts, options.secKey)
8989
signature = hashlib.md5(signature.encode()).hexdigest()[8:24]
9090
answer = {
@@ -115,7 +115,7 @@ def post(self):
115115
print(self.request.headers)
116116
if payload:
117117
try:
118-
decrypted_payload = decrypt(binascii.unhexlify(payload), options.secKey).decode()
118+
decrypted_payload = decrypt(binascii.unhexlify(payload), options.secKey.encode())
119119
if decrypted_payload[0] != "{":
120120
raise ValueError("payload is not JSON")
121121
print("payload", decrypted_payload)

scripts/mq_pub_15.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
from Cryptodome.Cipher import AES
2222
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
2323
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
24-
encrypt = lambda msg, key: AES.new(key.encode(), AES.MODE_ECB).encrypt(pad(msg).encode())
25-
decrypt = lambda msg, key: unpad(AES.new(key.encode(), AES.MODE_ECB).decrypt(msg.encode()))
24+
encrypt = lambda msg, key: AES.new(key, AES.MODE_ECB).encrypt(pad(msg).encode())
25+
decrypt = lambda msg, key: unpad(AES.new(key, AES.MODE_ECB).decrypt(msg)).decode()
2626

2727
def iot_dec(message, local_key):
28-
message_clear = decrypt(base64.b64decode(message[19:]), local_key)
28+
message_clear = decrypt(base64.b64decode(message[19:]), local_key.encode())
2929
print (message_clear)
3030
return message_clear
3131
def iot_enc(message, local_key, protocol):
32-
messge_enc = encrypt(message, local_key)
32+
messge_enc = encrypt(message, local_key.encode())
3333
if protocol == "2.1":
3434
messge_enc = base64.b64encode(messge_enc)
3535
signature = b'data=' + messge_enc + b'||pv=' + protocol.encode() + b'||' + local_key.encode()

scripts/psk-frontend.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ def new_client(self, s1):
7171
print("could not establish sslpsk socket:", e)
7272
if "NO_SHARED_CIPHER" in e.reason or "WRONG_VERSION_NUMBER" in e.reason or "WRONG_SSL_VERSION" in e.reason:
7373
print("don't panic this is probably just your phone!")
74+
except Exception as e:
75+
print(e)
7476
def data_ready_cb(self, s):
7577
if s == self.server_sock:
7678
_s, frm = s.accept()

scripts/tuya-discovery.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,39 @@
1212
from Cryptodome.Cipher import AES
1313
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
1414
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
15-
encrypt = lambda msg, key: AES.new(key.encode(), AES.MODE_ECB).encrypt(pad(msg).encode())
16-
decrypt = lambda msg, key: unpad(AES.new(key.encode(), AES.MODE_ECB).decrypt(msg.encode()))
15+
encrypt = lambda msg, key: AES.new(key, AES.MODE_ECB).encrypt(pad(msg).encode())
16+
decrypt = lambda msg, key: unpad(AES.new(key, AES.MODE_ECB).decrypt(msg)).decode()
1717

1818
from hashlib import md5
1919
udpkey = md5(b"yGAdlopoPVldABfn").digest()
2020
decrypt_udp = lambda msg: decrypt(msg, udpkey)
2121

22+
devices_seen = set()
23+
2224
class TuyaDiscovery(asyncio.DatagramProtocol):
2325
def datagram_received(self, data, addr):
26+
# ignore devices we've already seen
27+
if data in devices_seen:
28+
return
29+
devices_seen.add(data)
2430
# remove message frame
2531
data = data[20:-8]
2632
# decrypt if encrypted
2733
try:
2834
data = decrypt_udp(data)
2935
except:
30-
pass
36+
data = data.decode()
37+
print(addr[0], data)
3138
# parse json
3239
try:
3340
data = json.loads(data)
41+
# there is a typo present only in Tuya SDKs for non-ESP devices ("ablilty")
42+
# it is spelled correctly in the Tuya SDK for the ESP ("ability")
43+
# we can use this as a clue to report unsupported devices
44+
if "ablilty" in data:
45+
print("WARNING: it appears this device does not use an ESP82xx and therefore cannot install ESP based firmware")
3446
except:
3547
pass
36-
print(addr[0], data)
3748

3849
def main():
3950
loop = asyncio.get_event_loop()

start_flash.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ normal=$(tput sgr0)
44
. ./config.txt
55

66
setup () {
7+
echo "tuya-convert $(git describe --tags)"
78
pushd scripts >/dev/null || exit
89
. ./setup_checks.sh
910
screen_minor=$(screen --version | cut -d . -f 2)

0 commit comments

Comments
 (0)