Skip to content

Commit

Permalink
Include requesting principal in CMDs (#329)
Browse files Browse the repository at this point in the history
There are situations where it is useful to know the identity of the
principal who requested a CMD. Include this information in the CMD
packet in the following form:

* The `uuid` field of the CMD is set to the Factory+ UUID.
* The `body` of the CMD is a UTF-8 string starting with a scheme name
and a colon.
* The scheme `uuid:` is followed by a principal UUID in canonical string
form.
* The scheme `kerberos:` is followed by a Kerberos principal name.
* The schema `sparkplug:` is followed by a Sparkplug address in
`Group/Node` form.

(Currently Devices are not permitted to request command escalation, as
they aren't security principals and can't be authorised.)

This is a rebase of #269 onto `main`. The previous merge was lost when
we changed policy to 'main is always releasable'.
  • Loading branch information
amrc-benmorrow authored Aug 21, 2024
2 parents 4b78fc7 + 04b98ae commit 8ac6ee2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
9 changes: 8 additions & 1 deletion acs-cmdesc/lib/cmdescd.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,14 @@ export default class CmdEscD {
}
}

this.mqtt.publish(to, "CMD", [cmd]);
this.mqtt.publish({
address: to,
type: "CMD",
metrics: [cmd],
from: from instanceof Address
? `sparkplug:${from}`
: `kerberos:${from}`,
});
return log(200);
}
}
32 changes: 23 additions & 9 deletions acs-cmdesc/lib/mqttcli.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,11 @@ export default class MqttCli {
// Object.values(Changed).map(v =>
// ({ name: `Last_Changed/${v}`, type: "UUID", value: "" })));

this.publish(this.address, "BIRTH", metrics);
this.publish({
address: this.address,
type: "BIRTH",
metrics,
});
}

decode_request(metric) {
Expand Down Expand Up @@ -189,27 +193,33 @@ export default class MqttCli {
return [address, {name: tag, value}];
}

encode_metrics(metrics, kind) {
encode_metrics (opts) {
const { type, metrics, from } = opts;

const payload = {
timestamp: Date.now(),
metrics: metrics,
metrics,
};

/* CMDs don't increment the seq, because by spec they are only
* sent by the Primary App. */
if (kind != "CMD") {
if (type != "CMD") {
payload.seq = this.seq;
this.seq = (this.seq < 255) ? (this.seq + 1) : 0;
}
if (kind == "BIRTH")
if (type == "BIRTH" || type == "CMD")
payload.uuid = UUIDs.FactoryPlus;
if (type == "CMD") {
const sender = from ?? `uuid:${this.device_uuid}`;
payload.body = Buffer.from(sender.toString());
}

return SpB.encodePayload(payload);
}

async publish(addr, kind, metrics) {
const topic = addr.topic(kind);
const payload = this.encode_metrics(metrics, kind);
async publish (opts) {
const topic = opts.address.topic(opts.type);
const payload = this.encode_metrics(opts);

this.log("mqtt", `Publishing to ${topic}`);
this.mqtt.publish(topic, payload);
Expand All @@ -224,7 +234,11 @@ export default class MqttCli {

const resp = MetricBuilder.cmd.command_escalation_response(
to, cmd.name, stat);
this.publish(from, "CMD", resp);
this.publish({
address: from,
type: "CMD",
metrics: resp,
});
}
}

0 comments on commit 8ac6ee2

Please sign in to comment.