Open pbjfarm opened 2 weeks ago
@pbjfarm I think that with my branch the container will not stop, can you test ?
https://github.com/JuiceRescue/juicepassproxy/pull/69
If is just sometimes that it send wrong messages we can just skip, but if your device keeps sending that, maybe we need to get a way to ignore that unexpected character
@ivanfmartinez I have your branch running now. It's producing the same error, but is continuing with the Starting JuiceboxMITM Loop...and it did finally exit with:
juicepassproxy | 2024-11-10 21:33:21 ERROR [aiorun] Unhandled exception; stopping loop: 'Task exception was never retrieved'
The weird thing is that the problem ID in the message doesn't quite match my JuiceBox ID.
Sent: b'0\xc300081509281447541218021146
Mine: 0100081509281447541218021146
I'm not sure if it's gotten corrupted on the JuiceBox, or what? I'm not really sure how to change it either...
@pbjfarm its TCP/IP which does have checkings, the value will not be corrupted on TCP/IP part, it should be corrupted before going out juicebox device.
It appear to me something hardware related.
Even if I change the \xc3 to 1 on the message you sent on first comment of the issue, the checksum still does not match. Appear that something else on the message are wrong.
To try to understand if there is also another exception that I can catch probably I need a complete log to check. If you dont want to send log here you can send to my email (my github username at gmail) or telegram with same username .
All messages are corrupted or some are correct ?
@ivanfmartinez I thought this was UDP...but it does seem like my messages (or at least the ID) are corrupted somehow.
I've now managed to brick my box somehow (it's not showing the local WiFi SSID on reboot), so I won't be able to provide logs until I can figure out what's going on.
@pbjfarm JB used UDP and UDP is part of TCP/IP.
If the ids are broken in all messages, them is something on the device.
Maybe FalconFour can help with more ideas or maybe someone else on Discord check main page for link https://github.com/JuiceRescue
Hi. Not trying to be critical at all. But I'd like to clarify about TCP and UDP. UDP isn't part of TCP/IP. IP is a layer 3 protocol. Both UDP and TCP are layer 4 protocols that run on top of IP. You use one OR the other. TCP establishes a stateful connection to a remote peer and provides reliable stream transport so that higher layer protocols can send data without worrying about issues such as resending data if packets are lost. TCP takes care of that. UDP is a best effort datagram protocol. It is connectionless. It sends a packet and it's done. When using UDP, the higher layer protocol must handle issues such as resending lost packets/data.
While UDP doesn't guarantee packet delivery, it does support a checksum to try to detect any packet corruption. However, this checksum is optional and the implementation can set it to zero to disable it.
UDP seems a logical choice for the JB as it sends a complete message in a single datagram, and even if a packet is lost, the JB is going to resend another soon anyway. TCP would add unnecessary overhead, especially on a busy server. As for the UDP checksum, I have no idea if the JB uses it or not. We could tell from a packet capture. Since the Enel X protocol provides its own checksum, there is a good chance they are not using the UDP checksum.
This just started happening for me one day ago. Here's the error:
juicepassproxy | 2024-11-15 23:12:07 INFO [ha_mqtt_discoverable.sensors] Setting Send Command to JuiceBox to Send Command to JuiceBox using hmd/text/JuiceBox/Send-Command-to-JuiceBox/state
juicepassproxy | 2024-11-15 23:12:12 ERROR [juicebox_mitm] Not a valid juicebox message |b'0817081001070462465218264504:v08\xc2\xe1_\x01\x00\x01Z&\x17\xa5Wzp\x8c,\x00\xa7\xee/Tf\t\xf4\xe3\xed\xa4\xb6\x88I\x9en\x84a\x83\\\xb7\xc4\xa9RD\xe8%\x0cX\xfe\x93\x96\xa7\xa5\xf3B\x94)\xf7>\xef\x16\x9f\x8d\xa4\xa9\x84\x17sha\x86\xc1\xa9\x8ff\x02/F\x12|C\x0eR\xd5\xf1!\xeeYTE\xdfS/J<\xf5\xcfO\xc2\xa9\xaa\xf5\x98\xff\x85\x82\x9f4\x01\xbeJ\r\xac\xc7\xf0\xb6\xb9\x06,ce.\x9e\x1c\xf0%\x17m\xaf\xe4`\xc5'| 'utf-8' codec can't decode byte 0xc2 in position 32: unexpected end of data
juicepassproxy | Traceback (most recent call last):
juicepassproxy | File "/juicepassproxy/juicebox_message.py", line 144, in juicebox_message_from_bytes
juicepassproxy | string = data.decode("utf-8")
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^
juicepassproxy | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 32: invalid continuation byte
juicepassproxy |
juicepassproxy | During handling of the above exception, another exception occurred:
juicepassproxy |
juicepassproxy | Traceback (most recent call last):
juicepassproxy | File "/juicepassproxy/juicebox_mitm.py", line 156, in _message_decode
juicepassproxy | decoded_message = juicebox_message_from_bytes(data)
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
juicepassproxy | File "/juicepassproxy/juicebox_message.py", line 148, in juicebox_message_from_bytes
juicepassproxy | return JuiceboxEncryptedMessage().from_bytes(data)
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
juicepassproxy | File "/juicepassproxy/juicebox_message.py", line 389, in from_bytes
juicepassproxy | string = data[0:33].decode("utf-8")
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^^^^^^^
juicepassproxy | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 32: unexpected end of data
juicepassproxy | 2024-11-15 23:12:12 ERROR [__main__] A JuicePass Proxy task failed: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 32: invalid continuation byte
juicepassproxy | Traceback (most recent call last):
juicepassproxy | File "/juicepassproxy/juicepassproxy.py", line 581, in main
juicepassproxy | await asyncio.gather(
juicepassproxy | File "/juicepassproxy/juicebox_mitm.py", line 62, in start
juicepassproxy | await self._connect()
juicepassproxy | File "/juicepassproxy/juicebox_mitm.py", line 105, in _connect
juicepassproxy | self._mitm_loop_task = await self._mitm_loop()
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^^^^
juicepassproxy | File "/juicepassproxy/juicebox_mitm.py", line 136, in _mitm_loop
juicepassproxy | await self._main_mitm_handler(data, remote_addr)
juicepassproxy | File "/juicepassproxy/juicebox_mitm.py", line 213, in _main_mitm_handler
juicepassproxy | data = await self._local_mitm_handler(data, decoded_message)
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
juicepassproxy | File "/juicepassproxy/juicebox_mqtthandler.py", line 649, in local_mitm_handler
juicepassproxy | message = await self._basic_message_parse(data)
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
juicepassproxy | File "/juicepassproxy/juicebox_mqtthandler.py", line 472, in _basic_message_parse
juicepassproxy | parts = re.split(r",|!|:", data.decode("utf-8"))
juicepassproxy | ^^^^^^^^^^^^^^^^^^^^
juicepassproxy | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 32: invalid continuation byte
juicepassproxy | 2024-11-15 23:12:25 ERROR [__main__] Restarting JuicePass Proxy Loop (9)
juicepassproxy | 2024-11-15 23:12:25 INFO [juicebox_mqtthandler] max_current: 32
I tried rebooting the juicebox, and I found something interesting.
After issuing the reboot
command through the telnet shell (nc -v 10.0.1.230 2000
), as soon as the juicebox came online again I briefly saw the following result from the list
command:
list
! # Type Info
# 0 UDPC juicenet-udp-prod4-exw.enelx.com:9004 (30660)
# 1 HTTP https://juicenet-prod4.enelx.com/v1/unit/0817081001070462465218264504/keys:443 (20379)
> [2024-11-15 | 22:22:27: Closed: 1]
Note: That HTTP thing wasn't there before and went away after a few seconds.
Checking the response when visiting that URL, I saw this:
{"key":"ef3c41c925ff10174684512b40beace03dd22aeeac5aa2fb97a8af49fcb4d38c","exp_date":"2025-11-14T14:27:30.802Z","err_msg":null}
Found another bit of interesting information. I was using the DNS override method, and I had the juicenet-udp-prod4-exw.enelx.com
and directory-api.emotorwerks.com
hosts set to the IP of the machine hosting juicepassproxy. I decided to temporarily revert this change to let the juicebox phone home again. This worked and my car started charging again. Without any ability for me to control it though, as it appeared in the Enel X app as "Charger occupied: another user is charging." - whatever that means 🙃
What I saw after rebooting the juicebox again and running list
is this:
❯ nc -v 10.0.1.230 2000
Connection to 10.0.1.230 port 2000 [tcp/callbook] succeeded!
[2024-11-15 | 23:09:22: Ready]
> list
list
! # Type Info
# 0 UDPC jbv1.emotorwerks.com:8042 (6470)
# 1 HTTP https://directory-api.emotorwerks.com/v1/profiles/juicebox/0817081001070462465218264504/:443 (35085)
> [2024-11-15 | 23:09:24: Closed: 1]
[2024-11-15 | 23:09:24: Closed: 0]
[2024-11-15 | 23:09:25: Opening: juicenet-udp-prod4-exw.enelx.com:9004]
[2024-11-15 | 23:09:25: Opened: 0]
[2024-11-15 | 23:09:26: Opening: juicenet-prod4.enelx.com]
[2024-11-15 | 23:09:27: Opened: 1]
[2024-11-15 | 23:09:31: Closed: 1]
[2024-11-15 | 23:09:33: Opened: 1]
[2024-11-15 | 23:09:33: Closed: 1]
[2024-11-15 | 23:10:04: Opened: 1]
[2024-11-15 | 23:10:04: Closed: 1]
[2024-11-15 | 23:10:24: Opened: 1]
[2024-11-15 | 23:10:24: Closed: 1]
This time there's another URL listed (https://directory-api.emotorwerks.com/v1/profiles/juicebox/0817081001070462465218264504
), which returned this little gem:
{
"control_api_endpoint" : "https://juicenet-prod4.enelx.com",
"device_https_endpoint" : "https://juicenet-prod4.enelx.com",
"device_ocpp_endpoint" : "https://juicenet-prod4.enelx.com",
"device_protocol" : "Both",
"device_udp_endpoint" : "juicenet-udp-prod4-exw.enelx.com:9004",
"encrypt" : "false"
}
Note the presence of the OCPP protocol (Open Charge Point Protocol). Could this be the way to MITM this box and gain permanent control over it?
One more error, this time a different one (Unsupported encrypted message version
):
2024-11-16 01:32:43 INFO [ha_mqtt_discoverable.sensors] Setting Send Command to JuiceBox to Send Command to JuiceBox using hmd/text/JuiceBox/Send-Command-to-JuiceBox/state
2024-11-16 01:32:43 INFO [telnetlib3.client] Connected to <Peer 10.0.1.230 2000>
2024-11-16 01:32:45 INFO [juicebox_udpcupdater] JuiceboxUDPCUpdater Check Starting
2024-11-16 01:32:46 INFO [juicebox_udpcupdater] UDPC IP correct
2024-11-16 01:32:48 ERROR [juicebox_mitm] Not a valid juicebox message |b'0817081001070462465218264504:v08(\x1d?\x01\x00\x00\r\xadT\x93\xeaL*wt\xe3T\xdb\xe6\x96CU\x8c&\xf9K\x8a\x83\xc0\xcdu\xd6\xf5\x1e*\t\x81P]\x01\xeeGz\x8b\x9cX\xeb\xb6\xdd\xae\xe3m\xfd\xa4\xc97c\x86@\x1cEH\xc8e2\xd4#\xa9\xc2c\xd7a\xc0\x81\xd9{\xac\x04\xb4{\xf49V\xcb#4X\x1dxo\xb6\x8f-\xbf\x07O\xba?w\xd3\xd7\x10\xa40T1\xaa\x97X\x12.x\xca`\xd1\xc3\x8e\xc89\xae\n\x98\xe2#B\xc0\x94v'| Unsupported encrypted message version: 'b'0817081001070462465218264504:v08(\x1d?\x01\x00\x00\r\xadT\x93\xeaL*wt\xe3T\xdb\xe6\x96CU\x8c&\xf9K\x8a\x83\xc0\xcdu\xd6\xf5\x1e*\t\x81P]\x01\xeeGz\x8b\x9cX\xeb\xb6\xdd\xae\xe3m\xfd\xa4\xc97c\x86@\x1cEH\xc8e2\xd4#\xa9\xc2c\xd7a\xc0\x81\xd9{\xac\x04\xb4{\xf49V\xcb#4X\x1dxo\xb6\x8f-\xbf\x07O\xba?w\xd3\xd7\x10\xa40T1\xaa\x97X\x12.x\xca`\xd1\xc3\x8e\xc89\xae\n\x98\xe2#B\xc0\x94v''
Traceback (most recent call last):
File "/juicepassproxy/juicebox_message.py", line 144, in juicebox_message_from_bytes
string = data.decode("utf-8")
^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 39: invalid start byte
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/juicepassproxy/juicebox_mitm.py", line 156, in _message_decode
decoded_message = juicebox_message_from_bytes(data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/juicepassproxy/juicebox_message.py", line 148, in juicebox_message_from_bytes
return JuiceboxEncryptedMessage().from_bytes(data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/juicepassproxy/juicebox_message.py", line 398, in from_bytes
raise JuiceboxInvalidMessageFormat(f"Unsupported encrypted message version: '{data}'")
juicebox_exceptions.JuiceboxInvalidMessageFormat: Unsupported encrypted message version: 'b'0817081001070462465218264504:v08(\x1d?\x01\x00\x00\r\xadT\x93\xeaL*wt\xe3T\xdb\xe6\x96CU\x8c&\xf9K\x8a\x83\xc0\xcdu\xd6\xf5\x1e*\t\x81P]\x01\xeeGz\x8b\x9cX\xeb\xb6\xdd\xae\xe3m\xfd\xa4\xc97c\x86@\x1cEH\xc8e2\xd4#\xa9\xc2c\xd7a\xc0\x81\xd9{\xac\x04\xb4{\xf49V\xcb#4X\x1dxo\xb6\x8f-\xbf\x07O\xba?w\xd3\xd7\x10\xa40T1\xaa\x97X\x12.x\xca`\xd1\xc3\x8e\xc89\xae\n\x98\xe2#B\xc0\x94v''
2024-11-16 01:32:49 ERROR [__main__] A JuicePass Proxy task failed: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 39: invalid start byte
Traceback (most recent call last):
File "/juicepassproxy/juicepassproxy.py", line 581, in main
The enel X servers are enabling encryption on the devices.
You have to block access to the enel x servers using something
I have tried to access the standard endpoint for some of the devices that are using encryption and all return encrypt false, probably the Juicebox send any header that makes the server know that device can support encryption and then are returning true or other thing to enable the encryption.
@philipkocanda the line numbers from your exceptions does not match the lines from latest version in my branch. Latest version has better messages when encryption is found.
Your device is sending v08 protocol version, can you add information about your device at, help understand if its a different version or just something that directory server changed :
https://github.com/JuiceRescue/JuiceboxRescueWiki/wiki/Firmware-Versions
https://github.com/JuiceRescue/JuiceboxRescueWiki/wiki/Hardware-Versions
My JPP docker setup stopped working a couple weeks ago. It seems to be related to a character in the JuiceBox ID that the box is sending...although I haven't changed anything.
This appears to be different than the other issue mentioning UnicodeDecodeError - as that issue was using what appeared to be an encrypted version of the protocol...mine is still v07.
Startup just loops until finally erroring out.