Zwave2Mqtt
Zwave2Mqtt copied to clipboard
[feat] Check if node is added securely
I have been digging through the web interface and I haven't been able to find out how to tell if a node has been added securely. Is there a property somewhere that will tell you this information?
I'm asking because I used the "replace a failed node" feature and I'm unsure if the added node was added securely through this process.
@Fishwaldo is this method the correct one to check if a node is security added? https://github.com/OpenZWave/open-zwave/blob/master/cpp/src/Driver.cpp#L4505
No. That’s for a very very ancient version of Security in z-wave.
The presence of the Security CC and a bool ValueID indicate if it’s securely added (sorry, can’t remember the label right now)
Could you kindly tell me how I can do this? I’m not that familiar that C++
Daniel
On 1 Oct 2019, at 13:57, Justin Hammond [email protected] wrote:
No. That’s for a very very ancient version of Security in z-wave.
The presence of the Security CC and a bool ValueID indicate if it’s securely added (sorry, can’t remember the label right now)
— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub, or mute the thread.
It’s just a normal value that’s exposed by the Security CC.
Sorry @Fishwaldo but I relly have no idea about how to do this in C++. Any code example?
I have to add a boolean property secure
in this function
void populateNode(
v8::Local<v8::Object> &nodeobj,
uint32 homeid, uint8 nodeid)
{
OpenZWave::Manager *mgr = OpenZWave::Manager::Get();
AddStringProp(nodeobj, manufacturer, mgr->GetNodeManufacturerName(homeid, nodeid).c_str());
AddStringProp(nodeobj, manufacturerid, mgr->GetNodeManufacturerId(homeid, nodeid).c_str());
AddStringProp(nodeobj, product, mgr->GetNodeProductName(homeid, nodeid).c_str());
AddStringProp(nodeobj, producttype, mgr->GetNodeProductType(homeid, nodeid).c_str());
AddStringProp(nodeobj, productid, mgr->GetNodeProductId(homeid, nodeid).c_str());
AddStringProp(nodeobj, type, mgr->GetNodeType(homeid, nodeid).c_str());
AddStringProp(nodeobj, name, mgr->GetNodeName(homeid, nodeid).c_str());
AddStringProp(nodeobj, loc, mgr->GetNodeLocation(homeid, nodeid).c_str());
AddBooleanProp(nodeobj, secure, ??????); <---------
}
Just tell me what I need to write inside ??????
to get that property, I have the properties nodeid
and homeid
available inside the function
It’s not a attribute. It’s just like any other Value (on/off level etc) that exposed via a ValueAdded Notification
Ok now I got It so In poor words I need to check if there is or not a valueid in my node to tell if it has been security added or not? Can you tell me the classid and index of the valueid to check please? @Fishwaldo
Hi @robertsLando ! Here's a snipped from some test code I wrote.
I assume you have a function that was added as a watcher, see Manager->AddWatcher(... in my case it is called OnNotification. In there you'll have a bunch of if/else or a switch statement to match on notification type
void OnNotification(OpenZWave::Notification const *notification, Main &context)
const auto valueID = notification->GetValueID();
const auto t = notification->GetType();
switch (t)
{
using OpenZWave::Notification;
case Notification::Type_DriverReady:
(... more of these)
case Notification::Type_ValueAdded:
{
// Values are stored in memory in OZW
// They get added through ValueStore::AddValue
// Each call causes a Notification::Type_ValueAdded
// Values are added when OZW starts and reads the ozwcache file
// Filter out Security related IDs
// See OpenZWave cpp/src/command_classes/Security.h
// StaticGetCommandClassId will tell you this CC is 0x98
// In the cpp you'll see it exposes a bool ValueID_Index_Security::Secured
if ((valueID.GetCommandClassId() == 0x98) && (valueID.GetIndex() == OpenZWave::ValueID_Index_Security::Secured))
{
bool secure;
context.Manager->GetValueAsBool(valueID, &secure);
std::ostringstream txt;
txt << "Received Notification::Type_ValueAdded, NodeID = " << std::setw(3) << int(valueID.GetNodeId()) << " has security set to " << secure << '\n';
std::cout << txt.str();
}
}
break;
case Notification::Type_ValueChanged:
{
// Type_ValueChanged is caused by Value::OnValueChanged
// That is a method in a base class, it is not called directly
// Firstly, it is mainly Value::OnValueRefreshed that gets called
// Different species of Values call it, eg ValueShort::OnValueRefreshed
// That "OnValueRefreshed" will get called in de command classes when
// data arrives.
// Filter out Security related IDs
// See OpenZWave cpp/src/command_classes/Security.h
// StaticGetCommandClassId will tell you this CC is 0x98
// In the cpp you'll see it exposes a bool ValueID_Index_Security::Secured
if ((valueID.GetCommandClassId() == 0x98) && (valueID.GetIndex() == OpenZWave::ValueID_Index_Security::Secured))
{
bool secure;
context.Manager->GetValueAsBool(valueID, &secure);
std::ostringstream txt;
txt << "Received Notification::Type_ValueChanged, NodeID = " << std::setw(3) << int(valueID.GetNodeId()) << " has security set to " << secure << '\n';
std::cout << txt.str();
// printValueID(valueID);
}
}
break;
This prints on my small test network:
Received Notification::Type_ValueAdded, NodeID = 8 has security set to 0
Received Notification::Type_ValueAdded, NodeID = 14 has security set to 1
Hope this helps...
@petergebruers That is what I was looking for! Is it possible to know the value of OpenZWave::ValueID_Index_Security::Secured
? I think it should be a constant, I can easily do this check on zwave2mqtt
Yes that is a constant, all those ValueID_ index are in cpp/src/ValueIDIndexesDefines.h but that file is not a normal, user edited file, it is generated from "ValueIDIndexesDefines.def". You also do not reference it directly... Instead...
It's sufficient to have #include "value_classes/ValueID.h"
in your source file, that one will pull in ValueID.h and that one pulls in the ValueIDIndexesDefines.h and loads all ValueID_Index_* stuff
This OpenZWave::ValueID_Index_Security::Secured is 0 but the whole idea is you rely on that symbolic name.
Found it here: https://github.com/OpenZWave/open-zwave/blob/master/config/Localization.xml#L843
Seems the valueId index is 0. Thanks for pointing this out @petergebruers :)
@jshridha Try with latest commit :)
@jshridha Any news?
Yeah I sent you a message on slack but I'll post it here too.
The secure flag shows up now, but they all show up as insecure. I don't think that's right because I know I added most of them securely. Check out the image below:
Sorry I have missed it! Anyway there should be a value under system section that tells if it is secured or not, can you see it?
Daniel
On 9 Oct 2019, at 01:01, Jay [email protected] wrote:
Yeah I sent you a message on slack but I'll post it here too.
The secure flag shows up now, but they all show up as insecure. I don't think that's right because I know I added most of them securely. Check out the image below:
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
@robertsLando Nope, I don't see that value. This is what I see:
@robertsLando Just checking in. I'm not sure if you saw the message above.
Yep sorry I forgot to give you a feedback but I’m stucked and I don’t know what to do right now, I need to investigate :(
Daniel
On 21 Oct 2019, at 14:03, Jay [email protected] wrote:
@robertsLando Just checking in. I'm not sure if you saw the message above.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.
@petergebruers Is there a reason why I don't see that valueID?
I am too new to OpenZWave to give a complete answer but here is at least on prerequisite.
Does not have COMMAND_CLASS_SECURITY?
Check cache file, should have:
The presence of that CC triggers the function Security::CreateVars(uint8 const _instance) in OpenZWave source cpp/src/command_classes/Security.cpp
It does:
node->CreateValueBool(ValueID::ValueGenre_System, GetCommandClassId(), _instance, ValueID_Index_Security::Secured, "Secured", "", true, false, false, 0);
So for that node/instance/cc you get a ValueID_Index_Security::Secured in the store but with default 0. Not very interesting.
Only when the device responds with its capabilities, that is function Security::HandleMsg, and flags some CC as secure(d), OpenZWave runs
Log::Write(LogLevel_Info, GetNodeId(), "Received SecurityCmd_SupportedReport from node %d (instance %d)", GetNodeId(), _instance);
m_secured = true;
if (Internal::VC::ValueBool* value = static_cast<Internal::VC::ValueBool*>(GetValue(_instance, ValueID_Index_Security::Secured)))
{
value->OnValueRefreshed(m_secured);
value->Release();
}
So it will only update that value if the device is in secure mode (obviously reporting 1)
I am not at home but I have a small 12 node production network, mostly old stuff and only 2 of them have COMMAND_CLASS_SECURITY. When I freshly start OpenZWave, I do get
Received Notification::Type_ValueAdded, NodeID = 6 has security set to 0 Received Notification::Type_ValueAdded, NodeID = 8 has security set to 0
Last time I tested that with a demo device, it did report "...has security set to 1" a bit after that first message. But his12 node production network has no secure nodes.
I don't know much about S0 security because I avoid it, it slows down quite a bit. Of course it is mandatory for a door lock... The lock won't work if it wasn't included in S0 or S2 mode. So the question about "is this node secure" mostly applies to users wanting to control eg a garage door with a generic relay. Then it is important to know that is was included in secure mode... But that is fairly obvious in the logs because you will see "Nonce" a lot.
I am not sure how other gateways do it, and I wonder if this question was asked befor and if this flag is working "as intended".
@Fishwaldo you know a bit more about this topic (detecting if communication is secure)?
Partly what I am trying to say is this... At inclusion time, a very specific dialog takes place between the node and OpenZWave. Basically it is transferring the key. If that succeeds, the node remains "secure" and needs that unique key to work. It cannot revert back to non-secure mode. You'll have to exclude it or reset it to change that. So other gateways (like my Fibaro HomeCenter 2) might simply set a flag in its database at inclusion time. Then never worry about that again.
https://github.com/OpenZWave/open-zwave/issues/2137 Waiting for this to be supported by Openzwave