I started debugging this tonight.
One issue I found in the lua source code is this regex:
local server_matching_regex = ".*Server_Account=([%w%p%d]+).*Server_Account_Alt=([%w%p%d]+).*Use_Server_Account_Alt=(%d)"
Use_Server_Account_Alt
does not exist in my /etc/cmh/servers.conf, so it fails with:
“Could not retrieve the account servers”
This really should be three separate regexes with a default for the last one.
I added a line, Use_Server_Account_Alt=0 and did the recommended process at Ecobee Thermostat (by eZLO) Plugin - #54 by slackner and got the url back …
I can verify at that point that the auth token and the refresh token are in /etc/cmh/user_data.json.lzo
But now, there is a startup error:
LuaUPnP.log:01 03/14/24 20:05:38.766 LuaInterface::CallFunction_Startup-1 device 198 function Main failed [string "local dkjson = require("dkjson")..."]:348: attempt to concatenate local 'response_code' (a nil value) <0x76be6520>
What I am stumped at now is this always returns all nil’s:
local one, response_code, response_headers, response_status = RequestFunction {
url = url,
method = method,
headers = request_headers,
source = source,
sink = sink,
protocol = "tlsv1_2"
}
Best I can tell after an evening of debugging is that ssl.https on the vera is broken. This works on my Linux box (with an appropriate 500 error), but not on vera:
https = require('ssl.https')
print('hello world')
local res = {}
local one, two, three, four = https.request {
url="https://api.ecobee.com/1/thermostat?json=foo",
-- url="https://google.com",
method="GET",
protocol = "tlsv1_2",
sink=ltn12.sink.table(resp),
verify="none",
mode="client",
options="all",
}
print(tostring(one))
print(tostring(two))
print(tostring(three))
print(tostring(four))
More debugging this morning.
If I point my test script to a local https server on my network, it works:
root@MiOS_50009988:~/debug# ./foo.s
hello world
1
200
table: 0x7e34a8
HTTP/1.1 200 OK
I extracted the environment from /proc for the vera Lua process and replicated the env while testing:
foo.lua:https = require('ssl.https')
foo.lua:print('hello world')
foo.lua:local res = {}
foo.lua:local one, two, three, four = https.request {
foo.lua: -- url="https://api.ecobee.com/1/thermostat?[redacted]",
foo.lua: -- url="https://google.com",
foo.lua: url="https://10.13.54.100",
foo.lua: method="GET",
foo.lua: protocol = "tlsv1_2",
foo.lua: --sink=ltn12.sink.table(resp),
foo.lua: verify="none",
foo.lua: --mode="client",
foo.lua: --options="all",
foo.lua:}
foo.lua:
foo.lua:print(tostring(one))
foo.lua:print(tostring(two))
foo.lua:print(tostring(three))
foo.lua:print(tostring(four))
foo.sh:export LUA_PATH="./?.lua;/usr/share/lua/?.lua;/usr/share/lua/?/init.lua;/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;/etc/cmh-ludl/?.lua;/etc/cmh-lu/?.lua"
foo.sh:export LD_LIBRARY_PATH=/usr/lib/cmh:/mios/usr/lib/cmh:/rom/usr/lib/cmh
foo.sh:export HOME=/
foo.sh:export TERM=linux
foo.sh:export PATH=/usr/sbin:/usr/bin:/sbin:/bin
foo.sh:cd /
foo.sh:lua /root/debug/foo.lua
I think this is failing during the socket handshake.
I’m a little concerned how old the cacert.pem file is:
-rw-r--r-- 1 root root 253453 Aug 14 2014 /etc/mios/sslcerts/CA/cacert.pem
But curl works with google, so I’m skeptical of the age of the file being a problem. They likely share the same certs? But curl doesn’t use the openssl lib.
I wonder if maybe the older vera lua libraries don’t support a newer cypher that google, ecobee, etc. requires. But somehow curl supports it still.
And here is someone who tends to think the same thing:
If you’re doing this in Vera firmware…
You may be dealing with the server demanding a level of encryption that the libraries cannot provide. This has been an increasingly common issue for many plugins, and Google was leading the charge in dropping weaker ciphers. In some of my own plugins, I’ve had to offer curl
as an alternative mechanism, because the built-in curl
uses different libraries and can be a workaround if the Lua libraries aren’t cutting it.
It’s also the case that the CA chain is now out of date on all Vera firmware, and as old CA certificates are now expiring, and Vera/EZlo has not yet produced firmware with upgraded CA stores, you could be running into a certificate validation failure due to the outdated or expired data. The -k
on curl
is a possible cure for this. In the Lua SSL library, you can set verify
to none
in your request table.
The issues have affected, in addition to my plugins (SiteSensor, Reactor for Vera, etc.) the Honeywell and MyQ plugins, and I think GCal3 has already had one round of retrofit as a result of Google’s earlier changes. It’s going to get worse, not better, unless they update the firmware (or we do…)