-O ro: readonly files, never write anything (except to standard streams)
authorAndrey Rys <rys@lynxlynx.ru>
Sun, 28 Nov 2021 17:00:45 +0000 (18:00 +0100)
committerAndrey Rys <rys@lynxlynx.ru>
Sun, 28 Nov 2021 17:01:22 +0000 (18:01 +0100)
VERSION
tfc_base64.c
tfc_error.c
tfc_misc.c
tfc_random.c
tfc_skein.c
tfc_vars.c
tfcrypt.c
tfcrypt.h

diff --git a/VERSION b/VERSION
index f6b91e0e1f8dddaac700b51aa7a66f29fc135a02..e1617e842ad9a038ec2d8332c6084300a43cb09d 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-56
+57
index 68f0677998db07d6046e1edf8e8af87ae17711fb..b2edcbc7e705cb4ed7a3f8d854cef937c01edc19 100644 (file)
@@ -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) {
index 01cca1ac5c153247ae02b86cacbd31abec3cd7af..bb477c4883020ddbc3874d330dd418e48640b4d1 100644 (file)
@@ -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.");
index 44e1117be6342ec710d8e6848824cd55b9d6f895..bfb7265ff2dbf00442f26702456e7caeaf2ea864 100644 (file)
@@ -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);
index 9ef321d43304e51fbe35ce29c301d13339a64877..0a529d401b53410f08ef97d436a6fc4b578ab1f6 100644 (file)
@@ -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)
index 0917819e241196b7f9459e2dbbb4dea8198306e3..7886c2bc4c4002ee57a41c3cf85cb4f2560327c0 100644 (file)
@@ -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;
index 6ef6e59286fda23055e2b27ce75a1de0fd8b0c7d..8c6a38c08e493963e9c59c9e5a4f16e8fcd65460 100644 (file)
@@ -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;
index e8514391b8036b8168c5f85d7ef32e8383c59542..e6d422dbe25277dbf231633021e4f318fac14ee4 100644 (file)
--- 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);
index 58d77d56f7ccd9aba43c72535ff45a4024ceffe6..8a57c11491f23c76025059bc1a725d8e60b5f14b 100644 (file)
--- 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);