Browse Source
Checkpoint sekrits code
Checkpoint sekrits code
Sekrits is a small library to store/load secrets from plain text files, a pretty useful tool for building something that needs to communicate securely with something else.trunk
4 changed files with 193 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||
int main(int argc, const char *argv[]) { |
|||
return 0; |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
#include <stdlib.h> |
|||
#include <stdio.h> |
|||
#include <string.h> |
|||
|
|||
#include "sekrits.h" |
|||
|
|||
/// SEKRITS CODE |
|||
|
|||
struct sekrits_node { |
|||
struct sekrits_node *next; |
|||
char *name; |
|||
char *value; |
|||
}; |
|||
|
|||
struct sekrits { |
|||
struct sekrits_node *root; |
|||
}; |
|||
|
|||
int sekrits_create_from_filename(struct sekrits **ppsekrits, const char *filename) { |
|||
FILE *stream = fopen(filename, "r"); |
|||
if (stream == NULL) { |
|||
perror("couldn't open file"); |
|||
return SEKRITS_ERROR; |
|||
} |
|||
int result = sekrits_create_from_file(ppsekrits, stream); |
|||
fclose(stream); |
|||
return result; |
|||
} |
|||
|
|||
/* used to define how long a sekrit line is allowed to be (this includes the |
|||
* sekrit name and value) */ |
|||
#define SEKRIT_MAX_LINE_LEN 8096 |
|||
|
|||
int sekrits_create_from_file(struct sekrits **ppsekrits, FILE *file) { |
|||
struct sekrits *out = (struct sekrits *)malloc(sizeof(struct sekrits)); |
|||
if (file == NULL) { |
|||
return SEKRITS_ERROR; |
|||
} |
|||
char sekrit_buf[SEKRIT_MAX_LINE_LEN] = {0}; |
|||
char *line_end; |
|||
size_t line_num = 0; |
|||
while ((line_end = fgets(sekrit_buf, SEKRIT_MAX_LINE_LEN, file)) != NULL) { |
|||
++line_num; |
|||
ssize_t total_len = line_end - sekrit_buf; |
|||
char *iter; |
|||
for (iter = sekrit_buf; iter < line_end; ++iter) { |
|||
if (*iter == '\\') { |
|||
++iter; |
|||
continue; |
|||
} else if (*iter == '=') { |
|||
*iter = '\0'; |
|||
++iter; |
|||
break; |
|||
} |
|||
} |
|||
char *name = sekrit_buf; |
|||
size_t name_len = iter - sekrit_buf; |
|||
char *value = iter; |
|||
size_t value_len = line_end - iter; |
|||
// char name_buf[SEKRIT_MAX_LINE_LEN] = {0}; |
|||
// char value_buf[SEKRIT_MAX_LINE_LEN] = {0}; |
|||
// char terminator = 0; |
|||
// int read_bytes = 0; |
|||
// do { |
|||
// int res = sscanf(file, "%[^\\=]%n%[\=]c%s", name_buf, &read_bytes, ); |
|||
// } while (res != 2); |
|||
}; |
|||
*ppsekrits = out; |
|||
return SEKRITS_OK; |
|||
} |
|||
|
|||
int sekrits_destroy(struct sekrits *thing) { |
|||
if (thing != NULL) { |
|||
free(thing); |
|||
} |
|||
return SEKRITS_OK; |
|||
} |
|||
int sekrits_fetch(const struct sekrits *, const char *name, char *buf, size_t len); |
|||
|
|||
const char *sekrits_get(struct sekrits *secrets, const char *name) { |
|||
if (secrets == NULL) { |
|||
return NULL; |
|||
} |
|||
struct sekrits_node *curr = secrets->root; |
|||
while (curr != NULL) { |
|||
if (strcmp(curr->name, name)) { |
|||
return curr->value; |
|||
} |
|||
curr = curr->next; |
|||
}; |
|||
return NULL; |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
#ifndef WTFTRAINS_SEKRITS_H |
|||
#define WTFTRAINS_SEKRITS_H |
|||
|
|||
/** |
|||
* Library for loading/storing secrets encoded as simple NAME=VALUE, |
|||
* newline-delimited pairs in a text file. |
|||
*/ |
|||
|
|||
#define SEKRITS_ERROR -1 |
|||
#define SEKRITS_OK 0 |
|||
|
|||
/* opaque struct for storing sekrit information */ |
|||
struct sekrits; |
|||
|
|||
/* load a secret store from an opened file handle */ |
|||
int sekrits_create_from_file(struct sekrits **, FILE *file); |
|||
/* load a secret store from a filename */ |
|||
int sekrits_create_from_filename(struct sekrits **, const char *filename); |
|||
/* destroys an object created with sekrits_create_* */ |
|||
int sekrits_destroy(struct sekrits *); |
|||
|
|||
/* lists all of the names */ |
|||
int sekrits_list_names(const struct sekrits *, char ** names, size_t len); |
|||
/* fetches one specific value, given a name */ |
|||
int sekrits_fetch(const struct sekrits *, const char *name, char *buf, size_t len); |
|||
|
|||
/* convenience function to get the value of a sekrit */ |
|||
const char *sekrits_get(struct sekrits *secrets, const char *name); |
|||
|
|||
#endif // WTFTRAINS_SEKRITS_H |
|||
@ -0,0 +1,68 @@ |
|||
#include <stdlib.h> |
|||
#include <stdio.h> |
|||
#include <check.h> |
|||
|
|||
#include "../src/sekrits.h" |
|||
|
|||
START_TEST(test_create_from_file) { |
|||
const char *cases[] ={ |
|||
"hello=true", |
|||
"OK=FINE\n", |
|||
"notok" |
|||
}; |
|||
for (int i = 0; i < sizeof(cases); ++ i) { |
|||
struct sekrits *secrets = NULL; |
|||
FILE *data = fmemopen((char *)cases[i], strlen(cases[i]) + 1, "r"); |
|||
ck_assert_msg( |
|||
sekrits_create_from_file(&secrets, data) == SEKRITS_OK, |
|||
"Was expecting valid secret data to load from %s", cases[i] |
|||
); |
|||
sekrits_destroy(secrets); |
|||
fclose(data); |
|||
} |
|||
} |
|||
END_TEST |
|||
|
|||
START_TEST(test_create_from_file_neg) { |
|||
const char *cases[] ={ |
|||
"notok" |
|||
}; |
|||
for (int i = 0; i < sizeof(cases); ++ i) { |
|||
printf("running case"); |
|||
struct sekrits *secrets = NULL; |
|||
FILE *data = fmemopen((char *)cases[i], strlen(cases[i]) + 1, "r"); |
|||
ck_assert_msg( |
|||
sekrits_create_from_file(&secrets, data) == SEKRITS_ERROR, |
|||
"Was expecting invalid secret data to load from %s", cases[i] |
|||
); |
|||
sekrits_destroy(secrets); |
|||
fclose(data); |
|||
} |
|||
} |
|||
END_TEST |
|||
|
|||
Suite * sekrits_suite(void) { |
|||
TCase *tc_create_file; |
|||
tc_create_file = tcase_create("create_from_file"); |
|||
tcase_add_test(tc_create_file, test_create_from_file); |
|||
|
|||
TCase *tc_create_file_neg; |
|||
tc_create_file_neg = tcase_create("create_from_file_neg"); |
|||
tcase_add_test(tc_create_file_neg, test_create_from_file_neg); |
|||
|
|||
Suite *s = suite_create("sekrits"); |
|||
suite_add_tcase(s, tc_create_file); |
|||
suite_add_tcase(s, tc_create_file_neg); |
|||
return s; |
|||
} |
|||
|
|||
int main(void) { |
|||
int number_failed; |
|||
SRunner *srunner = srunner_create(sekrits_suite()); |
|||
|
|||
srunner_run_all(srunner, CK_VERBOSE); |
|||
number_failed = srunner_ntests_failed(srunner); |
|||
srunner_free(srunner); |
|||
|
|||
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue