/* * gfsecret - Secret sharing tools * Copyright (C) 2021 Damien Goutte-Gattat * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "secret.h" #include "secretcfg.h" struct test { const char *content; int rc; const char *outfile; const char *restore_cmd; const char *destroy_cmd; unsigned min_shares; unsigned total_shares; }; struct test tests[] = { /* Default values. */ { "", 0, NULL, NULL, NULL, 2, 0 }, /* Invalid threshold values. */ { "MINSHARES=1\n", GFSEC_ERR_CONFIG_INVALID_THRESHOLD }, { "MINSHARES=256\n", GFSEC_ERR_CONFIG_INVALID_THRESHOLD }, { "MINSHARES=invalid\n", GFSEC_ERR_CONFIG_INVALID_THRESHOLD }, /* Ignoring unknown keys. */ { "OUTFILE=outfile.txt\n" "UNKNOWN=unknown\n" "MINSHARES=3\n", 0, "outfile.txt", NULL, NULL, 3, 0 }, /* Presence of invalid URIs. */ { "URI=file:///path/to/share.123\n" "URI=invalid\n" "URI=file:///path/to/share.124\n", GFSEC_ERR_CONFIG_UNKNOWN_SCHEME }, { "URI=file:///path/to/share.123\n" "URI=file://\n" "URI=file:///path/to/share.124\n", GFSEC_ERR_CONFIG_INVALID_URI }, /* Use of destroy/restore commands */ { "OUTFILE=outfile.txt\n" "RESTORE=restore command\n" "DESTROY=destroy command\n", 0, "outfile.txt", "restore command", "destroy command", 2, 0 }, { NULL } }; unsigned testnr; unsigned sum; static void fail(const char *msg, ...) { va_list ap; va_start(ap, msg); fprintf(stderr, "Test #%u: ", testnr); vfprintf(stderr, msg, ap); va_end(ap); sum += 1; } static int write_test_config(const char *test, int fd) { int rc; rc = lseek(fd, 0, SEEK_SET); if ( rc != -1 ) rc = ftruncate(fd, 0); if ( rc != -1 ) rc = write(fd, test, strlen(test)); if ( rc != -1 ) rc = fsync(fd); return fd; } int main(int argc, char **argv) { int rc, fd, hard_error; gfsec_secret_t *secret; struct test *test = tests; char filename[] = "testXXXXXX"; testnr = 1; sum = 0; hard_error = 0; if ( (fd = mkstemp(filename)) == -1 ) { fprintf(stderr, "Cannot create temporary file: %s\n", strerror(errno)); return 99; /* Hard error. */ } while ( test->content ) { if ( write_test_config(test->content, fd) == -1 ) { fprintf(stderr, "Cannot write to temporary file: %s\n", strerror(errno)); hard_error = 1; break; } secret = gfsec_secret_new(); rc = gfsec_read_config(&secret, filename, NULL); if ( rc != test->rc ) { fail("expected code %d, got %d\n", test->rc, rc); } if ( rc == 0 ) { if ( test->outfile && strcmp(secret->filename, test->outfile) != 0 ) fail("expected filename '%s', got '%s'\n", test->outfile, secret->filename); if ( test->restore_cmd && strcmp(secret->restore, test->restore_cmd) != 0 ) fail("expected command '%s', got '%s'\n", test->restore_cmd, secret->restore); if ( test->destroy_cmd && strcmp(secret->destroy, test->destroy_cmd) != 0 ) fail("expected command '%s', got '%s'\n", test->destroy_cmd, secret->destroy); if ( secret->threshold != test->min_shares ) fail("expected threshold %u, got %u\n", test->min_shares, secret->threshold); if ( secret->n_shares != test->total_shares ) fail("expected %u shares, got %u\n", test->total_shares, secret->n_shares); } if ( secret ) gfsec_secret_free(secret); test += 1; testnr += 1; } close(fd); unlink(filename); return hard_error ? 99 : sum == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }