Browse Source

Merge branch 'develop'

master gfsecret-0.4.1
Damien Goutte-Gattat 5 years ago
parent
commit
ad8f161b8a
  1. 5
      NEWS
  2. 3
      README.md
  3. 2
      configure.ac
  4. 5
      man/gfsec-split.1.in
  5. 3
      src/Makefile.am
  6. 150
      src/gfsec-split.c
  7. 10
      src/scheme-file.c
  8. 6
      src/scheme-file.h
  9. 24
      src/scheme-gio.c
  10. 6
      src/scheme-gio.h
  11. 12
      src/scheme-libmtp.c
  12. 6
      src/scheme-libmtp.h
  13. 26
      src/scheme-module.c
  14. 6
      src/scheme-module.h
  15. 11
      src/secret.c
  16. 2
      src/secret.h
  17. 89
      src/support.c
  18. 54
      src/support.h

5
NEWS

@ -1,3 +1,8 @@
Changes in gfsecret 0.4.1
* Add the -i, --interactive option to gfsec-split.
Changes in gfsecret 0.4.0
* Add a -k, --keep option to gfsec-use.

3
README.md

@ -82,7 +82,8 @@ will be unable to fetch the shares.
As a convenience, before splitting you may call _gfsec-split_ with the
single `-l` option to list the available external volumes and their
identifiers.
identifiers. Alternatively, the `-i` option may be used to both list
the available volumes and select those to use in an interactive menu.
gfsec-use

2
configure.ac

@ -1,6 +1,6 @@
dnl Configure template for the gfsecret package
AC_INIT([gfsecret], [0.4.0],
AC_INIT([gfsecret], [0.4.1],
[dgouttegattat@incenp.org])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])

5
man/gfsec-split.1.in

@ -11,6 +11,7 @@ gfsec-split \- Split a file into shares and dispatch them
.IR N ]
.RB [ \-c | --config
.IR file ]
.RB [ \-i | --interactive ]
.RB [ \-k | --keep ]
.RB [ \-l | --list-supports ]
.B file
@ -46,6 +47,10 @@ the secret with
) to the specified file. Default is the basename of
the splitted file in $XDG_CONFIG_HOME/gfsecret.
.TP
.BR -i ", " --interactive
Present the user with an interactive menu to specify the
shares to create.
.TP
.BR -k ", " --keep
By default,
.B gfsec-split

3
src/Makefile.am

@ -5,7 +5,8 @@ common_sources = util.c util.h secret.c secret.h \
schemes.h scheme-module.c scheme-module.h \
scheme-libmtp.c scheme-libmtp.h \
scheme-gio.c scheme-gio.h \
scheme-file.c scheme-file.h
scheme-file.c scheme-file.h \
support.c support.h
gfsec_use_SOURCES = gfsec-use.c $(common_sources)

150
src/gfsec-split.c

@ -52,7 +52,8 @@ Split the specified file for later use with gfsec-use.\n");
-n, --threshold N Specify the minimal number of shares\n\
required to re-assemble the secret.\n\
Default is 2.\n\
-s, --share URI Add a share.\n");
-s, --share URI Add a share.\n\
-i, --interactive Prompt the user for share URIs.\n");
puts("\
-c, --config FILE Write configuration to the specified\n\
@ -85,6 +86,124 @@ See the COPYING file or <http://www.gnu.org/licenses/gpl.html>.\n\
exit(EXIT_SUCCESS);
}
static char *
ask(const char *prompt)
{
char *buffer = NULL;
size_t len = 0;
ssize_t n;
printf("%s ", prompt);
if ( (n = getline(&buffer, &len, stdin)) == -1 )
err(EXIT_FAILURE, "Cannot read from standard input");
else if ( n > 0 && buffer[n - 1] == '\n' )
buffer[n - 1] = '\0';
return buffer;
}
static char *
ask_nonempty(const char *prompt)
{
char *answer;
int done = 0;
do {
answer = ask(prompt);
if ( ! (done = *answer != '\0') )
free(answer);
} while ( ! done );
return answer;
}
static int
ask_confirmation(const char *prompt)
{
int rc = 0;
char *answer;
answer = ask(prompt);
if ( (*answer == 'y' || *answer == 'Y') && *(answer + 1) == '\0' )
rc = 1;
free(answer);
return rc;
}
static int
prompt_for_share(gfsec_secret_t *cfg, gfsec_supports_list_t *list, unsigned number)
{
int i, rc;
char *answer, *path;
gfsec_share_t *share;
rc = -1;
printf("Select a support for share #%u:\n\n", number);
for ( i = 0; i < list->count; i++ )
printf(" (%d) %s\n", i+1, list->supports[i].description);
printf(" (x) Done\n\n");
while ( rc == -1 ) {
answer = ask ("Your choice?");
if ( (*answer == 'x' || *answer == 'X') && *(answer + 1) == '\0' )
rc = 1; /* We're done selecting supports. */
else {
int selected;
selected = strtol(answer, NULL, 10);
if ( selected > 0 && selected < list->count ) {
path = ask_nonempty("Specify a pathname on this support:");
share = gfsec_share_new();
gfsec_share_set_info(share, GFSEC_SHARE_NUMBER_AUTOASSIGN,
list->supports[selected - 1].scheme,
list->supports[selected - 1].authority,
path, NULL);
if ( (i = gfsec_secret_add_share(cfg, share)) != 0 )
errx(EXIT_FAILURE, "Cannot add share: %s", gfsec_error_string(i));
rc = 0; /* Done for this share. */
free(path);
}
}
free(answer);
}
return rc;
}
static void
interactive_loop(gfsec_secret_t *cfg)
{
gfsec_supports_list_t *list;
int i;
char buffer[255];
list = gfsec_scheme_module_get_supports();
i = 0;
while ( ! prompt_for_share(cfg, list, ++i) ) ;
gfsec_support_destroy_list(list);
printf("\nThe following shares will be created:\n");
for ( i = 0; i < cfg->n_shares; i++ ) {
gfsec_share_get_uri(cfg->shares[i], buffer, sizeof(buffer));
printf(" %s\n", buffer);
}
putchar('\n');
if ( ! ask_confirmation("Proceed (y/N)?") )
errx(EXIT_FAILURE, "Split cancelled");
}
static unsigned
get_uinteger_or_die(const char *arg)
{
@ -102,7 +221,7 @@ get_uinteger_or_die(const char *arg)
int
main(int argc, char **argv)
{
int c, list_mode;
int c, list_mode, interactive;
unsigned threshold, keep_original;
char *config_path, *secret_file;
gfsec_secret_t *cfg;
@ -112,6 +231,7 @@ main(int argc, char **argv)
{ "version", 0, NULL, 'v' },
{ "treshold", 1, NULL, 'n' },
{ "share", 1, NULL, 's' },
{ "interactive", 0, NULL, 'i' },
{ "config", 1, NULL, 'c' },
{ "keep", 0, NULL, 'k' },
{ "list-supports", 0, NULL, 'l' },
@ -120,14 +240,14 @@ main(int argc, char **argv)
setprogname(argv[0]);
threshold = 2;
keep_original = list_mode = 0;
keep_original = list_mode = interactive = 0;
config_path = NULL;
srandom(time(NULL));
cfg = gfsec_secret_new();
while ( (c = getopt_long(argc, argv, "hvn:s:c:kl",
while ( (c = getopt_long(argc, argv, "hvn:s:ic:kl",
options, NULL)) != -1 ) {
switch ( c ) {
case 'h':
@ -151,6 +271,10 @@ main(int argc, char **argv)
errx(EXIT_FAILURE, "Cannot add share: %s", gfsec_error_string(c));
break;
case 'i':
interactive = 1;
break;
case 'c':
config_path = optarg;
break;
@ -168,7 +292,20 @@ main(int argc, char **argv)
gfsec_scheme_module_init();
if ( list_mode ) {
gfsec_scheme_module_list_authorities(stdout);
gfsec_supports_list_t *list;
char *schemes[] = { "file", "uuid", "label", "mtp" };
int i;
list = gfsec_scheme_module_get_supports();
for ( i = 0; i < list->count; i++ ) {
printf("%s://%s/ %s\n",
schemes[list->supports[i].scheme],
list->supports[i].authority,
list->supports[i].description);
}
gfsec_support_destroy_list(list);
exit(EXIT_SUCCESS);
}
@ -200,6 +337,9 @@ main(int argc, char **argv)
errx(EXIT_FAILURE, "Cannot add share: %s", gfsec_error_string(c));
}
if ( interactive )
interactive_loop(cfg);
if ( (c = gfsec_secret_split(cfg, threshold)) != 0 )
errx(EXIT_FAILURE, "Cannot split secret: %s", gfsec_error_string(c));

10
src/scheme-file.c

@ -26,6 +26,8 @@
#include "scheme-module.h"
#include "util.h"
#include <xmem.h>
int
gfsec_scheme_file_get_file(gfsec_scheme_t scheme,
const char *authority,
@ -69,8 +71,10 @@ gfsec_scheme_file_put_file(gfsec_scheme_t scheme,
return GFSEC_SCHEME_STATUS_ERROR;
}
void
gfsec_scheme_file_lst_auth(FILE *f)
int
gfsec_scheme_file_get_supports(gfsec_supports_list_t *list)
{
fprintf(f, "file:// Local filesystem\n");
gfsec_support_add(list, GFSEC_SCHEME_FILE, xstrdup(""), xstrdup("Local filesystem"));
return 1;
}

6
src/scheme-file.h

@ -19,8 +19,8 @@
#ifndef ICP20160821_SCHEME_FILE_H
#define ICP20160821_SCHEME_FILE_H
#include <stdio.h>
#include "schemes.h"
#include "support.h"
#ifdef __cpluscplus
extern "C" {
@ -40,8 +40,8 @@ gfsec_scheme_file_put_file(gfsec_scheme_t,
unsigned char *,
size_t);
void
gfsec_scheme_file_lst_auth(FILE *);
int
gfsec_scheme_file_get_supports(gfsec_supports_list_t *);
#ifdef __cplusplus
}

24
src/scheme-gio.c

@ -27,6 +27,7 @@
#include <string.h>
#include <gio/gio.h>
#include <xmem.h>
#include "util.h"
typedef struct mount_cb_data {
@ -292,16 +293,17 @@ gfsec_scheme_gio_put_file(gfsec_scheme_t scheme,
return rc;
}
void
gfsec_scheme_gio_lst_auth(FILE *f)
int
gfsec_scheme_gio_get_supports(gfsec_supports_list_t *list)
{
GVolumeMonitor *volmon;
GList *volumes, *l;
int n;
volmon = g_volume_monitor_get();
volumes = g_volume_monitor_get_volumes(volmon);
for ( l = volumes; l != NULL; l = l->next ) {
for ( l = volumes, n = 0; l != NULL; l = l->next ) {
char *label, *uuid;
GVolume *volume;
@ -310,13 +312,19 @@ gfsec_scheme_gio_lst_auth(FILE *f)
uuid = g_volume_get_uuid(volume);
if ( label ) {
fprintf(f, "label://%s GIO volume\n", label);
free(label);
char *desc;
xasprintf(&desc, "External volume with label '%s'", label);
gfsec_support_add(list, GFSEC_SCHEME_LABEL, label, desc);
n += 1;
}
if ( uuid ) {
fprintf(f, "uuid://%s GIO volume\n", uuid);
free(uuid);
char *desc;
xasprintf(&desc, "External volume with UUID %s", uuid);
gfsec_support_add(list, GFSEC_SCHEME_UUID, uuid, desc);
n += 1;
}
g_object_unref(l->data);
@ -324,6 +332,8 @@ gfsec_scheme_gio_lst_auth(FILE *f)
g_list_free(volumes);
g_object_unref(volmon);
return n;
}
#endif /* HAVE_GIO */

6
src/scheme-gio.h

@ -19,8 +19,8 @@
#ifndef ICP20160207_SCHEME_GIO_H
#define ICP20160207_SCHEME_GIO_H
#include <stdio.h>
#include "schemes.h"
#include "support.h"
#ifdef __cpluscplus
extern "C" {
@ -40,8 +40,8 @@ gfsec_scheme_gio_put_file(gfsec_scheme_t,
unsigned char *,
size_t);
void
gfsec_scheme_gio_lst_auth(FILE *);
int
gfsec_scheme_gio_get_supports(gfsec_supports_list_t *);
#ifdef __cplusplus
}

12
src/scheme-libmtp.c

@ -387,15 +387,15 @@ gfsec_scheme_libmtp_put_file(gfsec_scheme_t scheme,
return rc;
}
void
gfsec_scheme_libmtp_lst_auth(FILE *f)
int
gfsec_scheme_libmtp_get_supports(gfsec_supports_list_t *list)
{
LIBMTP_raw_device_t *raw_devices;
LIBMTP_mtpdevice_t *device;
int i, n;
if ( LIBMTP_Detect_Raw_Devices(&raw_devices, &n) != 0 )
return;
return 0;
for ( i = 0, device = NULL; i < n && device == NULL; i++ ) {
char *serial, *name;
@ -404,12 +404,12 @@ gfsec_scheme_libmtp_lst_auth(FILE *f)
serial = LIBMTP_Get_Serialnumber(device);
name = LIBMTP_Get_Friendlyname(device);
fprintf(f, "mtp://%s %s\n", serial, name);
gfsec_support_add(list, GFSEC_SCHEME_MTP, serial, name);
free(serial);
free(name);
LIBMTP_Release_Device(device);
}
return n;
}
#endif /* HAVE_LIBMTP */

6
src/scheme-libmtp.h

@ -19,8 +19,8 @@
#ifndef ICP20160207_SCHEME_LIBMTP_H
#define ICP20160207_SCHEME_LIBMTP_H
#include <stdio.h>
#include "schemes.h"
#include "support.h"
#ifdef __cpluscplus
extern "C" {
@ -40,8 +40,8 @@ gfsec_scheme_libmtp_put_file(gfsec_scheme_t,
unsigned char *,
size_t);
void
gfsec_scheme_libmtp_lst_auth(FILE *);
int
gfsec_scheme_libmtp_get_supports(gfsec_supports_list_t *);
#ifdef __cplusplus
}

26
src/scheme-module.c

@ -41,13 +41,13 @@ typedef int (*fn_put_file)(gfsec_scheme_t,
unsigned char *,
size_t);
typedef void (*fn_lst_auth)(FILE *);
typedef int (*fn_get_supp)(gfsec_supports_list_t *);
typedef struct module {
int present;
fn_get_file get_file;
fn_put_file put_file;
fn_lst_auth lst_auth;
fn_get_supp get_supp;
} module_t;
static module_t *modules;
@ -65,21 +65,21 @@ gfsec_scheme_module_init(void)
mods[n].get_file = gfsec_scheme_file_get_file;
mods[n].put_file = gfsec_scheme_file_put_file;
mods[n].lst_auth = gfsec_scheme_file_lst_auth;
mods[n].get_supp = gfsec_scheme_file_get_supports;
mods[n++].present = 1;
#ifdef HAVE_LIBMTP
LIBMTP_Init();
mods[n].get_file = gfsec_scheme_libmtp_get_file;
mods[n].put_file = gfsec_scheme_libmtp_put_file;
mods[n].lst_auth = gfsec_scheme_libmtp_lst_auth;
mods[n].get_supp = gfsec_scheme_libmtp_get_supports;
mods[n++].present = 1;
#endif
#ifdef HAVE_GIO
mods[n].get_file = gfsec_scheme_gio_get_file;
mods[n].put_file = gfsec_scheme_gio_put_file;
mods[n].lst_auth = gfsec_scheme_gio_lst_auth;
mods[n].get_supp = gfsec_scheme_gio_get_supports;
mods[n++].present = 1;
#endif
@ -167,17 +167,21 @@ gfsec_scheme_module_put_file(gfsec_scheme_t scheme,
}
/**
* List currently available authorities reported by all modules.
* Get a list of currently available supports.
*
* @param f The stream to write into.
* @return A gfsec_supports_list_t object containing all available
* supports.
*/
void
gfsec_scheme_module_list_authorities(FILE *f)
gfsec_supports_list_t *
gfsec_scheme_module_get_supports(void)
{
gfsec_supports_list_t *list = gfsec_support_new_list();
module_t *mod;
for ( mod = modules; mod->present; mod++ ) {
if ( mod->lst_auth )
mod->lst_auth(f);
if ( mod->get_supp )
mod->get_supp(list);
}
return list;
}

6
src/scheme-module.h

@ -20,9 +20,9 @@
#define ICP20160820_SCHEME_MODULE_H
#include <stdlib.h>
#include <stdio.h>
#include "schemes.h"
#include "support.h"
typedef enum gfsec_scheme_status {
GFSEC_SCHEME_STATUS_SUCCESS = 0,
@ -51,8 +51,8 @@ gfsec_scheme_module_put_file(gfsec_scheme_t,
unsigned char *,
size_t);
void
gfsec_scheme_module_list_authorities(FILE *);
gfsec_supports_list_t *
gfsec_scheme_module_get_supports(void);
#ifdef __cpluscplus
}

11
src/secret.c

@ -152,7 +152,7 @@ gfsec_share_new(void)
*/
void
gfsec_share_set_info(gfsec_share_t *share,
unsigned char number,
unsigned short number,
gfsec_scheme_t scheme,
const char *authority,
const char *path,
@ -165,8 +165,13 @@ gfsec_share_set_info(gfsec_share_t *share,
share->scheme = scheme;
if ( authority )
share->authority = xstrdup(authority);
if ( path )
share->path = xstrdup(path);
if ( path ) {
/* Make sure the path is absolute. */
if ( *path != '/' )
xasprintf(&(share->path), "/%s", path);
else
share->path = xstrdup(path);
}
if ( hash )
memcpy(share->hash, hash, 32);

2
src/secret.h

@ -98,7 +98,7 @@ gfsec_share_new(void);
void
gfsec_share_set_info(gfsec_share_t *,
unsigned char,
unsigned short,
gfsec_scheme_t,
const char *,
const char *,

89
src/support.c

@ -0,0 +1,89 @@
/*
* gfsecret - Secret sharing tools
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "support.h"
#include <xmem.h>
/**
* Create a new list of supports.
*/
gfsec_supports_list_t *
gfsec_support_new_list(void)
{
gfsec_supports_list_t *list;
list = xmalloc(sizeof(*list));
list->supports = xmalloc(10 * sizeof(gfsec_support_t));
list->size = 10;
list->count = 0;
return list;
}
/**
* Destroy a list of supports and release all associated memory.
*
* @param list The list to destroy.
*/
void
gfsec_support_destroy_list(gfsec_supports_list_t *list)
{
unsigned n;
for ( n = 0; n < list->count; n++ ) {
free(list->supports[n].authority);
free(list->supports[n].description);
}
free(list->supports);
free(list);
}
/**
* Add a new support to a list of supports.
*
* @param list The list to modify.
* @param scheme The scheme associated to the support.
* @param authority The authority refering to the support.
* @param description A free-form description of the support.
*
* @note The string parameters will be owned by the list and freed
* when the gfsec_support_destroy_list function is called.
*/
void
gfsec_support_add(gfsec_supports_list_t *list,
gfsec_scheme_t scheme,
char *authority,
char *description)
{
if ( list->count >= list->size ) {
list->size += 10;
list->supports = xrealloc(list->supports, list->size * sizeof(gfsec_support_t));
}
list->supports[list->count].scheme = scheme;
list->supports[list->count].authority = authority;
list->supports[list->count].description = description;
list->count += 1;
}

54
src/support.h

@ -0,0 +1,54 @@
/*
* gfsecret - Secret sharing tools
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20161015_SUPPORT_H
#define ICP20161015_SUPPORT_H
#include "schemes.h"
typedef struct gfsec_support {
gfsec_scheme_t scheme;
char *authority;
char *description;
} gfsec_support_t;
typedef struct gfsec_supports_list {
gfsec_support_t *supports;
size_t size;
size_t count;
} gfsec_supports_list_t;
#ifdef __cpluscplus
extern "C" {
#endif
gfsec_supports_list_t *
gfsec_support_new_list(void);
void
gfsec_support_destroy_list(gfsec_supports_list_t *);
void
gfsec_support_add(gfsec_supports_list_t *, gfsec_scheme_t, char *, char *);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20161015_SUPPORT_H */
Loading…
Cancel
Save