aboutsummaryrefslogtreecommitdiff
path: root/src/cred_dict.c
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2020-09-18 00:39:10 +0930
committerDavid Timber <mieabby@gmail.com>2020-09-18 00:39:10 +0930
commit54166c46f32555532dc3c0e922fe6a591cb74128 (patch)
treedee32ffb8a15365cc2800f6c2cbc3520ef56324e /src/cred_dict.c
parente6953dcb47193746a4f4d9fff0193723fadbb3e6 (diff)
* Impl: bne
* Add prne_index_nybin()
Diffstat (limited to 'src/cred_dict.c')
-rw-r--r--src/cred_dict.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/cred_dict.c b/src/cred_dict.c
new file mode 100644
index 0000000..1b6a5bb
--- /dev/null
+++ b/src/cred_dict.c
@@ -0,0 +1,151 @@
+#include "cred_dict.h"
+#include "util_rt.h"
+#include "endian.h"
+#include "strmap.h"
+
+#include <string.h>
+#include <errno.h>
+
+
+void prne_init_cred_dict (prne_cred_dict_t *p) {
+ prne_memzero(p, sizeof(prne_cred_dict_t));
+}
+
+void prne_free_cred_dict (prne_cred_dict_t *p) {
+ if (p == NULL) {
+ return;
+ }
+
+ prne_free(p->arr);
+ prne_memzero(p, sizeof(prne_cred_dict_t));
+}
+
+bool prne_build_cred_dict (
+ const prne_cred_dict_raw_entry_t *arr,
+ const size_t cnt,
+ uint8_t **out_m,
+ size_t *out_l)
+{
+ bool ret = false;
+ prne_strmap_t map;
+ uint8_t *m = NULL, *p;
+ size_t l = 0, strsize, sum_str;
+ uint16_t idx_id, idx_pw;
+
+ if (cnt > UINT16_MAX) {
+ errno = E2BIG;
+ return false;
+ }
+
+ prne_init_strmap(&map);
+
+// TRY
+ for (size_t i = 0; i < cnt; i += 1) {
+ if (arr[i].id == NULL || arr[i].pw == NULL) {
+ errno = EINVAL;
+ goto END;
+ }
+ prne_strmap_insert(&map, arr[i].id, 0);
+ prne_strmap_insert(&map, arr[i].pw, 0);
+ }
+
+ sum_str = 0;
+ for (size_t i = 0; i < map.size; i += 1) {
+ map.tbl[i].val = (prne_strmap_val_t)sum_str;
+ sum_str += strlen(map.tbl[i].key) + 1;
+ }
+ l = 2/*head*/ + 5 * cnt/*entries*/ + sum_str;
+ if (sum_str > UINT16_MAX || l > UINT16_MAX) {
+ errno = E2BIG;
+ goto END;
+ }
+
+ p = m = (uint8_t*)prne_malloc(1, l);
+ if (m == NULL) {
+ goto END;
+ }
+
+ p[0] = prne_getmsb16(cnt, 0);
+ p[1] = prne_getmsb16(cnt, 1);
+ p += 2;
+ for (size_t i = 0; i < cnt; i += 1) {
+ idx_id = (uint16_t)(prne_strmap_lookup(&map, arr[i].id)->val);
+ idx_pw = (uint16_t)(prne_strmap_lookup(&map, arr[i].pw)->val);
+ p[0] = prne_getmsb16(idx_id, 0);
+ p[1] = prne_getmsb16(idx_id, 1);
+ p[2] = prne_getmsb16(idx_pw, 0);
+ p[3] = prne_getmsb16(idx_pw, 1);
+ p[4] = arr[i].weight;
+ p += 5;
+ }
+ for (size_t i = 0; i < map.size; i += 1) {
+ strsize = strlen(map.tbl[i].key) + 1;
+ memcpy(p, map.tbl[i].key, strsize);
+ p += strsize;
+ }
+
+ *out_m = m;
+ *out_l = l;
+ m = NULL;
+ ret = true;
+END: // CATCH
+ prne_free(m);
+ prne_free_strmap(&map);
+ return ret;
+}
+
+bool prne_dser_cred_dict (
+ prne_cred_dict_t *dict,
+ const uint8_t *buf,
+ const size_t len)
+{
+ prne_cred_dict_entry_t *arr = NULL;
+ size_t cnt, head_size, m_size;
+ const uint8_t *p = buf;
+ bool ret = false;
+
+ if (len < 2) {
+ errno = EINVAL;
+ return false;
+ }
+ cnt = prne_recmb_msb16(p[0], p[1]);
+ head_size = 2 + 5 * cnt;
+ if (head_size > len) {
+ errno = EINVAL;
+ return false;
+ }
+ if (cnt > 0 && buf[len - 1] != 0) {
+ errno = EINVAL;
+ return false;
+ }
+ p += 2;
+ m_size = len - head_size;
+
+// TRY
+ arr = prne_malloc(sizeof(prne_cred_dict_entry_t), cnt);
+ if (cnt > 0 && arr == NULL) {
+ goto END;
+ }
+
+ for (size_t i = 0; i < cnt; i += 1) {
+ arr[i].id = prne_recmb_msb16(p[0], p[1]);
+ arr[i].pw = prne_recmb_msb16(p[2], p[3]);
+ arr[i].weight = p[4];
+ p += 5;
+
+ if (arr[i].id >= m_size || arr[i].pw >= m_size) {
+ errno = EINVAL;
+ goto END;
+ }
+ }
+
+ prne_free_cred_dict(dict);
+ dict->arr = arr;
+ dict->cnt = cnt;
+ dict->m = (const char *)(buf + head_size);
+ arr = NULL;
+ ret = true;
+END:
+ prne_free(arr);
+ return ret;
+}