diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gpgconf.c | 10 | ||||
-rw-r--r-- | tools/gpgtar-create.c | 120 | ||||
-rw-r--r-- | tools/gpgtar-extract.c | 61 | ||||
-rw-r--r-- | tools/gpgtar.c | 63 | ||||
-rw-r--r-- | tools/gpgtar.h | 9 | ||||
-rw-r--r-- | tools/send-mail.c | 7 |
6 files changed, 231 insertions, 39 deletions
diff --git a/tools/gpgconf.c b/tools/gpgconf.c index bb9ac5419..46489df1f 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1515,6 +1515,11 @@ show_configs (estream_t outfp) static const char *names[] = { "common.conf", "gpg-agent.conf", "scdaemon.conf", "dirmngr.conf", "gpg.conf", "gpgsm.conf" }; + static const char *envvars[] = { "PATH", + "http_proxy", "HTTP_PROXY", + "https_proxy", "HTTPS_PROXY", + "LD_LIBRARY_PATH", "LD_PRELOAD", + "LD_AUDIT", "LD_ORIGIN_PATH" }; gpg_error_t err; int idx; char *fname; @@ -1545,6 +1550,11 @@ show_configs (estream_t outfp) list_dirs (outfp, NULL, 1); es_fprintf (outfp, "\n"); + for (idx=0; idx < DIM(envvars); idx++) + if ((s = getenv (envvars[idx]))) + es_fprintf (outfp, "%s=%s\n", envvars[idx], s); + es_fprintf (outfp, "\n"); + fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL); if (!gnupg_access (fname, F_OK)) { diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index ebcfc5229..c239b0fc6 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1,5 +1,5 @@ /* gpgtar-create.c - Create a TAR archive - * Copyright (C) 2016-2017, 2019-2022 g10 Code GmbH + * Copyright (C) 2016-2017, 2019-2023 g10 Code GmbH * Copyright (C) 2010, 2012, 2013 Werner Koch * Copyright (C) 2010 Free Software Foundation, Inc. * @@ -49,10 +49,19 @@ #define lstat(a,b) gnupg_stat ((a), (b)) #endif +/* Number of files to be write. */ +static unsigned long global_total_files; + +/* Count the number of written file and thus headers. Extended + * headers are not counted. */ +static unsigned long global_written_files; + +/* Total data expected to be written. */ +static unsigned long long global_total_data; + +/* Number of data bytes written so far. */ +static unsigned long long global_written_data; -/* Count the number of written headers. Extended headers are not - * counted. */ -static unsigned long global_header_count; /* Object to control the file scanning. */ @@ -62,10 +71,62 @@ struct scanctrl_s { tar_header_t flist; tar_header_t *flist_tail; + unsigned long file_count; int nestlevel; }; +/* See ../g10/progress.c:write_status_progress for some background. */ +static void +write_progress (int countmode, unsigned long long current, + unsigned long long total_arg) +{ + char units[] = "BKMGTPEZY?"; + int unitidx = 0; + uint64_t total = total_arg; + + if (!opt.status_stream) + return; /* Not enabled. */ + + if (countmode) + { + if (total && current > total) + current = total; + } + else if (total) /* Size mode: This may use units. */ + { + if (current > total) + current = total; + + while (total > 1024*1024) + { + total /= 1024; + current /= 1024; + unitidx++; + } + } + else /* Size mode */ + { + while (current > 1024*1024) + { + current /= 1024; + unitidx++; + } + } + + if (unitidx > sizeof units - 1) + unitidx = sizeof units - 1; + + if (countmode) + es_fprintf (opt.status_stream, "[GNUPG:] PROGRESS gpgtar c %zu %zu\n", + (size_t)current, (size_t)total); + else + es_fprintf (opt.status_stream, "[GNUPG:] PROGRESS gpgtar s %zu %zu %c%s\n", + (size_t)current, (size_t)total, + units[unitidx], + unitidx? "iB" : ""); +} + /* On Windows convert name to UTF8 and return it; caller must release * the result. On Unix or if ALREADY_UTF8 is set, this function is a @@ -300,6 +361,12 @@ add_entry (const char *dname, const char *entryname, scanctrl_t scanctrl) gpgtar_print_header (hdr, NULL, log_get_stream ()); *scanctrl->flist_tail = hdr; scanctrl->flist_tail = &hdr->next; + scanctrl->file_count++; + /* Print a progress line during scnanning in increments of 5000 + * and not of 100 as we doing during write: Scanning is of + * course much faster. */ + if (!(scanctrl->file_count % 5000)) + write_progress (1, scanctrl->file_count, 0); } return 0; @@ -709,7 +776,7 @@ build_header (void *record, tar_header_t hdr, strlist_t *r_exthdr) * will do. To ease testing we also put in the PID. The * count is bumped after the header has been written. */ snprintf (raw->name, sizeof raw->name-1, "_@paxheader.%u.%lu", - (unsigned int)getpid(), global_header_count + 1); + (unsigned int)getpid(), global_written_files + 1); } } @@ -881,7 +948,7 @@ write_extended_header (estream_t stream, const void *record, strlist_t exthdr) static gpg_error_t -write_file (estream_t stream, tar_header_t hdr) +write_file (estream_t stream, tar_header_t hdr, unsigned int *skipped_open) { gpg_error_t err; char record[RECORDSIZE]; @@ -895,7 +962,7 @@ write_file (estream_t stream, tar_header_t hdr) { if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) { - log_info ("skipping unsupported file '%s'\n", hdr->name); + log_info ("silently skipping unsupported file '%s'\n", hdr->name); err = 0; } return err; @@ -907,9 +974,12 @@ write_file (estream_t stream, tar_header_t hdr) if (!infp) { err = gpg_error_from_syserror (); - log_error ("can't open '%s': %s - skipped\n", + log_info ("can't open '%s': %s - skipped\n", hdr->name, gpg_strerror (err)); - return err; + ++*skipped_open; + if (!*skipped_open) /* Protect against overflow. */ + --*skipped_open; + return 0; } } else @@ -920,7 +990,9 @@ write_file (estream_t stream, tar_header_t hdr) err = write_record (stream, record); if (err) goto leave; - global_header_count++; + global_written_files++; + if (!(global_written_files % 100)) + write_progress (1, global_written_files, global_total_files); if (hdr->typeflag == TF_REGULAR) { @@ -946,6 +1018,9 @@ write_file (estream_t stream, tar_header_t hdr) err = write_record (stream, record); if (err) goto leave; + global_written_data += nbytes; + if (!((global_written_data/nbytes) % (2048*100))) + write_progress (0, global_written_data, global_total_data); } nread = es_fread (record, 1, 1, infp); if (nread) @@ -995,6 +1070,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, estream_t outstream = NULL; int eof_seen = 0; gnupg_process_t proc = NULL; + unsigned int skipped_open = 0; memset (scanctrl, 0, sizeof *scanctrl); scanctrl->flist_tail = &scanctrl->flist; @@ -1137,6 +1213,17 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, if (files_from_stream && files_from_stream != es_stdin) es_fclose (files_from_stream); + global_total_files = global_total_data = 0; + global_written_files = global_written_data = 0; + for (hdr = scanctrl->flist; hdr; hdr = hdr->next) + { + global_total_files++; + global_total_data += hdr->size; + } + write_progress (1, 0, global_total_files); + write_progress (0, 0, global_total_data); + + if (encrypt || sign) { strlist_t arg; @@ -1227,17 +1314,20 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, es_set_binary (outstream); } - + skipped_open = 0; for (hdr = scanctrl->flist; hdr; hdr = hdr->next) { - err = write_file (outstream, hdr); + err = write_file (outstream, hdr, &skipped_open); if (err) goto leave; } + err = write_eof_mark (outstream); if (err) goto leave; + write_progress (1, global_written_files, global_total_files); + write_progress (0, global_written_data, global_total_data); if (proc) { @@ -1260,6 +1350,12 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, proc = NULL; } + if (skipped_open) + { + log_info ("number of skipped files: %u\n", skipped_open); + log_error ("exiting with failure status due to previous errors\n"); + } + leave: if (!err) { diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 9d5abd33d..c8e4a4571 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -37,7 +37,7 @@ #include "gpgtar.h" static gpg_error_t -check_suspicious_name (const char *name) +check_suspicious_name (const char *name, tarinfo_t info) { size_t n; @@ -47,6 +47,7 @@ check_suspicious_name (const char *name) { log_error ("filename '%s' contains a backslash - " "can't extract on this system\n", name); + info->skipped_badname++; return gpg_error (GPG_ERR_INV_NAME); } #endif /*HAVE_DOSISH_SYSTEM*/ @@ -59,6 +60,7 @@ check_suspicious_name (const char *name) { log_error ("filename '%s' has suspicious parts - not extracting\n", name); + info->skipped_suspicious++; return gpg_error (GPG_ERR_INV_NAME); } @@ -83,7 +85,7 @@ extract_regular (estream_t stream, const char *dirname, if (sl->flags == 1) fname = sl->d; - err = check_suspicious_name (fname); + err = check_suspicious_name (fname, info); if (err) goto leave; @@ -131,8 +133,12 @@ extract_regular (estream_t stream, const char *dirname, /* Fixme: Set permissions etc. */ leave: - if (!err && opt.verbose) - log_info ("extracted '%s'\n", fname); + if (!err) + { + if (opt.verbose) + log_info ("extracted '%s'\n", fname); + info->nextracted++; + } es_fclose (outfp); if (err && fname && outfp) { @@ -146,7 +152,8 @@ extract_regular (estream_t stream, const char *dirname, static gpg_error_t -extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr) +extract_directory (const char *dirname, tarinfo_t info, + tar_header_t hdr, strlist_t exthdr) { gpg_error_t err; const char *name; @@ -158,7 +165,7 @@ extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr) if (sl->flags == 1) name = sl->d; - err = check_suspicious_name (name); + err = check_suspicious_name (name, info); if (err) goto leave; @@ -198,6 +205,8 @@ extract_directory (const char *dirname, tar_header_t hdr, strlist_t exthdr) { *p = 0; rc = gnupg_mkdir (fname, "-rwx------"); + if (gpg_err_code (rc) == GPG_ERR_EEXIST) + rc = 0; *p = '/'; if (rc) break; @@ -228,13 +237,19 @@ extract (estream_t stream, const char *dirname, tarinfo_t info, if (hdr->typeflag == TF_REGULAR || hdr->typeflag == TF_UNKNOWN) err = extract_regular (stream, dirname, info, hdr, exthdr); else if (hdr->typeflag == TF_DIRECTORY) - err = extract_directory (dirname, hdr, exthdr); + err = extract_directory (dirname, info, hdr, exthdr); else { char record[RECORDSIZE]; log_info ("unsupported file type %d for '%s' - skipped\n", (int)hdr->typeflag, hdr->name); + if (hdr->typeflag == TF_SYMLINK) + info->skipped_symlinks++; + else if (hdr->typeflag == TF_HARDLINK) + info->skipped_hardlinks++; + else + info->skipped_other++; for (err = 0, n=0; !err && n < hdr->nrecords; n++) { err = read_record (stream, record); @@ -326,7 +341,7 @@ gpgtar_extract (const char *filename, int decrypt) tarinfo_t tarinfo = &tarinfo_buffer; gnupg_process_t proc; char *logfilename = NULL; - + unsigned long long notextracted; memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer); @@ -479,6 +494,36 @@ gpgtar_extract (const char *filename, int decrypt) } leave: + notextracted = tarinfo->skipped_badname; + notextracted += tarinfo->skipped_suspicious; + notextracted += tarinfo->skipped_symlinks; + notextracted += tarinfo->skipped_hardlinks; + notextracted += tarinfo->skipped_other; + if (opt.status_stream) + es_fprintf (opt.status_stream, "[GNUPG:] GPGTAR_EXTRACT" + " %llu %llu %lu %lu %lu %lu %lu\n", + tarinfo->nextracted, + notextracted, + tarinfo->skipped_badname, + tarinfo->skipped_suspicious, + tarinfo->skipped_symlinks, + tarinfo->skipped_hardlinks, + tarinfo->skipped_other); + if (notextracted && !opt.quiet) + { + log_info ("Number of files not extracted: %llu\n", notextracted); + if (tarinfo->skipped_badname) + log_info (" invalid name: %lu\n", tarinfo->skipped_badname); + if (tarinfo->skipped_suspicious) + log_info (" suspicious name: %lu\n", tarinfo->skipped_suspicious); + if (tarinfo->skipped_symlinks) + log_info (" symlink: %lu\n", tarinfo->skipped_symlinks); + if (tarinfo->skipped_hardlinks) + log_info (" hardlink: %lu\n", tarinfo->skipped_hardlinks); + if (tarinfo->skipped_other) + log_info (" other reason: %lu\n", tarinfo->skipped_other); + } + free_strlist (extheader); xfree (header); xfree (dirname); diff --git a/tools/gpgtar.c b/tools/gpgtar.c index 8461666b9..64e5306b2 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -459,7 +459,7 @@ main (int argc, char **argv) gnupg_reopen_std (GPGTAR_NAME); gpgrt_set_strusage (my_strusage); - log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX); + log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX|GPGRT_LOG_NO_REGISTRY); /* Make sure that our subsystems are ready. */ i18n_init(); @@ -491,6 +491,36 @@ main (int argc, char **argv) log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]); } + /* Set status stream for our own use of --status-fd. The original + * status fd is passed verbatim to gpg. */ + if (opt.status_fd != -1) + { + int fd = translate_sys2libc_fd_int (opt.status_fd, 1); + + if (!gnupg_fd_valid (fd)) + log_fatal ("status-fd is invalid: %s\n", strerror (errno)); + + if (fd == 1) + { + opt.status_stream = es_stdout; + if (!skip_crypto) + log_fatal ("using stdout for the status-fd is not possible\n"); + } + else if (fd == 2) + opt.status_stream = es_stderr; + else + { + opt.status_stream = es_fdopen (fd, "w"); + if (opt.status_stream) + es_setvbuf (opt.status_stream, NULL, _IOLBF, 0); + } + if (!opt.status_stream) + { + log_fatal ("can't open fd %d for status output: %s\n", + fd, strerror (errno)); + } + } + if (! opt.gpg_program) opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG); @@ -499,17 +529,27 @@ main (int argc, char **argv) switch (cmd) { + case aDecrypt: case aList: if (argc > 1) gpgrt_usage (1); - fname = argc ? *argv : NULL; + fname = (argc && strcmp (*argv, "-"))? *argv : NULL; if (opt.filename) log_info ("note: ignoring option --set-filename\n"); if (files_from) log_info ("note: ignoring option --files-from\n"); - err = gpgtar_list (fname, !skip_crypto); - if (err && log_get_errorcount (0) == 0) - log_error ("listing archive failed: %s\n", gpg_strerror (err)); + if (cmd == aDecrypt) + { + err = gpgtar_extract (fname, !skip_crypto); + if (err && !log_get_errorcount (0)) + log_error ("extracting archive failed: %s\n", gpg_strerror (err)); + } + else + { + err = gpgtar_list (fname, !skip_crypto); + if (err && !log_get_errorcount (0)) + log_error ("listing archive failed: %s\n", gpg_strerror (err)); + } break; case aEncrypt: @@ -530,19 +570,6 @@ main (int argc, char **argv) log_error ("creating archive failed: %s\n", gpg_strerror (err)); break; - case aDecrypt: - if (argc != 1) - gpgrt_usage (1); - if (opt.outfile) - log_info ("note: ignoring option --output\n"); - if (files_from) - log_info ("note: ignoring option --files-from\n"); - fname = argc ? *argv : NULL; - err = gpgtar_extract (fname, !skip_crypto); - if (err && log_get_errorcount (0) == 0) - log_error ("extracting archive failed: %s\n", gpg_strerror (err)); - break; - default: log_error (_("invalid command (there is no implicit command)\n")); break; diff --git a/tools/gpgtar.h b/tools/gpgtar.h index 0854064fb..9177fcfcb 100644 --- a/tools/gpgtar.h +++ b/tools/gpgtar.h @@ -45,6 +45,7 @@ struct int answer_yes; int answer_no; int status_fd; + estream_t status_stream; int require_compliance; int with_log; } opt; @@ -53,8 +54,14 @@ struct /* An info structure to avoid global variables. */ struct tarinfo_s { - unsigned long long nblocks; /* Count of processed blocks. */ + unsigned long long nblocks; /* Count of processed blocks. */ unsigned long long headerblock; /* Number of current header block. */ + unsigned long long nextracted; /* Number of extracted files. */ + unsigned long skipped_badname; + unsigned long skipped_suspicious; + unsigned long skipped_symlinks; + unsigned long skipped_hardlinks; + unsigned long skipped_other; }; typedef struct tarinfo_s *tarinfo_t; diff --git a/tools/send-mail.c b/tools/send-mail.c index 6492c43c1..d348f28cb 100644 --- a/tools/send-mail.c +++ b/tools/send-mail.c @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> /* for X_OK */ #include "../common/util.h" #include "../common/exectool.h" @@ -36,6 +37,12 @@ run_sendmail (estream_t data) const char pgmname[] = NAME_OF_SENDMAIL; const char *argv[3]; + if (!*pgmname || gnupg_access (pgmname, X_OK)) + { + log_error ("sendmail tool '%s' is not correctly installed\n", pgmname); + return gpg_error (GPG_ERR_ENOENT); + } + argv[0] = "-oi"; argv[1] = "-t"; argv[2] = NULL; |