Version 2.4.2

pull/548/head v2.4.2
Colin Kuebler 2020-01-25 18:15:42 -05:00 committed by GitHub
commit 52910905bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 29 additions and 16 deletions

View File

@ -1,4 +1,4 @@
FROM phusion/baseimage:0.11
FROM phusion/baseimage:master
RUN apt-get update && apt-get install -y sudo iproute2 iputils-ping

View File

@ -1,3 +1,2 @@
#!/bin/bash
cd /usr/bin/tuya-convert
./stop_flash.sh
pkill -SIGINT -f start_flash.sh

View File

@ -5,6 +5,6 @@ set -e
sudo apt-get update
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
sudo -H python3 -m pip install paho-mqtt tornado git+https://github.com/drbild/sslpsk.git@use-byte-string-for-identity-hints pycryptodomex
sudo -H python3 -m pip install --upgrade paho-mqtt tornado git+https://github.com/drbild/sslpsk.git@use-byte-string-for-identity-hints pycryptodomex
echo "Ready to start upgrade"

View File

@ -27,8 +27,8 @@ signal.signal(signal.SIGINT, exit_cleanly)
from Cryptodome.Cipher import AES
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
encrypt = lambda msg, key: AES.new(key.encode(), AES.MODE_ECB).encrypt(pad(msg).encode())
decrypt = lambda msg, key: unpad(AES.new(key.encode(), AES.MODE_ECB).decrypt(msg.encode()))
encrypt = lambda msg, key: AES.new(key, AES.MODE_ECB).encrypt(pad(msg).encode())
decrypt = lambda msg, key: unpad(AES.new(key, AES.MODE_ECB).decrypt(msg)).decode()
from base64 import b64encode
import hashlib
@ -84,7 +84,7 @@ class JSONHandler(tornado.web.RequestHandler):
't': ts,
'success': True }
answer = jsonstr(answer)
payload = b64encode(encrypt(answer, options.secKey)).decode()
payload = b64encode(encrypt(answer, options.secKey.encode())).decode()
signature = "result=%s||t=%d||%s" % (payload, ts, options.secKey)
signature = hashlib.md5(signature.encode()).hexdigest()[8:24]
answer = {
@ -115,7 +115,7 @@ class JSONHandler(tornado.web.RequestHandler):
print(self.request.headers)
if payload:
try:
decrypted_payload = decrypt(binascii.unhexlify(payload), options.secKey).decode()
decrypted_payload = decrypt(binascii.unhexlify(payload), options.secKey.encode())
if decrypted_payload[0] != "{":
raise ValueError("payload is not JSON")
print("payload", decrypted_payload)

View File

@ -21,15 +21,15 @@ iot:
from Cryptodome.Cipher import AES
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
encrypt = lambda msg, key: AES.new(key.encode(), AES.MODE_ECB).encrypt(pad(msg).encode())
decrypt = lambda msg, key: unpad(AES.new(key.encode(), AES.MODE_ECB).decrypt(msg.encode()))
encrypt = lambda msg, key: AES.new(key, AES.MODE_ECB).encrypt(pad(msg).encode())
decrypt = lambda msg, key: unpad(AES.new(key, AES.MODE_ECB).decrypt(msg)).decode()
def iot_dec(message, local_key):
message_clear = decrypt(base64.b64decode(message[19:]), local_key)
message_clear = decrypt(base64.b64decode(message[19:]), local_key.encode())
print (message_clear)
return message_clear
def iot_enc(message, local_key, protocol):
messge_enc = encrypt(message, local_key)
messge_enc = encrypt(message, local_key.encode())
if protocol == "2.1":
messge_enc = base64.b64encode(messge_enc)
signature = b'data=' + messge_enc + b'||pv=' + protocol.encode() + b'||' + local_key.encode()

View File

@ -71,6 +71,8 @@ class PskFrontend():
print("could not establish sslpsk socket:", e)
if "NO_SHARED_CIPHER" in e.reason or "WRONG_VERSION_NUMBER" in e.reason or "WRONG_SSL_VERSION" in e.reason:
print("don't panic this is probably just your phone!")
except Exception as e:
print(e)
def data_ready_cb(self, s):
if s == self.server_sock:
_s, frm = s.accept()

View File

@ -12,28 +12,39 @@ import json
from Cryptodome.Cipher import AES
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
encrypt = lambda msg, key: AES.new(key.encode(), AES.MODE_ECB).encrypt(pad(msg).encode())
decrypt = lambda msg, key: unpad(AES.new(key.encode(), AES.MODE_ECB).decrypt(msg.encode()))
encrypt = lambda msg, key: AES.new(key, AES.MODE_ECB).encrypt(pad(msg).encode())
decrypt = lambda msg, key: unpad(AES.new(key, AES.MODE_ECB).decrypt(msg)).decode()
from hashlib import md5
udpkey = md5(b"yGAdlopoPVldABfn").digest()
decrypt_udp = lambda msg: decrypt(msg, udpkey)
devices_seen = set()
class TuyaDiscovery(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
# ignore devices we've already seen
if data in devices_seen:
return
devices_seen.add(data)
# remove message frame
data = data[20:-8]
# decrypt if encrypted
try:
data = decrypt_udp(data)
except:
pass
data = data.decode()
print(addr[0], data)
# parse json
try:
data = json.loads(data)
# there is a typo present only in Tuya SDKs for non-ESP devices ("ablilty")
# it is spelled correctly in the Tuya SDK for the ESP ("ability")
# we can use this as a clue to report unsupported devices
if "ablilty" in data:
print("WARNING: it appears this device does not use an ESP82xx and therefore cannot install ESP based firmware")
except:
pass
print(addr[0], data)
def main():
loop = asyncio.get_event_loop()

View File

@ -4,6 +4,7 @@ normal=$(tput sgr0)
. ./config.txt
setup () {
echo "tuya-convert $(git describe --tags)"
pushd scripts >/dev/null || exit
. ./setup_checks.sh
screen_minor=$(screen --version | cut -d . -f 2)