This version 5 of the keyring has been restructured to separate the
node filesystem rework for the keyring that requires it.
See the mesh/README file for the new directory layout of the node. Instead
runtime saving of full path of the node.json file, we save it's base path,
and use that to construct all the paths needed in realtime. We also have
changed ownership of this path to node.c, and when we remove the node, we
recursively delete everything its entire tree.
Brian Gix (2):
mesh: Reconfigure node storage tree
mesh: Add key storage
Makefile.mesh | 1 +
mesh/README | 34 ++++++-
mesh/keyring.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mesh/keyring.h | 49 ++++++++++
mesh/node.c | 16 ++--
mesh/node.h | 4 +-
mesh/storage.c | 144 +++++++++++++++++-----------
7 files changed, 478 insertions(+), 67 deletions(-)
create mode 100644 mesh/keyring.c
create mode 100644 mesh/keyring.h
--
2.14.5
Add a tree structure to a nodes data storage, in order to safely handle
Replay Protection list, Refactor local Sequence Numbers, and add Key
storage for Config Client nodes.
---
mesh/README | 34 +++++++++++++-
mesh/node.c | 16 ++++---
mesh/node.h | 4 +-
mesh/storage.c | 144 ++++++++++++++++++++++++++++++++++-----------------------
4 files changed, 131 insertions(+), 67 deletions(-)
diff --git a/mesh/README b/mesh/README
index ca223a6d8..82fd5a017 100644
--- a/mesh/README
+++ b/mesh/README
@@ -36,8 +36,40 @@ Each subdirectory contains the following files:
provisioner/configuration client
- node.json.bak:
a backup that the last known good node configuration.
+ - seq_num:
+ File containing next sequence number to use
+ - seq_num.bak:
+ Backup of the sequence number. This may be larger than the
+ actual sequence number being used at runtime, to prevent re-use
+ of sequence numbers in the event of an unexpected restart.
+ - ./rpl/:
+ Directory to store the sequence numbers of remote nodes, as
+ required by Replay Protection List (RPL) parameters.
+ - xxxx:
+ Files named for remote Unicast addresses, and contain
+ last received iv_index + seq_num from each SRC address.
+ - ./dev_keys/:
+ Directory to store remote Device keys. This is only created/used
+ by Configuration Client (Network administration) nodes.
+ - xxxx:
+ Files named for remote Unicast addresses, and contains
+ 16 octet key.
+ - ./net_keys/:
+ Directory to store network subnet keys. This is only
+ created/used by Configuration Client (Network administration)
+ nodes.
+ - xxx:
+ Files named for subnet index, and contains key refresh
+ phase, and old/new versions of the key.
+ - ./app_keys/:
+ Directory to store application keys. This is only created/used
+ by Configuration Client (Network administration) nodes.
+ - xxx:
+ Files named for application index, and contains bound
+ subnet index, and old/new versions of the key.
-The files are in JSON format.
+The node.json and node.json.bak are in JSON format. All other files are stored
+in little endian binary format.
Information
===========
diff --git a/mesh/node.c b/mesh/node.c
index 5904b116c..6f95c8d1c 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -79,7 +79,7 @@ struct mesh_node {
char *owner;
char *path;
void *jconfig;
- char *cfg_file;
+ char *node_path;
uint32_t disc_watch;
time_t upd_sec;
uint32_t seq_number;
@@ -236,6 +236,7 @@ static void free_node_resources(void *data)
l_free(node->comp);
l_free(node->app_path);
l_free(node->owner);
+ l_free(node->node_path);
if (node->disc_watch)
l_dbus_remove_watch(dbus_get_bus(), node->disc_watch);
@@ -259,7 +260,7 @@ void node_remove(struct mesh_node *node)
l_queue_remove(nodes, node);
- if (node->cfg_file)
+ if (node->node_path)
storage_remove_node_config(node);
free_node_resources(node);
@@ -395,7 +396,7 @@ static void cleanup_node(void *data)
struct mesh_net *net = node->net;
/* Save local node configuration */
- if (node->cfg_file) {
+ if (node->node_path) {
/* Preserve the last sequence number */
storage_write_sequence_number(net, mesh_net_get_seq_num(net));
@@ -1859,14 +1860,15 @@ void *node_jconfig_get(struct mesh_node *node)
return node->jconfig;
}
-void node_cfg_file_set(struct mesh_node *node, char *cfg)
+void node_path_set(struct mesh_node *node, char *path)
{
- node->cfg_file = cfg;
+ l_free(node->node_path);
+ node->node_path = l_strdup(path);
}
-char *node_cfg_file_get(struct mesh_node *node)
+char *node_path_get(struct mesh_node *node)
{
- return node->cfg_file;
+ return node->node_path;
}
struct mesh_net *node_get_net(struct mesh_node *node)
diff --git a/mesh/node.h b/mesh/node.h
index 1be4de1da..1194ff837 100644
--- a/mesh/node.h
+++ b/mesh/node.h
@@ -95,5 +95,5 @@ bool node_dbus_init(struct l_dbus *bus);
void node_cleanup_all(void);
void node_jconfig_set(struct mesh_node *node, void *jconfig);
void *node_jconfig_get(struct mesh_node *node);
-void node_cfg_file_set(struct mesh_node *node, char *cfg);
-char *node_cfg_file_get(struct mesh_node *node);
+void node_path_set(struct mesh_node *node, char *path);
+char *node_path_get(struct mesh_node *node);
diff --git a/mesh/storage.c b/mesh/storage.c
index 2580cbe7f..f4e23bf49 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -28,6 +28,7 @@
#include <unistd.h>
#include <dirent.h>
#include <libgen.h>
+#include <ftw.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -49,13 +50,30 @@
struct write_info {
json_object *jnode;
- const char *config_name;
+ const char *node_path;
void *user_data;
mesh_status_func_t cb;
};
+static const char *cfg_name = "/node.json";
+static const char *bak_ext = ".bak";
+static const char *tmp_ext = ".tmp";
static const char *storage_dir;
+/* This is a thread-safe always malloced version of dirname which will work
+ * regardless of which underlying dirname() implementation is used.
+ */
+static char *alloc_dirname(const char *path)
+{
+ char *tmp = l_strdup(path);
+ char *dir;
+
+ dir = dirname(tmp);
+ strncpy(tmp, dir, strlen(path) + 1);
+
+ return tmp;
+}
+
static bool read_node_cb(struct mesh_db_node *db_node, void *user_data)
{
struct mesh_node *node = user_data;
@@ -166,7 +184,7 @@ static bool parse_node(struct mesh_node *node, json_object *jnode)
return true;
}
-static bool parse_config(char *in_file, char *out_file, const uint8_t uuid[16])
+static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
{
int fd;
char *str;
@@ -213,7 +231,7 @@ static bool parse_config(char *in_file, char *out_file, const uint8_t uuid[16])
}
node_jconfig_set(node, jnode);
- node_cfg_file_set(node, out_file);
+ node_path_set(node, out_dir);
done:
close(fd);
@@ -430,15 +448,12 @@ static bool save_config(json_object *jnode, const char *config_name)
static void idle_save_config(void *user_data)
{
struct write_info *info = user_data;
- size_t len = strlen(info->config_name) + 5;
- char *tmp = l_malloc(len);
- char *bak = l_malloc(len);
+ char *tmp, *bak, *cfg;
bool result = false;
- strncpy(tmp, info->config_name, len);
- strncpy(bak, info->config_name, len);
- tmp = strncat(tmp, ".tmp", 5);
- bak = strncat(bak, ".bak", 5);
+ cfg = l_strdup_printf("%s%s", info->node_path, cfg_name);
+ tmp = l_strdup_printf("%s%s", cfg, tmp_ext);
+ bak = l_strdup_printf("%s%s", cfg, bak_ext);
remove(tmp);
l_debug("Storage-Wrote");
@@ -446,13 +461,14 @@ static void idle_save_config(void *user_data)
if (result) {
remove(bak);
- rename(info->config_name, bak);
- rename(tmp, info->config_name);
+ rename(cfg, bak);
+ rename(tmp, cfg);
}
remove(tmp);
l_free(tmp);
l_free(bak);
+ l_free(cfg);
if (info->cb)
info->cb(info->user_data, result);
@@ -467,7 +483,7 @@ void storage_save_config(struct mesh_node *node, bool no_wait,
info = l_new(struct write_info, 1);
info->jnode = node_jconfig_get(node);
- info->config_name = node_cfg_file_get(node);
+ info->node_path = node_path_get(node);
info->cb = cb;
info->user_data = user_data;
@@ -517,6 +533,7 @@ bool storage_load_nodes(const char *dir_name)
{
DIR *dir;
struct dirent *entry;
+ size_t path_len = strlen(dir_name) + strlen(cfg_name) + strlen(bak_ext);
create_dir(dir_name);
dir = opendir(dir_name);
@@ -529,33 +546,37 @@ bool storage_load_nodes(const char *dir_name)
storage_dir = dir_name;
while ((entry = readdir(dir)) != NULL) {
- char *cfg;
- char *bak;
+ char *dir, *cfg, *bak;
uint8_t uuid[16];
+ size_t node_len;
if (entry->d_type != DT_DIR)
continue;
- if (!str2hex(entry->d_name, strlen(entry->d_name), uuid, sizeof(uuid)))
+ /* Check path length */
+ node_len = strlen(entry->d_name);
+ if (path_len + node_len + 1 >= PATH_MAX)
continue;
- cfg = l_strdup_printf("%s/%s/node.json", dir_name, entry->d_name);
-
- if (parse_config(cfg, cfg, uuid))
+ if (!str2hex(entry->d_name, node_len, uuid, sizeof(uuid)))
continue;
- /* Fall-back to Backup version */
- bak = l_strdup_printf("%s/%s/node.json.bak", dir_name, entry->d_name);
+ dir = l_strdup_printf("%s/%s", dir_name, entry->d_name);
+ cfg = l_strdup_printf("%s%s", dir, cfg_name);
- if (parse_config(bak, cfg, uuid)) {
- remove(cfg);
- rename(bak, cfg);
- l_free(cfg);
- continue;
- }
+ if (!parse_config(cfg, dir, uuid)) {
+ /* Fall-back to Backup version */
+ bak = l_strdup_printf("%s%s", cfg, bak_ext);
+
+ if (parse_config(bak, dir, uuid)) {
+ remove(cfg);
+ rename(bak, cfg);
+ }
+ l_free(bak);
+ }
l_free(cfg);
- l_free(bak);
+ l_free(dir);
}
return true;
@@ -566,8 +587,8 @@ bool storage_create_node_config(struct mesh_node *node, void *data)
struct mesh_db_node *db_node = data;
char uuid[33];
char name_buf[PATH_MAX];
- char *filename;
json_object *jnode;
+ size_t max_len = strlen(cfg_name) + strlen(bak_ext);
if (!storage_dir)
return false;
@@ -578,25 +599,26 @@ bool storage_create_node_config(struct mesh_node *node, void *data)
return false;
if (!hex2str(node_uuid_get(node), 16, uuid, sizeof(uuid)))
- return false;
+ goto fail;
snprintf(name_buf, PATH_MAX, "%s/%s", storage_dir, uuid);
+ if (strlen(name_buf) + max_len >= PATH_MAX)
+ goto fail;
+
/* Create a new directory and node.json file */
if (mkdir(name_buf, 0755) != 0)
goto fail;
- filename = l_strdup_printf("%s/node.json", name_buf);
+ node_path_set(node, name_buf);
- l_debug("New node config %s", filename);
+ snprintf(name_buf, PATH_MAX, "%s/%s%s", storage_dir, uuid, cfg_name);
+ l_debug("New node config %s", name_buf);
- if (!save_config(jnode, filename)) {
- l_free(filename);
+ if (!save_config(jnode, name_buf))
goto fail;
- }
node_jconfig_set(node, jnode);
- node_cfg_file_set(node, filename);
return true;
fail:
@@ -604,13 +626,29 @@ fail:
return false;
}
+static int del_fobject(const char *fpath, const struct stat *sb, int typeflag,
+ struct FTW *ftwbuf)
+{
+ switch (typeflag) {
+ case FTW_DP:
+ rmdir(fpath);
+ l_debug("RMDIR %s", fpath);
+ break;
+
+ case FTW_SL:
+ default:
+ remove(fpath);
+ l_debug("RM %s", fpath);
+ break;
+ }
+ return 0;
+}
+
/* Permanently remove node configuration */
void storage_remove_node_config(struct mesh_node *node)
{
- char *cfg;
+ char *node_path, *mesh_path, *mesh_name;
struct json_object *jnode;
- const char *dir_name;
- char *bak;
if (!node)
return;
@@ -621,25 +659,17 @@ void storage_remove_node_config(struct mesh_node *node)
json_object_put(jnode);
node_jconfig_set(node, NULL);
- /* Delete node configuration file */
- cfg = node_cfg_file_get(node);
- if (!cfg)
- return;
-
- l_debug("Delete node config file %s", cfg);
- remove(cfg);
-
- /* Delete the backup file */
- bak = l_strdup_printf("%s.bak", cfg);
- remove(bak);
- l_free(bak);
+ node_path = node_path_get(node);
+ l_debug("Delete node config %s", node_path);
- /* Delete the node directory */
- dir_name = dirname(cfg);
+ /* Make sure path name of node follows expected guidelines */
+ mesh_path = alloc_dirname(node_path);
+ mesh_name = basename(mesh_path);
+ if (strcmp(mesh_name, "mesh"))
+ goto done;
- l_debug("Delete directory %s", dir_name);
- rmdir(dir_name);
+ nftw(node_path, del_fobject, 5, FTW_DEPTH | FTW_PHYS);
- l_free(cfg);
- node_cfg_file_set(node, NULL);
+done:
+ l_free(mesh_path);
}
--
2.14.5
This implements internal key storage add/delete/fetch for the three
basic key types managed in Mesh: Network, Application and Device.
This key storage is separate from keys assigned to nodes within the
mesh, and are used to support Configuration Client functionality.
---
Makefile.mesh | 1 +
mesh/keyring.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mesh/keyring.h | 49 ++++++++++
3 files changed, 347 insertions(+)
create mode 100644 mesh/keyring.c
create mode 100644 mesh/keyring.h
diff --git a/Makefile.mesh b/Makefile.mesh
index 76e424b92..bccd4d946 100644
--- a/Makefile.mesh
+++ b/Makefile.mesh
@@ -25,6 +25,7 @@ mesh_sources = mesh/mesh.h mesh/mesh.c \
mesh/agent.h mesh/agent.c \
mesh/prov-acceptor.c mesh/prov-initiator.c \
mesh/pb-adv.h mesh/pb-adv.c \
+ mesh/keyring.h mesh/keyring.c \
mesh/mesh-defs.h
libexec_PROGRAMS += mesh/bluetooth-meshd
diff --git a/mesh/keyring.c b/mesh/keyring.c
new file mode 100644
index 000000000..0ca53b0f8
--- /dev/null
+++ b/mesh/keyring.c
@@ -0,0 +1,297 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <libgen.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ell/ell.h>
+
+#include "mesh/mesh-defs.h"
+
+#include "mesh/net.h"
+#include "mesh/keyring.h"
+#include "mesh/mesh.h"
+#include "mesh/node.h"
+
+const char *dev_key_dir = "/dev_keys";
+const char *app_key_dir = "/app_keys";
+const char *net_key_dir = "/net_keys";
+
+bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx,
+ struct keyring_net_key *key)
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+ bool result = false;
+ int fd;
+
+ if (!node || !key)
+ return false;
+
+ node_path = node_path_get(node);
+
+ if (strlen(node_path) + strlen(net_key_dir) + 1 + 3 >= PATH_MAX)
+ return false;
+
+ snprintf(key_file, PATH_MAX, "%s%s", node_path, net_key_dir);
+ mkdir(key_file, 0755);
+ snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
+ net_idx);
+ l_debug("Put Net Key %s", key_file);
+
+ fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC);
+ if (fd > 0) {
+ if (write(fd, key, sizeof(*key)) == sizeof(*key))
+ result = true;
+
+ close(fd);
+ }
+
+ return result;
+}
+
+bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx,
+ uint16_t net_idx, struct keyring_app_key *key)
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+ bool result = false;
+ int fd;
+
+ if (!node || !key)
+ return false;
+
+ node_path = node_path_get(node);
+
+ if (strlen(node_path) + strlen(app_key_dir) + 1 + 3 >= PATH_MAX)
+ return false;
+
+ snprintf(key_file, PATH_MAX, "%s%s", node_path, app_key_dir);
+ mkdir(key_file, 0755);
+ snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
+ app_idx);
+ l_debug("Put App Key %s", key_file);
+
+ fd = open(key_file, O_RDONLY);
+ if (fd > 0) {
+ struct keyring_app_key old_key;
+
+ if (read(fd, &old_key, sizeof(old_key)) == sizeof(old_key)) {
+ if (old_key.net_idx != net_idx) {
+ close(fd);
+ return false;
+ }
+ }
+ close(fd);
+ }
+
+ fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC);
+ if (fd > 0) {
+ if (write(fd, key, sizeof(*key)) == sizeof(*key))
+ result = true;
+ }
+ close(fd);
+
+ return result;
+}
+
+bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+ uint8_t count, uint8_t dev_key[16])
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+ bool result = true;
+ int fd, i;
+
+ if (!node)
+ return false;
+
+ node_path = node_path_get(node);
+
+ if (strlen(node_path) + strlen(dev_key_dir) + 1 + 4 >= PATH_MAX)
+ return false;
+
+ snprintf(key_file, PATH_MAX, "%s%s", node_path, dev_key_dir);
+ mkdir(key_file, 0755);
+
+ for (i = 0; i < count; i++) {
+ snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path,
+ dev_key_dir, unicast + i);
+ l_debug("Put Dev Key %s", key_file);
+
+ fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC);
+ if (fd > 0) {
+ if (write(fd, dev_key, 16) != 16)
+ result = false;
+
+ close(fd);
+ } else
+ result = false;
+ }
+
+ return result;
+}
+
+bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx,
+ struct keyring_net_key *key)
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+ bool result = false;
+ int fd;
+
+ if (!node || !key)
+ return false;
+
+ node_path = node_path_get(node);
+ snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
+ net_idx);
+
+ fd = open(key_file, O_RDONLY);
+ if (fd > 0) {
+ if (read(fd, key, sizeof(*key)) == sizeof(*key))
+ result = true;
+
+ close(fd);
+ }
+
+ return result;
+}
+
+bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx,
+ struct keyring_app_key *key)
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+ bool result = false;
+ int fd;
+
+ if (!node || !key)
+ return false;
+
+ node_path = node_path_get(node);
+ snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
+ app_idx);
+
+ fd = open(key_file, O_RDONLY);
+ if (fd > 0) {
+ if (read(fd, key, sizeof(*key)) == sizeof(*key))
+ result = true;
+
+ close(fd);
+ }
+
+ return result;
+}
+
+bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+ uint8_t dev_key[16])
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+ bool result = false;
+ int fd;
+
+ if (!node)
+ return false;
+
+ node_path = node_path_get(node);
+ snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, dev_key_dir,
+ unicast);
+
+ fd = open(key_file, O_RDONLY);
+ if (fd > 0) {
+ if (read(fd, dev_key, 16) == 16)
+ result = true;
+
+ close(fd);
+ }
+
+ return result;
+}
+
+bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx)
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+
+ if (!node)
+ return false;
+
+ node_path = node_path_get(node);
+ snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
+ net_idx);
+ l_debug("RM Net Key %s", key_file);
+ remove(key_file);
+
+ /* TODO: See if it is easiest to delete all bound App keys here */
+ /* TODO: see nftw() */
+
+ return true;
+}
+
+bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx)
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+
+ if (!node)
+ return false;
+
+ node_path = node_path_get(node);
+ snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
+ app_idx);
+ l_debug("RM App Key %s", key_file);
+ remove(key_file);
+
+ return true;
+}
+
+bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+ uint8_t count)
+{
+ char *node_path;
+ char key_file[PATH_MAX];
+ int i;
+
+ if (!node)
+ return false;
+
+ node_path = node_path_get(node);
+ for (i = 0; i < count; i++) {
+ snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path,
+ dev_key_dir, unicast + i);
+ l_debug("RM Dev Key %s", key_file);
+ remove(key_file);
+ }
+
+ return true;
+}
diff --git a/mesh/keyring.h b/mesh/keyring.h
new file mode 100644
index 000000000..167191013
--- /dev/null
+++ b/mesh/keyring.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+struct keyring_net_key {
+ uint16_t net_idx;
+ uint8_t phase;
+ uint8_t old_key[16];
+ uint8_t new_key[16];
+};
+
+struct keyring_app_key {
+ uint16_t app_idx;
+ uint16_t net_idx;
+ uint8_t old_key[16];
+ uint8_t new_key[16];
+};
+
+bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx,
+ struct keyring_net_key *key);
+bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx,
+ struct keyring_net_key *key);
+bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx);
+bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx,
+ uint16_t net_idx, struct keyring_app_key *key);
+bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx,
+ struct keyring_app_key *key);
+bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx);
+bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+ uint8_t dev_key[16]);
+bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+ uint8_t count, uint8_t dev_key[16]);
+bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast,
+ uint8_t count);
--
2.14.5
Hi again,
On 05/09, Brian Gix wrote:
> + fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC);
> + if (fd > 0) {
Hm. I might be mistaken, since I'm not that much familiar with systemd
internals, but 'back in the day' daemons were expected to close their
stdin, leaving descriptor #0 free for reuse.
regards
--
Michał Lowas-Rzechonek <[email protected]>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND