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