From 151ca81f1a5a03ae83d9c14ab7748a2d3c09919e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 13 Oct 2004 18:10:06 +0000 Subject: [PATCH] Added SELInux hacks and did some cleanups. --- g10/ChangeLog | 28 ++++++++++++ g10/card-util.c | 11 ++++- g10/dearmor.c | 26 ++++++++--- g10/decrypt.c | 12 ++++++ g10/encode.c | 32 ++++++++++---- g10/exec.c | 13 ++++++ g10/g10.c | 55 +++++++++++++++++++----- g10/import.c | 6 +++ g10/keydb.c | 2 +- g10/keygen.c | 6 +++ g10/keyring.c | 23 +++++++++- g10/main.h | 3 ++ g10/misc.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++ g10/openfile.c | 12 ++++++ g10/photoid.c | 8 +++- g10/plaintext.c | 12 ++++++ g10/sign.c | 41 +++++++++++++++--- g10/tdbdump.c | 26 +++++++---- g10/tdbio.c | 1 + g10/verify.c | 12 ++++++ include/iobuf.h | 1 + include/util.h | 16 ------- 22 files changed, 396 insertions(+), 62 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 558299dab..f4a769d29 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -14,13 +14,41 @@ 2004-10-13 Werner Koch + * tdbdump.c (import_ownertrust): Removed all log_error_f and + reworded the messages. + + * dermor.c: Include i18n.h. Made 2 strings translatable. + + * misc.c (register_secured_file, is_secured_file) + (unregister_secured_file): New. + * keyring.c (do_copy, rename_tmp_file): Implement the SELinux hacks. + (keyring_register_filename): Ditto. + * tdbio.c (open_db): Ditto. + * openfile.c (copy_options_file, open_sigfile): Ditto. + * verify.c (verify_signatures, verify_one_file): Ditto. + * photoid.c (generate_photo_id): Ditto. + * keygen.c (read_parameter_file): Ditto. + * import.c (import_keys_internal): Ditto. + * decrypt.c (decrypt_message, decrypt_messages): Ditto. + * dearmor.c (dearmor_file, enarmor_file): Ditto. + * g10.c (main, print_mds): Ditto. + * exec.c (exec_write, exec_read): Ditto. + * card-util.c (change_login): Ditto. + * encode.c (encode_simple, encode_crypt): Ditto. + * openfile.c (overwrite_filep, make_outfile_name, open_outfile) (open_sigfile): Use iobuf_is_pipe_filename to check for pipes so that special filesnames are taken into account. This is bug 327. + * tdbdump.c (import_ownertrust): Ditto. + * sign.c (write_plaintext_packet): Ditto. + (sign_file, clearsign_file, sign_symencrypt_file): + * progress.c (handle_progress): Ditto. * plaintext.c (handle_plaintext): Ditto. + (ask_for_detached_datafile, hash_datafiles): + * encode.c (encode_simple, encode_crypt): Ditto. 2004-10-12 Werner Koch diff --git a/g10/card-util.c b/g10/card-util.c index 8f638c930..1d2e47ea2 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -577,17 +577,24 @@ change_login (const char *args) for (args++; spacep (args); args++) ; fp = fopen (args, "rb"); + if (fp && is_secured_file (fileno (fp))) + { + fclose (fp); + fp = NULL; + errno = EPERM; + } if (!fp) { - tty_printf ("can't open `%s': %s\n", args, strerror (errno)); + tty_printf (_("can't open `%s': %s\n"), args, strerror (errno)); return -1; } + data = xmalloc (254); n = fread (data, 1, 254, fp); fclose (fp); if (n < 0) { - tty_printf ("error reading `%s': %s\n", args, strerror (errno)); + tty_printf (_("error reading `%s': %s\n"), args, strerror (errno)); xfree (data); return -1; } diff --git a/g10/dearmor.c b/g10/dearmor.c index 4ec8fa012..355820d9f 100644 --- a/g10/dearmor.c +++ b/g10/dearmor.c @@ -33,7 +33,7 @@ #include "packet.h" #include "options.h" #include "main.h" - +#include "i18n.h" /**************** * Take an armor file and write it out without armor @@ -49,8 +49,15 @@ dearmor_file( const char *fname ) memset( &afx, 0, sizeof afx); /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - log_error("can't open %s: %s\n", fname? fname: "[stdin]", + inp = iobuf_open(fname); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if (!inp) { + log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]", strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; @@ -91,9 +98,16 @@ enarmor_file( const char *fname ) memset( &afx, 0, sizeof afx); /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); + inp = iobuf_open(fname); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if (!inp) { + log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]", + strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; } diff --git a/g10/decrypt.c b/g10/decrypt.c index 028815eec..90130872c 100644 --- a/g10/decrypt.c +++ b/g10/decrypt.c @@ -58,6 +58,12 @@ decrypt_message( const char *filename ) /* open the message file */ fp = iobuf_open(filename); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } if( !fp ) { log_error(_("can't open `%s'\n"), print_fname_stdin(filename)); return G10ERR_OPEN_FILE; @@ -140,6 +146,12 @@ decrypt_messages(int nfiles, char *files[]) if (!output) goto next_file; fp = iobuf_open(filename); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } if (!fp) { log_error(_("can't open `%s'\n"), print_fname_stdin(filename)); diff --git a/g10/encode.c b/g10/encode.c index 1a6ca6da7..764b804b3 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -170,9 +170,16 @@ encode_simple( const char *filename, int mode, int use_seskey ) init_packet(&pkt); /* prepare iobufs */ - if( !(inp = iobuf_open(filename)) ) { - log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]", - strerror(errno) ); + inp = iobuf_open(filename); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if( !inp ) { + log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]", + strerror(errno) ); return G10ERR_OPEN_FILE; } @@ -298,7 +305,7 @@ encode_simple( const char *filename, int mode, int use_seskey ) off_t tmpsize; if ( !(tmpsize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: empty file\n"), filename ); + log_info(_("WARNING: `%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the the size of a file is larger than 2^32 minus some bytes for @@ -470,8 +477,15 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey ) } /* prepare iobufs */ - if( !(inp = iobuf_open(filename)) ) { - log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]", + inp = iobuf_open(filename); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if( !inp ) { + log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]", strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; @@ -587,7 +601,7 @@ encode_crypt( const char *filename, STRLIST remusr, int use_symkey ) off_t tmpsize; if ( !(tmpsize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: empty file\n"), filename ); + log_info(_("WARNING: `%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the the size of a file is larger than 2^32 minus some bytes for @@ -861,7 +875,7 @@ encode_crypt_files(int nfiles, char **files, STRLIST remusr) line[strlen(line)-1] = '\0'; print_file_status(STATUS_FILE_START, line, 2); if ( (rc = encode_crypt(line, remusr, 0)) ) - log_error("%s: encryption failed: %s\n", + log_error("encryption of `%s' failed: %s\n", print_fname_stdin(line), g10_errstr(rc) ); write_status( STATUS_FILE_DONE ); } @@ -872,7 +886,7 @@ encode_crypt_files(int nfiles, char **files, STRLIST remusr) { print_file_status(STATUS_FILE_START, *files, 2); if ( (rc = encode_crypt(*files, remusr, 0)) ) - log_error("%s: encryption failed: %s\n", + log_error("encryption of `%s' failed: %s\n", print_fname_stdin(*files), g10_errstr(rc) ); write_status( STATUS_FILE_DONE ); files++; diff --git a/g10/exec.c b/g10/exec.c index 5c51b3f9f..e3a6933d9 100644 --- a/g10/exec.c +++ b/g10/exec.c @@ -478,6 +478,12 @@ int exec_write(struct exec_info **info,const char *program, /* It's not fork/exec/pipe, so create a temp file */ (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w"); + if((*info)->tochild && is_secured_file (fileno ((*info)->tochild))) + { + fclose ((*info)->tochild); + (*info)->tochild = NULL; + errno = EPERM; + } if((*info)->tochild==NULL) { log_error(_("can't create file `%s': %s\n"), @@ -545,6 +551,13 @@ int exec_read(struct exec_info *info) if(!info->writeonly) { info->fromchild=iobuf_open(info->tempfile_out); + if (info->fromchild + && is_secured_file (iobuf_get_fd (info->fromchild))) + { + iobuf_close (info->fromchild); + info->fromchild = NULL; + errno = EPERM; + } if(info->fromchild==NULL) { log_error(_("unable to read external program response: %s\n"), diff --git a/g10/g10.c b/g10/g10.c index 9a885c711..fe4c89a70 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -690,6 +690,14 @@ static ARGPARSE_OPTS opts[] = { {0,NULL,0,NULL} }; + +#ifdef ENABLE_SELINUX_HACKS +#define ALWAYS_ADD_KEYRINGS 1 +#else +#define ALWAYS_ADD_KEYRINGS 0 +#endif + + int g10_errors_seen = 0; static int utf8_strings = 0; @@ -1778,6 +1786,12 @@ main( int argc, char **argv ) configlineno = 0; configfp = fopen( configname, "r" ); + if (configfp && is_secured_file (fileno (configfp))) + { + fclose (configfp); + configfp = NULL; + errno = EPERM; + } if( !configfp ) { if( default_config ) { if( parse_debug ) @@ -2827,6 +2841,8 @@ main( int argc, char **argv ) if( use_random_seed ) { char *p = make_filename(opt.homedir, "random_seed", NULL ); set_random_seed_file(p); + if (!access (p, F_OK)) + register_secured_file (p); m_free(p); } @@ -2859,12 +2875,18 @@ main( int argc, char **argv ) /* Add the keyrings, but not for some special commands and not in case of "-kvv userid keyring". Also avoid adding the secret keyring for a couple of commands to avoid unneeded access in - case the secrings are stored on a floppy */ - if( cmd != aDeArmor && cmd != aEnArmor - && !(cmd == aKMode && argc == 2 ) ) + case the secrings are stored on a floppy. + + We always need to add the keyrings if we are running under + SELinux, thi is so that the rings are added to the list of + secured files. */ + if( ALWAYS_ADD_KEYRINGS + || (cmd != aDeArmor && cmd != aEnArmor + && !(cmd == aKMode && argc == 2 )) ) { - if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys - && cmd != aVerify && cmd != aSym) + if (ALWAYS_ADD_KEYRINGS + || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys + && cmd != aVerify && cmd != aSym)) { if (!sec_nrings || default_keyring) /* add default secret rings */ keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1); @@ -2923,15 +2945,15 @@ main( int argc, char **argv ) if( argc > 1 ) wrong_args(_("--store [filename]")); if( (rc = encode_store(fname)) ) - log_error_f( print_fname_stdin(fname), - "store failed: %s\n", g10_errstr(rc) ); + log_error ("storing `%s' failed: %s\n", + print_fname_stdin(fname),g10_errstr(rc) ); break; case aSym: /* encrypt the given file only with the symmetric cipher */ if( argc > 1 ) wrong_args(_("--symmetric [filename]")); if( (rc = encode_symmetric(fname)) ) - log_error_f(print_fname_stdin(fname), - "symmetric encryption failed: %s\n",g10_errstr(rc) ); + log_error (_("symmetric encryption of `%s' failed: %s\n"), + print_fname_stdin(fname),g10_errstr(rc) ); break; case aEncr: /* encrypt the given file */ @@ -3505,7 +3527,14 @@ main( int argc, char **argv ) && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) ) log_info(_("Go ahead and type your message ...\n")); - if( !(a = iobuf_open(fname)) ) + a = iobuf_open(fname); + if (a && is_secured_file (iobuf_get_fd (a))) + { + iobuf_close (a); + a = NULL; + errno = EPERM; + } + if( !a ) log_error(_("can't open `%s'\n"), print_fname_stdin(fname)); else { @@ -3678,6 +3707,12 @@ print_mds( const char *fname, int algo ) } else { fp = fopen( fname, "rb" ); + if (fp && is_secured_file (fileno (fp))) + { + fclose (fp); + fp = NULL; + errno = EPERM; + } } if( !fp ) { log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) ); diff --git a/g10/import.c b/g10/import.c index 28ecb819a..9586ba314 100644 --- a/g10/import.c +++ b/g10/import.c @@ -165,6 +165,12 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames, IOBUF inp2 = iobuf_open(fname); if( !fname ) fname = "[stdin]"; + if (inp2 && is_secured_file (iobuf_get_fd (inp2))) + { + iobuf_close (inp2); + inp2 = NULL; + errno = EPERM; + } if( !inp2 ) log_error(_("can't open `%s': %s\n"), fname, strerror(errno) ); else { diff --git a/g10/keydb.c b/g10/keydb.c index 953bc5853..34f0ebcf4 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -71,7 +71,7 @@ static void unlock_all (KEYDB_HANDLE hd); /* Handle the creation of a keyring if it does not yet exist. Take - into acount that other processes might have the keyring alread + into acount that other processes might have the keyring already locked. This lock check does not work if the directory itself is not yet available. */ static int diff --git a/g10/keygen.c b/g10/keygen.c index fe3893499..6380ca171 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2215,6 +2215,12 @@ read_parameter_file( const char *fname ) fname = "-"; fp = iobuf_open (fname); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } if (!fp) { log_error (_("can't open `%s': %s\n"), fname, strerror(errno) ); return; diff --git a/g10/keyring.c b/g10/keyring.c index 093bb0074..ae1957398 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -213,6 +213,9 @@ keyring_register_filename (const char *fname, int secret, void **ptr) } } + if (secret) + register_secured_file (fname); + kr = m_alloc (sizeof *kr + strlen (fname)); strcpy (kr->fname, fname); kr->secret = !!secret; @@ -1226,10 +1229,13 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) remove( fname ); #endif + if (secret) + unregister_secured_file (fname); if (rename (tmpfname, fname) ) { - log_error ("renaming `%s' to `%s' failed: %s\n", + log_error (_("renaming `%s' to `%s' failed: %s\n"), tmpfname, fname, strerror(errno) ); + register_secured_file (fname); rc = G10ERR_RENAME_FILE; if (secret) { @@ -1505,12 +1511,15 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, goto leave; } - /* create the new file */ + /* Create the new file. */ rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); if (rc) { iobuf_close(fp); goto leave; } + if (secret) + register_secured_file (tmpfname); + if( mode == 1 ) { /* insert */ /* copy everything to the new file */ rc = copy_all_packets (fp, newfp); @@ -1518,6 +1527,8 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, log_error("%s: copy to `%s' failed: %s\n", fname, tmpfname, g10_errstr(rc) ); iobuf_close(fp); + if (secret) + unregister_secured_file (tmpfname); iobuf_cancel(newfp); goto leave; } @@ -1531,6 +1542,8 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, log_error ("%s: copy to `%s' failed: %s\n", fname, tmpfname, g10_errstr(rc) ); iobuf_close(fp); + if (secret) + unregister_secured_file (tmpfname); iobuf_cancel(newfp); goto leave; } @@ -1541,6 +1554,8 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, log_error("%s: skipping %u packets failed: %s\n", fname, n_packets, g10_errstr(rc)); iobuf_close(fp); + if (secret) + unregister_secured_file (tmpfname); iobuf_cancel(newfp); goto leave; } @@ -1550,6 +1565,8 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, rc = write_keyblock (newfp, root); if (rc) { iobuf_close(fp); + if (secret) + unregister_secured_file (tmpfname); iobuf_cancel(newfp); goto leave; } @@ -1562,6 +1579,8 @@ do_copy (int mode, const char *fname, KBNODE root, int secret, log_error("%s: copy to `%s' failed: %s\n", fname, tmpfname, g10_errstr(rc) ); iobuf_close(fp); + if (secret) + unregister_secured_file (tmpfname); iobuf_cancel(newfp); goto leave; } diff --git a/g10/main.h b/g10/main.h index aa213bbe0..38750dff8 100644 --- a/g10/main.h +++ b/g10/main.h @@ -72,6 +72,9 @@ char *make_radix64_string( const byte *data, size_t len ); /*-- misc.c --*/ void trap_unaligned(void); int disable_core_dumps(void); +void register_secured_file (const char *fname); +void unregister_secured_file (const char *fname); +int is_secured_file (int fd); u16 checksum_u16( unsigned n ); u16 checksum( byte *p, unsigned n ); u16 checksum_mpi( MPI a ); diff --git a/g10/misc.c b/g10/misc.c index c47459ba6..207367d7e 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -34,6 +34,9 @@ #include #include #endif +#ifdef ENABLE_SELINUX_HACKS +#include +#endif #include "util.h" #include "main.h" #include "photoid.h" @@ -41,6 +44,21 @@ #include "i18n.h" #include "cardglue.h" + +#ifdef ENABLE_SELINUX_HACKS +/* A object and a global variable to keep track of files marked as + secured. */ +struct secured_file_item +{ + struct secured_file_item *next; + ino_t ino; + dev_t dev; +}; +static struct secured_file_item *secured_files; +#endif /*ENABLE_SELINUX_HACKS*/ + + + #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 static int setsysinfo(unsigned long op, void *buffer, unsigned long size, @@ -87,6 +105,100 @@ disable_core_dumps() } +/* For the sake of SELinux we want to restrict access through gpg to + certain files we keep under our own control. This function + registers such a file and is_secured_file may then be used to + check whether a file has ben registered as secured. */ +void +register_secured_file (const char *fname) +{ +#ifdef ENABLE_SELINUX_HACKS + struct stat buf; + struct secured_file_item *sf; + + /* Note that we stop immediatley if something goes wrong here. */ + if (stat (fname, &buf)) + log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname, + "register_secured_file", strerror (errno)); +/* log_debug ("registering `%s' i=%lu.%lu\n", fname, */ +/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */ + for (sf=secured_files; sf; sf = sf->next) + { + if (sf->ino == buf.st_ino && sf->dev == buf.st_dev) + return; /* Already registered. */ + } + + sf = xmalloc (sizeof *sf); + sf->ino = buf.st_ino; + sf->dev = buf.st_dev; + sf->next = secured_files; + secured_files = sf; +#endif /*ENABLE_SELINUX_HACKS*/ +} + +/* Remove a file registerd as secure. */ +void +unregister_secured_file (const char *fname) +{ +#ifdef ENABLE_SELINUX_HACKS + struct stat buf; + struct secured_file_item *sf, *sfprev; + + if (stat (fname, &buf)) + { + log_error (_("fstat of `%s' failed in %s: %s\n"), fname, + "unregister_secured_file", strerror (errno)); + return; + } +/* log_debug ("unregistering `%s' i=%lu.%lu\n", fname, */ +/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */ + for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next) + { + if (sf->ino == buf.st_ino && sf->dev == buf.st_dev) + { + if (sfprev) + sfprev->next = sf->next; + else + secured_files = sf->next; + xfree (sf); + return; + } + } +#endif /*ENABLE_SELINUX_HACKS*/ +} + +/* Return true if FD is corresponds to a secured file. Using -1 for + FS is allowed and will return false. */ +int +is_secured_file (int fd) +{ +#ifdef ENABLE_SELINUX_HACKS + struct stat buf; + struct secured_file_item *sf; + + if (fd == -1) + return 0; /* No file descriptor so it can't be secured either. */ + + /* Note that we print out a error here and claim that a file is + secure if something went wrong. */ + if (fstat (fd, &buf)) + { + log_error (_("fstat(%d) failed in %s: %s\n"), fd, + "is_secured_file", strerror (errno)); + return 1; + } +/* log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */ +/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */ + for (sf=secured_files; sf; sf = sf->next) + { + if (sf->ino == buf.st_ino && sf->dev == buf.st_dev) + return 1; /* Yes. */ + } +#endif /*ENABLE_SELINUX_HACKS*/ + return 0; /* No. */ +} + + u16 checksum_u16( unsigned n ) diff --git a/g10/openfile.c b/g10/openfile.c index 3f52b613b..9c305a2f2 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -278,6 +278,12 @@ open_sigfile( const char *iname, progress_filter_context_t *pfx ) buf = m_strdup(iname); buf[len-(buf[len-1]=='n'?5:4)] = 0 ; a = iobuf_open( buf ); + if (a && is_secured_file (iobuf_get_fd (a))) + { + iobuf_close (a); + a = NULL; + errno = EPERM; + } if( a && opt.verbose ) log_info(_("assuming signed data in `%s'\n"), buf ); if (a && pfx) @@ -309,6 +315,12 @@ copy_options_file( const char *destdir ) fname = m_alloc( strlen(datadir) + strlen(destdir) + 15 ); strcpy(stpcpy(fname, datadir), DIRSEP_S "options" SKELEXT ); src = fopen( fname, "r" ); + if (src && is_secured_file (fileno (src))) + { + fclose (src); + src = NULL; + errno = EPERM; + } if( !src ) { log_error(_("%s: can't open: %s\n"), fname, strerror(errno) ); m_free(fname); diff --git a/g10/photoid.c b/g10/photoid.c index 9487c0fb9..385a6818e 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -83,9 +83,15 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk) goto scram; file=iobuf_open(filename); + if (file && is_secured_file (iobuf_get_fd (file))) + { + iobuf_close (file); + file = NULL; + errno = EPERM; + } if(!file) { - log_error(_("Unable to open JPEG file `%s': %s\n"), + log_error(_("unable to open JPEG file `%s': %s\n"), filename,strerror(errno)); continue; } diff --git a/g10/plaintext.c b/g10/plaintext.c index 8918d199c..8b782add7 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -446,6 +446,12 @@ ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2, goto leave; } fp = iobuf_open(answer); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } if( !fp && errno == ENOENT ) { tty_printf("No such file, try again or hit enter to quit.\n"); any++; @@ -501,6 +507,12 @@ hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files, for (sl=files; sl; sl = sl->next ) { fp = iobuf_open( sl->d ); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } if( !fp ) { log_error(_("can't open signed data `%s'\n"), print_fname_stdin(sl->d)); diff --git a/g10/sign.c b/g10/sign.c index c2d84459a..b6f67e55c 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -750,8 +750,15 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( multifile ) /* have list of filenames */ inp = NULL; /* we do it later */ else { - if( !(inp = iobuf_open(fname)) ) { - log_error("can't open %s: %s\n", fname? fname: "[stdin]", + inp = iobuf_open(fname); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if( !inp ) { + log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]", strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; @@ -888,7 +895,14 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, /* must walk reverse trough this list */ for( sl = strlist_last(filenames); sl; sl = strlist_prev( filenames, sl ) ) { - if( !(inp = iobuf_open(sl->d)) ) { + inp = iobuf_open(sl->d); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if( !inp ) { log_error(_("can't open file `%s': %s\n"), sl->d, strerror(errno) ); rc = G10ERR_OPEN_FILE; @@ -989,8 +1003,15 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) } /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - log_error("can't open %s: %s\n", fname? fname: "[stdin]", + inp = iobuf_open(fname); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if( !inp ) { + log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]", strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; @@ -1122,9 +1143,15 @@ sign_symencrypt_file (const char *fname, STRLIST locusr) /* prepare iobufs */ inp = iobuf_open(fname); + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } if( !inp ) { - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); + log_error(_("can't open `%s': %s\n"), + fname? fname: "[stdin]", strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; } diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 559a208aa..f3ec27df9 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -137,10 +137,18 @@ import_ownertrust( const char *fname ) is_stdin = 1; } else if( !(fp = fopen( fname, "r" )) ) { - log_error_f(fname, _("can't open file: %s\n"), strerror(errno) ); + log_error ( _("can't open `%s': %s\n"), fname, strerror(errno) ); return; } + if (is_secured_file (fileno (fp))) + { + fclose (fp); + errno = EPERM; + log_error (_("can't open `%s': %s\n"), fname, strerror(errno) ); + return; + } + while( fgets( line, DIM(line)-1, fp ) ) { TRUSTREC rec; @@ -148,7 +156,7 @@ import_ownertrust( const char *fname ) continue; n = strlen(line); if( line[n-1] != '\n' ) { - log_error_f(fname, _("line too long\n") ); + log_error (_("error in `%s': %s\n"), fname, _("line too long") ); /* ... or last line does not have a LF */ break; /* can't continue */ } @@ -156,16 +164,18 @@ import_ownertrust( const char *fname ) if( !hexdigitp(p) ) break; if( *p != ':' ) { - log_error_f(fname, _("error: missing colon\n") ); + log_error (_("error in `%s': %s\n"), fname, _("colon missing") ); continue; } fprlen = p - line; if( fprlen != 32 && fprlen != 40 ) { - log_error_f(fname, _("error: invalid fingerprint\n") ); + log_error (_("error in `%s': %s\n"), + fname, _("invalid fingerprint") ); continue; } if( sscanf(p, ":%u:", &otrust ) != 1 ) { - log_error_f(fname, _("error: no ownertrust value\n") ); + log_error (_("error in `%s': %s\n"), + fname, _("ownertrust value missing")); continue; } if( !otrust ) @@ -201,11 +211,11 @@ import_ownertrust( const char *fname ) any = 1; } else /* error */ - log_error_f(fname, _("error finding trust record: %s\n"), - g10_errstr(rc)); + log_error (_("error finding trust record in `%s': %s\n"), + fname, g10_errstr(rc)); } if( ferror(fp) ) - log_error_f(fname, _("read error: %s\n"), strerror(errno) ); + log_error ( _("read error in `%s': %s\n"), fname, strerror(errno) ); if( !is_stdin ) fclose(fp); diff --git a/g10/tdbio.c b/g10/tdbio.c index b245da049..0b182cfad 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -593,6 +593,7 @@ open_db() } if ( db_fd == -1 ) log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) ); + register_secured_file (db_name); /* check whether we need to do a version migration */ do diff --git a/g10/verify.c b/g10/verify.c index 24e140b26..df60b7d71 100644 --- a/g10/verify.c +++ b/g10/verify.c @@ -91,6 +91,12 @@ verify_signatures( int nfiles, char **files ) /* open the signature file */ fp = iobuf_open(sigfile); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } if( !fp ) { log_error(_("can't open `%s'\n"), print_fname_stdin(sigfile)); return G10ERR_OPEN_FILE; @@ -137,6 +143,12 @@ verify_one_file( const char *name ) print_file_status( STATUS_FILE_START, name, 1 ); fp = iobuf_open(name); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } if( !fp ) { print_file_status( STATUS_FILE_ERROR, name, 1 ); log_error(_("can't open `%s'\n"), print_fname_stdin(name)); diff --git a/include/iobuf.h b/include/iobuf.h index 348b9b32c..bc2f0a156 100644 --- a/include/iobuf.h +++ b/include/iobuf.h @@ -124,6 +124,7 @@ int iobuf_write_temp( IOBUF a, IOBUF temp ); size_t iobuf_temp_to_buffer( IOBUF a, byte *buffer, size_t buflen ); void iobuf_unget_and_close_temp( IOBUF a, IOBUF temp ); +int iobuf_get_fd (IOBUF a); off_t iobuf_get_filelength( IOBUF a ); #define IOBUF_FILELENGTH_LIMIT 0xffffffff const char *iobuf_get_real_fname( IOBUF a ); diff --git a/include/util.h b/include/util.h index e8d79e8c2..458d13257 100644 --- a/include/util.h +++ b/include/util.h @@ -85,14 +85,6 @@ void g10_log_hexdump( const char *text, const char *buf, size_t len ); void g10_log_info( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); void g10_log_warning( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); void g10_log_debug( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - void g10_log_fatal_f( const char *fname, const char *fmt, ... ) - __attribute__ ((noreturn, format (printf,2,3))); - void g10_log_error_f( const char *fname, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); - void g10_log_info_f( const char *fname, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); - void g10_log_debug_f( const char *fname, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); #ifndef __riscos__ #define BUG() g10_log_bug0( __FILE__ , __LINE__, __FUNCTION__ ) #else @@ -106,10 +98,6 @@ void g10_log_hexdump( const char *text, const char *buf, size_t len ); void g10_log_info( const char *fmt, ... ); void g10_log_warning( const char *fmt, ... ); void g10_log_debug( const char *fmt, ... ); - void g10_log_fatal_f( const char *fname, const char *fmt, ... ); - void g10_log_error_f( const char *fname, const char *fmt, ... ); - void g10_log_info_f( const char *fname, const char *fmt, ... ); - void g10_log_debug_f( const char *fname, const char *fmt, ... ); #define BUG() g10_log_bug0( __FILE__ , __LINE__ ) #endif @@ -121,10 +109,6 @@ void g10_log_hexdump( const char *text, const char *buf, size_t len ); #define log_info g10_log_info #define log_warning g10_log_warning #define log_debug g10_log_debug -#define log_fatal_f g10_log_fatal_f -#define log_error_f g10_log_error_f -#define log_info_f g10_log_info_f -#define log_debug_f g10_log_debug_f /*-- errors.c --*/