From: Andrey Rys Date: Sun, 28 Nov 2021 17:00:45 +0000 (+0100) Subject: -O ro: readonly files, never write anything (except to standard streams) X-Git-Url: https://jxself.org/git/?a=commitdiff_plain;h=ba5ce99d77078a8629779641e8506b74e50fe6af;p=tfcrypt.git -O ro: readonly files, never write anything (except to standard streams) --- diff --git a/VERSION b/VERSION index f6b91e0..e1617e8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -56 +57 diff --git a/tfc_base64.c b/tfc_base64.c index 68f0677..b2edcbc 100644 --- a/tfc_base64.c +++ b/tfc_base64.c @@ -43,7 +43,7 @@ void do_edbase64(char **fargv) if (fargv[0]) { if (!strcmp(fargv[0], "-")) sfd = 0; else { - sfd = open(fargv[0], O_RDONLY | O_LARGEFILE); + sfd = xopen(fargv[0], O_RDONLY | O_LARGEFILE); if (do_preserve_time) if (fstat(sfd, &s_stat) == -1) xerror(YES, NO, YES, "stat(%s)", fargv[0]); } @@ -52,8 +52,7 @@ void do_edbase64(char **fargv) if (fargv[0] && fargv[1]) { if (!strcmp(fargv[1], "-")) dfd = 1; - else dfd = open(fargv[1], O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); - if (dfd == -1) xerror(NO, NO, YES, "%s", fargv[1]); + else dfd = xopen(fargv[1], O_WRONLY | O_CREAT | O_LARGEFILE | write_flags); } if (do_edcrypt == TFC_DO_ENCRYPT) { diff --git a/tfc_error.c b/tfc_error.c index 01cca1a..bb477c4 100644 --- a/tfc_error.c +++ b/tfc_error.c @@ -148,6 +148,7 @@ void usage(void) tfc_say(" -a: shortcut of -O xtime."); tfc_say(" -l length: read only these first bytes of source."); tfc_say(" -O opts: set options (comma separated list):"); + tfc_say(" ro: open all files only for reading, even those intended for writing,"); tfc_say(" sync: request a synchronous I/O for a output,"); tfc_say(" fsync: on each write() call a corresponding fsync(fd),"); tfc_say(" trunc: open(O_WRONLY) will truncate output file to zero size."); @@ -315,6 +316,7 @@ void usage(void) tfc_say(" Multiple -E specifiers may be given in separate options."); tfc_say(" -o logfile: redirect all messages to logfile instead of stderr."); tfc_say(" -O opts: set options (comma separated list):"); + tfc_say(" ro: open all files only for reading, even those intended for writing,"); tfc_say(" sync: request a synchronous I/O for a output,"); tfc_say(" fsync: on each write() call a corresponding fsync(fd),"); tfc_say(" trunc: open(O_WRONLY) will truncate output file to zero size."); diff --git a/tfc_misc.c b/tfc_misc.c index 44e1117..bfb7265 100644 --- a/tfc_misc.c +++ b/tfc_misc.c @@ -63,6 +63,26 @@ tfc_yesno str_empty(const char *str) return NO; } +int xxopen(tfc_yesno noerr, const char *pathname, int flags) +{ + int r; + + if ((flags & O_WRONLY || flags & O_RDWR)) { + if (read_only == YES) flags = O_RDONLY; + else flags |= write_flags; + } + + flags |= O_LARGEFILE; + r = open(pathname, flags, 0666); + if (noerr == NO && r == -1) xerror(NO, NO, YES, "%s", pathname); + return r; +} + +int xopen(const char *pathname, int flags) +{ + return xxopen(NO, pathname, flags); +} + void xclose(int fd) { if (fd < 3) return; @@ -164,7 +184,7 @@ tfc_fsize tfc_fnamesize(char *fname, tfc_yesno noexit) memset(s, 0, 2); } - fnmfd = open(fname, O_RDONLY); + fnmfd = xxopen(YES, fname, O_RDONLY); if (s) memcpy(s, T, 2); if (fnmfd == -1) { xerror(noexit, NO, YES, "%s", fname); diff --git a/tfc_random.c b/tfc_random.c index 9ef321d..0a529d4 100644 --- a/tfc_random.c +++ b/tfc_random.c @@ -143,8 +143,7 @@ void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes) fd = 1; foutname = TFC_STDOUT_NAME; } - else fd = open(foutname, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); - if (fd == -1) xerror(NO, NO, YES, "%s", foutname); + else fd = xopen(foutname, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags); if (offset) { if (lseek(fd, offset, SEEK_SET) == -1) diff --git a/tfc_skein.c b/tfc_skein.c index 0917819..7886c2b 100644 --- a/tfc_skein.c +++ b/tfc_skein.c @@ -225,7 +225,7 @@ _dothat: s = strchr(shash, ' '); if (s && s[1] == ' ') *s = 0; - fd = open(fname, O_RDONLY | O_LARGEFILE); + fd = xxopen(YES, fname, O_RDONLY | O_LARGEFILE); if (fd == -1) { xerror(YES, NO, YES, "%s", fname); exitcode = 1; @@ -277,7 +277,7 @@ _dothat: for (x = 0; fargv[x] && xx; x++) { if (!strcmp(fargv[x], "-")) fd = 0; - else fd = open(fargv[x], O_RDONLY | O_LARGEFILE); + else fd = xxopen(YES, fargv[x], O_RDONLY | O_LARGEFILE); if (fd == -1) { xerror(YES, NO, YES, "%s", fargv[x]); exitcode = 1; diff --git a/tfc_vars.c b/tfc_vars.c index 6ef6e59..8c6a38c 100644 --- a/tfc_vars.c +++ b/tfc_vars.c @@ -64,7 +64,7 @@ int do_edcrypt = TFC_DO_ENCRYPT, do_stop, quiet, error_action; int counter_opt, mackey_opt, do_mac, do_outfmt = TFC_OUTFMT_B64, rawkey; int idx, write_flags; tfc_yesno catch_all_errors, ignore_seek_errors, password, overwrite_source, do_fsync, do_pad, do_ftrunc = TFC_NO_FTRUNC; -tfc_yesno do_preserve_time, do_stats_in_gibs, do_statline_dynamic = YES, do_less_stats, show_pid; +tfc_yesno do_preserve_time, do_stats_in_gibs, do_statline_dynamic = YES, do_less_stats, show_pid, read_only; tfc_yesno no_repeat, do_full_hexdump = YES, verbose, statline_was_shown, show_secrets, show_when_done; char *srcfname = TFC_STDIN_NAME, *dstfname = TFC_STDOUT_NAME, *do_mac_file, *counter_file, *sksum_hashlist_file; char *saltf, *genkeyf, *mackeyf, *tweakf; diff --git a/tfcrypt.c b/tfcrypt.c index e851439..e6d422d 100644 --- a/tfcrypt.c +++ b/tfcrypt.c @@ -34,11 +34,14 @@ static tfc_fsize rwd, do_read_loops, loopcnt; static void open_log(const char *logfile) { int fd; + tfc_yesno ro; if (!strcmp(logfile, "-")) return; - fd = open(logfile, O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC, 0666); - if (fd == -1) xerror(NO, NO, YES, "%s", logfile); + ro = read_only; + read_only = NO; + fd = xopen(logfile, O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC); + read_only = ro; xclose(2); if (dup2(fd, 2) == -1) xexit(2); xclose(fd); @@ -317,6 +320,10 @@ _baddfname: do_fsync = YES; else if (!strcmp(s, "pad")) do_pad = YES; + else if (!strcmp(s, "ro")) + read_only = YES; + else if (!strcmp(s, "rw")) + read_only = NO; else if (!strcmp(s, "xtime")) do_preserve_time = YES; else if (!strcmp(s, "gibsize")) @@ -650,8 +657,7 @@ _baddfname: if (!strcasecmp(saltf, "disable")) goto _nosalt; if (!strcmp(saltf, "-")) saltfd = 0; - else saltfd = open(saltf, O_RDONLY | O_LARGEFILE); - if (saltfd == -1) xerror(NO, NO, YES, "%s", saltf); + else saltfd = xopen(saltf, O_RDONLY | O_LARGEFILE); lio = xread(saltfd, tfc_salt, TFC_MAX_SALT - TF_FROM_BITS(TFC_KEY_BITS)); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", saltf); tfc_saltsz = lio; @@ -664,8 +670,7 @@ _nosalt: tfc_yesno do_stop; if (!strcmp(mackeyf, "-")) mkfd = 0; - else mkfd = open(mackeyf, O_RDONLY | O_LARGEFILE); - if (mkfd == -1) xerror(NO, NO, YES, "%s", mackeyf); + else mkfd = xopen(mackeyf, O_RDONLY | O_LARGEFILE); skein_init(&sk, TFC_KEY_BITS); @@ -740,8 +745,7 @@ _mkragain: lio = xread(mkfd, pblk, lrem); if (argv[idx]) { if (password || rawkey > TFC_RAWKEY_KEYFILE) goto _nokeyfd; if (!strcmp(argv[idx], "-")) kfd = 0; - else kfd = open(argv[idx], O_RDONLY | O_LARGEFILE); - if (kfd == -1) xerror(NO, NO, YES, "%s", argv[idx]); + else kfd = xopen(argv[idx], O_RDONLY | O_LARGEFILE); lio = strnlen(argv[idx], PATH_MAX); memset(argv[idx], '*', lio); @@ -769,11 +773,10 @@ _nokeyfd: if (argv[idx]) { if (!strcmp(argv[idx], "-") && kfd) sfd = 0; else { - sfd = open(argv[idx], O_RDONLY | O_LARGEFILE); + sfd = xopen(argv[idx], O_RDONLY | O_LARGEFILE); if (do_preserve_time) if (fstat(sfd, &s_stat) == -1) xerror(YES, NO, YES, "stat(%s)", argv[idx]); } - if (sfd == -1) xerror(NO, NO, YES, "%s", argv[idx]); if ((do_mac >= TFC_MAC_VRFY || do_mac <= TFC_MAC_DROP) && !do_mac_file) { maxlen = tfc_fdsize(sfd); @@ -798,8 +801,7 @@ _nokeyfd: int ctrfd; if (!strcmp(counter_file, "-")) ctrfd = 0; - else ctrfd = open(counter_file, O_RDONLY | O_LARGEFILE); - if (ctrfd == -1) xerror(NO, NO, YES, "%s", counter_file); + else ctrfd = xopen(counter_file, O_RDONLY | O_LARGEFILE); lio = xread(ctrfd, ctr, ctrsz); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", counter_file); if (lio < ctrsz) xerror(NO, YES, YES, "counter file is too small (%zu)!", lio); @@ -999,8 +1001,7 @@ _pwdagain: memset(&getps, 0, sizeof(struct getpasswd_state)); pblk = key; if (!strcmp(genkeyf, "-")) krfd = 1; - else krfd = open(genkeyf, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); - if (krfd == -1) xerror(NO, NO, YES, "%s", genkeyf); + else krfd = xopen(genkeyf, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags); _xts2genkey: if (xwrite(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == NOSIZE) xerror(NO, NO, YES, "%s", genkeyf); if (do_fsync && fsync(krfd) == -1) xerror(NO, NO, YES, "%s", genkeyf); if (verbose && xtskeyset == NO) { @@ -1071,11 +1072,8 @@ _ctrskip2: _plain: if (argv[idx]) { if (!strcmp(argv[idx], "-")) dfd = 1; - else dfd = open(argv[idx], O_RDWR | O_LARGEFILE | write_flags, 0666); - if (dfd == -1) { - dfd = open(argv[idx], O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); - if (dfd == -1) xerror(NO, NO, YES, "%s", argv[idx]); - } + else dfd = xxopen(YES, argv[idx], O_RDWR | O_LARGEFILE | write_flags); + if (dfd == -1) dfd = xopen(argv[idx], O_WRONLY | O_CREAT | O_LARGEFILE | write_flags); dstfname = argv[idx]; idx++; } @@ -1292,8 +1290,7 @@ _macragain: lio = xread(sfd, pblk, lrem); int mfd; if (!strcmp(do_mac_file, "-")) mfd = 0; - else mfd = open(do_mac_file, O_RDONLY | O_LARGEFILE); - if (mfd == -1) xerror(YES, NO, NO, "%s", do_mac_file); + else mfd = xopen(do_mac_file, O_RDONLY | O_LARGEFILE); lio = ldone = xread(mfd, tmpdata, sizeof(tmpdata)); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", do_mac_file); if (!memcmp(tmpdata, TFC_ASCII_TFC_MAC_FOURCC, TFC_ASCII_TFC_MAC_FOURCC_LEN)) { @@ -1384,8 +1381,7 @@ _macwagain: lio = xwrite(dfd, pblk, lrem); int mfd; if (!strcmp(do_mac_file, "-")) mfd = 1; - else mfd = open(do_mac_file, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); - if (mfd == -1) xerror(YES, NO, NO, "%s", do_mac_file); + else mfd = xopen(do_mac_file, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags); if (do_outfmt == TFC_OUTFMT_B64) { memcpy(macvrfy, tmpdata, TF_FROM_BITS(macbits)); memset(tmpdata, 0, TFC_TMPSIZE); diff --git a/tfcrypt.h b/tfcrypt.h index 58d77d5..8a57c11 100644 --- a/tfcrypt.h +++ b/tfcrypt.h @@ -158,7 +158,7 @@ extern int do_edcrypt, do_stop, quiet, error_action; extern int counter_opt, mackey_opt, do_mac, do_outfmt, rawkey; extern int idx, write_flags; extern tfc_yesno catch_all_errors, ignore_seek_errors, password, overwrite_source, do_fsync, do_pad, do_ftrunc; -extern tfc_yesno do_preserve_time, do_stats_in_gibs, do_statline_dynamic, do_less_stats, show_pid; +extern tfc_yesno do_preserve_time, do_stats_in_gibs, do_statline_dynamic, do_less_stats, show_pid, read_only; extern tfc_yesno no_repeat, do_full_hexdump, verbose, statline_was_shown, show_secrets, show_when_done; extern char *srcfname, *dstfname, *do_mac_file, *counter_file, *sksum_hashlist_file; extern char *saltf, *genkeyf, *mackeyf, *tweakf; @@ -189,6 +189,8 @@ void tfc_describescale(tfc_fsize num, double *w, int *scale); size_t blk_len_adj(tfc_fsize filelen, tfc_fsize read_already, size_t blklen); tfc_yesno xor_shrink(void *dst, size_t szdst, const void *src, size_t szsrc); tfc_yesno str_empty(const char *str); +int xxopen(tfc_yesno noerr, const char *pathname, int flags); +int xopen(const char *pathname, int flags); void xclose(int fd); const char *tfc_modename(int mode); void tfc_getcurtime(tfc_useconds *tx);