46 #define PERM_TABLE_ROWS (sizeof(permission_table)/sizeof(permission_table)[0])
49 size_t offset,
size_t *new_offset,
struct json_tokener *tokener,
50 Com__Seagate__Kinetic__Proto__Command__Security__ACL **instance);
52 int scope_count, json_object *scopes);
59 if (pp->permission == perm) {
return pp->string; }
68 if (0 == strcmp(str, pp->string)) {
return pp->permission; }
76 if (path == NULL || instance == NULL) {
80 int fd = open(path, O_RDONLY);
83 LOGF0(
"Failed ot open file '%s': %s", path, strerror(errno));
90 const int BUF_START_SIZE = 256;
91 char *buf = calloc(1, BUF_START_SIZE);
96 size_t buf_sz = BUF_START_SIZE;
101 read_sz = read(fd, &buf[buf_used], buf_sz - buf_used);
105 }
else if (read_sz == 0) {
109 if (buf_sz == buf_used) {
110 size_t nsz = 2 * buf_sz;
111 char *nbuf = realloc(buf, nsz);
121 LOGF2(
" -- read %zd bytes, parsing...", buf_used);
125 if (buf) { free(buf); }
133 struct ACL *acl_group = NULL;
134 Com__Seagate__Kinetic__Proto__Command__Security__ACL **acl_array = NULL;
135 struct json_tokener* tokener = NULL;
137 acl_group = calloc(1,
sizeof(*acl_group));
138 if (acl_group == NULL) {
goto cleanup; }
140 acl_group->
ACLs = calloc(1,
sizeof(Com__Seagate__Kinetic__Proto__Command__Security__ACL *));
141 if (acl_group->
ACLs == NULL) {
goto cleanup; }
145 tokener = json_tokener_new();
146 if (tokener == NULL) {
goto cleanup; }
150 while (buf_size - offset > 0) {
151 size_t offset_out = 0;
152 Com__Seagate__Kinetic__Proto__Command__Security__ACL *new_acl = NULL;
154 LOGF2(
" -- reading next ACL at offset %zd, rem %zd", offset, buf_size - offset);
157 &offset_out, tokener, &new_acl);
158 offset += offset_out;
160 LOGF2(
" -- result %d, offset_out %zd", res, offset);
164 size_t nsz = 2 * acl_group->
ACL_ceil *
sizeof(acl_group->
ACLs[0]);
165 Com__Seagate__Kinetic__Proto__Command__Security__ACL **nACLs = realloc(acl_group->
ACLs, nsz);
170 acl_group->
ACLs = nACLs;
181 if (tokener) { json_tokener_free(tokener); }
184 if (acl_group && acl_group->
ACL_count == 0) {
185 LOG2(
"Failed to read any JSON objects");
188 *instance = acl_group;
192 if (acl_group) { free(acl_group); }
193 if (acl_array) { free(acl_array); }
199 size_t offset,
size_t *new_offset,
200 struct json_tokener *tokener, Com__Seagate__Kinetic__Proto__Command__Security__ACL **instance)
202 struct json_object *obj = json_tokener_parse_ex(tokener,
203 &buf[offset], buf_size - offset);
205 if (json_tokener_get_error(tokener) == json_tokener_error_parse_eof) {
208 LOGF2(
"JSON error %d", json_tokener_get_error(tokener));
213 *new_offset = tokener->char_offset;
216 Com__Seagate__Kinetic__Proto__Command__Security__ACL *acl = NULL;
217 uint8_t *data = NULL;
220 struct json_object *val = NULL;
221 if (json_object_object_get_ex(obj,
"scope", &val)) {
222 scope_count = json_object_array_length(val);
228 size_t alloc_sz =
sizeof(*acl);
229 acl = calloc(1, alloc_sz);
230 if (acl == NULL) {
goto cleanup; }
235 if (json_object_object_get_ex(obj,
"identity", &val)) {
236 acl->has_identity =
true;
237 acl->identity = json_object_get_int64(val);
239 acl->has_identity =
false;
242 if (json_object_object_get_ex(obj,
"key", &val)) {
243 const char *key = json_object_get_string(val);
244 size_t len = strlen(key);
246 acl->has_hmacalgorithm =
true;
250 data = calloc(1, len + 1);
251 if (data == NULL) {
goto cleanup; }
252 memcpy(data, key, len);
254 acl->key.data = data;
259 if (json_object_object_get_ex(obj,
"HMACAlgorithm", &val)) {
260 const char *hmac = json_object_get_string(val);
261 if (0 != strcmp(hmac,
"HmacSHA1")) {
269 struct json_object *scopes = NULL;
270 if (json_object_object_get_ex(obj,
"scope", &scopes)) {
272 if (res !=
ACL_OK) {
goto cleanup; }
276 json_object_put(obj);
280 if (obj) { json_object_put(obj); }
281 if (acl) { free(acl); }
282 if (data) { free(data); }
287 int scope_count, json_object *scopes)
290 Com__Seagate__Kinetic__Proto__Command__Security__ACL__Scope **scope_array = NULL;
292 Com__Seagate__Kinetic__Proto__Command__Security__ACL__Scope *scope = NULL;
293 uint8_t *data = NULL;
295 scope_array = calloc(scope_count,
sizeof(*scope_array));
296 if (scope_array == NULL) {
goto cleanup; }
298 acl->scope = scope_array;
300 for (
int si = 0; si < scope_count; si++) {
301 struct json_object *cur_scope = json_object_array_get_idx(scopes, si);
303 scope = calloc(1,
sizeof(*scope));
304 if (scope == NULL) {
goto cleanup; }
307 struct json_object *val = NULL;
308 if (json_object_object_get_ex(cur_scope,
"offset", &val)) {
309 scope->offset = json_object_get_int64(val);
310 scope->has_offset =
true;
312 scope->has_offset =
false;
315 if (json_object_object_get_ex(cur_scope,
"value", &val)) {
316 const char *str = json_object_get_string(val);
318 size_t len = strlen(str);
319 data = malloc(len + 1);
323 memcpy(data, str, len);
325 scope->value.data = data;
326 scope->value.len = len;
328 scope->has_value =
true;
332 scope->has_value =
false;
335 scope->n_permission = 0;
336 if (json_object_object_get_ex(cur_scope,
"permission", &val)) {
338 if (perm_array == NULL) {
goto cleanup; }
339 scope->permission = perm_array;
342 enum json_type perm_type = json_object_get_type(val);
343 if (perm_type == json_type_string) {
348 scope->n_permission++;
350 }
else if (perm_type == json_type_array) {
351 int count = json_object_array_length(val);
352 for (
int i = 0; i < count; i++) {
353 struct json_object *jperm = json_object_array_get_idx(val, i);
359 scope->permission[scope->n_permission] = p;
360 scope->n_permission++;
367 if (json_object_object_get_ex(cur_scope,
"TlsRequired", &val)) {
368 scope->tlsrequired = json_object_get_boolean(val);
369 scope->has_tlsrequired =
true;
372 acl->scope[acl->n_scope] = scope;
377 acl->n_scope = scope_count;
381 if (scope_array) { free(scope_array); }
382 if (scope) { free(scope); }
383 if (perm_array) { free(perm_array); }
384 if (data) { free(data); }
391 fprintf(f,
"NULL\n");
395 fprintf(f,
"ACLs [%zd]:\n", ACLs->
ACL_count);
397 for (
size_t ai = 0; ai < ACLs->
ACL_count; ai++) {
398 Com__Seagate__Kinetic__Proto__Command__Security__ACL *acl = ACLs->
ACLs[ai];
399 if (acl == NULL) {
continue; }
400 if (ai > 0) { fprintf(f,
"\n"); }
402 if (acl->has_identity) {
403 fprintf(f,
" identity: %lld\n", (
long long)acl->identity);
407 fprintf(f,
" key[%s,%zd]: \"%s\"\n",
408 "HmacSHA1", acl->key.len, acl->key.data);
411 fprintf(f,
" scopes: (%zd)\n", acl->n_scope);
413 for (
size_t si = 0; si < acl->n_scope; si++) {
414 Com__Seagate__Kinetic__Proto__Command__Security__ACL__Scope *scope = acl->scope[si];
415 if (si > 0) { fprintf(f,
"\n"); }
416 fprintf(f,
" scope %zd:\n", si);
417 if (scope->has_offset) {
418 fprintf(f,
" offset: %lld\n", (
long long)scope->offset);
420 if (scope->has_value) {
421 fprintf(f,
" value[%zd]: \"%s\"\n",
422 scope->value.len, scope->value.data);
424 for (
size_t pi = 0; pi < scope->n_permission; pi++) {
425 fprintf(f,
" permission: %s\n",
429 if (scope->has_tlsrequired) {
430 fprintf(f,
" tlsrequired: %d\n", scope->tlsrequired);
438 for (
size_t ai = 0; ai < ACLs->
ACL_count; ai++) {
439 Com__Seagate__Kinetic__Proto__Command__Security__ACL *acl = ACLs->
ACLs[ai];
441 for (
size_t si = 0; si < acl->n_scope; si++) {
442 Com__Seagate__Kinetic__Proto__Command__Security__ACL__Scope *scope = acl->scope[si];
443 if (scope->has_value && scope->value.data) {
444 free(scope->value.data);
447 if (scope->n_permission > 0) {
448 free(scope->permission);
454 if (acl->has_key && acl->key.data) {
Com__Seagate__Kinetic__Proto__Command__Security__ACL__Permission
void KineticACL_Free(struct ACL *ACLs)
void com__seagate__kinetic__proto__command__security__acl__scope__init(Com__Seagate__Kinetic__Proto__Command__Security__ACL__Scope *message)
static KineticACLLoadResult unpack_scopes(Com__Seagate__Kinetic__Proto__Command__Security__ACL *acl, int scope_count, json_object *scopes)
static Com__Seagate__Kinetic__Proto__Command__Security__ACL__Permission permission_of_str(const char *str)
static KineticACLLoadResult acl_of_string(const char *buf, size_t buf_size, struct ACL **instance)
void com__seagate__kinetic__proto__command__security__acl__init(Com__Seagate__Kinetic__Proto__Command__Security__ACL *message)
Com__Seagate__Kinetic__Proto__Command__Security__ACL ** ACLs
ACL struct array.
#define LOGF0(message,...)
KineticACLLoadResult KineticACL_LoadFromFile(const char *path, struct ACL **instance)
static permission_pair permission_table[]
Unable to open JSON file.
void KineticACL_Print(FILE *f, struct ACL *ACLs)
#define ACL_MAX_PERMISSIONS
size_t ACL_ceil
Ceiling of ACLs array: resize if count == ceil.
size_t ACL_count
How many ACL * structs are in ACLs[].
Memory allocation failure.
static KineticACLLoadResult read_next_ACL(const char *buf, size_t buf_size, size_t offset, size_t *new_offset, struct json_tokener *tokener, Com__Seagate__Kinetic__Proto__Command__Security__ACL **instance)
#define LOGF2(message,...)
static const char * str_of_permission(Com__Seagate__Kinetic__Proto__Command__Security__ACL__Permission perm)