diff --git a/ChangeLog b/ChangeLog index d4b01c746..e8d61c556 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Jul 30 19:17:07 1998 Werner Koch (wk@(none)) + + * acinclude.h (WK_CHECK_IPC): New + * configure.in : Add checks for SysV IPC + Thu Jun 25 11:18:49 1998 Werner Koch (wk@isil.d.shuttle.de) * configure.in (--disable-dynload): New. diff --git a/NEWS b/NEWS index 0a375b1a3..4cbb5a777 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,9 @@ Noteworthy changes in version 0.3.3 IMPORTANT: Use version 0.3.[12] to save your assigned ownertrusts ("gpgm --list-ownertrust >saved-trust"); then build this new version and restore the ownertrust with this new version - ("gpgm --import-ownertrust saved-trust"). + ("gpgm --import-ownertrust saved-trust"). Please note that + --list-ownertrust has been renamed to --export-ownertrust in this + release and it does now only export defined ownertrusts. * The command --edit-key now provides a commandline driven menu which can be used vor vaious tasks. --sign-key is only an @@ -15,6 +17,8 @@ Noteworthy changes in version 0.3.3 * Alternate user ids can now be created an signed. + * Owner trust values can now be changed with --edit-key (trust) + * Removed options --gen-prime and --gen-random. * Removed option --add-key; use --edit-key instead. diff --git a/TODO b/TODO index 9ceeb728f..e6cf8a71a 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,3 @@ - * Change the internal represenation of keyid into a struct which - can also hold the localid and extend the localid to hold information - of the subkey number because two subkeys may have the same keyid. - * Fix Oscaris problems with the trustdb. * add test cases for invalid data (scrambled armor or other random data) @@ -19,10 +15,6 @@ * what about the CR,LF in cleartext singatures? - * add option --import-ownertrust - - * add a way to delete subkeys (in edit-keys?) - * make preferences work * rewrite --list-packets or put it into another tool. @@ -30,8 +22,6 @@ * add usage arguments to get_key_byname or return a PKC_LIST with all keys and add a selection. - * add readline support. Must enhance libreadline - Anyone? - * Burn the buffers used by fopen(), or use read(2). Does this really make sense? @@ -41,6 +31,10 @@ * add checking of armor trailers * remove all "Fixmes" + * Change the internal represention of keyid into a struct which + can also hold the localid and extend the localid to hold information + of the subkey number because two subkeys may have the same keyid. + * add an option to re-create a public key from a secret key. Think about a backup system of only the secret part of the secret key. diff --git a/acconfig.h b/acconfig.h index 50014cf39..89e367b7c 100644 --- a/acconfig.h +++ b/acconfig.h @@ -76,6 +76,10 @@ #undef HAVE_DL_DLOPEN #undef HAVE_DLD_DLD_LINK +#undef USE_SHM_COPROCESSING + +#undef IPC_RMID_DEFERRED_RELEASE + @BOTTOM@ #endif /*G10_CONFIG_H*/ diff --git a/acinclude.m4 b/acinclude.m4 index bbb409b60..5f7c56215 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -22,7 +22,7 @@ AC_DEFUN(WK_CHECK_TYPEDEF, ], wk_cv_typedef_$1=yes, wk_cv_typedef_$1=no )]) AC_MSG_RESULT($wk_cv_typedef_$1) if test "$wk_cv_typedef_$1" = yes; then - AC_DEFINE($2) + AC_DEFINE($2) fi ]) @@ -37,11 +37,11 @@ dnl correct when using a caching scheme dnl define(WK_LINK_FILES, [ if test "x$wk_link_files_src" = "x"; then - wk_link_files_src="$1" - wk_link_files_dst="$2" + wk_link_files_src="$1" + wk_link_files_dst="$2" else - wk_link_files_src="$wk_link_files_src $1" - wk_link_files_dst="$wk_link_files_dst $2" + wk_link_files_src="$wk_link_files_src $1" + wk_link_files_dst="$wk_link_files_dst $2" fi ]) define(WK_DO_LINK_FILES, @@ -54,38 +54,38 @@ dnl define either LITTLE_ENDIAN_HOST or BIG_ENDIAN_HOST dnl define(WK_CHECK_ENDIAN, [ if test "$cross_compiling" = yes; then - AC_MSG_WARN(cross compiling; assuming little endianess) + AC_MSG_WARN(cross compiling; assuming little endianess) fi AC_MSG_CHECKING(endianess) AC_CACHE_VAL(wk_cv_c_endian, [ wk_cv_c_endian=unknown - # See if sys/param.h defines the BYTE_ORDER macro. - AC_TRY_COMPILE([#include - #include ], [ - #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros - #endif], [# It does; now see whether it defined to BIG_ENDIAN or not. - AC_TRY_COMPILE([#include - #include ], [ - #if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif], wk_cv_c_endian=big, wk_cv_c_endian=little)]) - if test "$wk_cv_c_endian" = unknown; then - AC_TRY_RUN([main () { - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long l; - char c[sizeof (long)]; - } u; - u.l = 1; - exit (u.c[sizeof (long) - 1] == 1); - }], - wk_cv_c_endian=little, - wk_cv_c_endian=big, - wk_cv_c_endian=little - ) - fi + # See if sys/param.h defines the BYTE_ORDER macro. + AC_TRY_COMPILE([#include + #include ], [ + #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros + #endif], [# It does; now see whether it defined to BIG_ENDIAN or not. + AC_TRY_COMPILE([#include + #include ], [ + #if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif], wk_cv_c_endian=big, wk_cv_c_endian=little)]) + if test "$wk_cv_c_endian" = unknown; then + AC_TRY_RUN([main () { + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); + }], + wk_cv_c_endian=little, + wk_cv_c_endian=big, + wk_cv_c_endian=little + ) + fi ]) AC_MSG_RESULT([$wk_cv_c_endian]) if test "$wk_cv_c_endian" = little; then @@ -102,12 +102,54 @@ define(WK_CHECK_CACHE, wk_hostcheck="$target" AC_CACHE_VAL(wk_cv_hostcheck, [ wk_cv_hostcheck="$wk_hostcheck" ]) if test "$wk_cv_hostcheck" != "$wk_hostcheck"; then - AC_MSG_RESULT(changed) - AC_MSG_WARN(config.cache exists!) - AC_MSG_ERROR(you must do 'make distclean' first to compile for - different target or different parameters.) + AC_MSG_RESULT(changed) + AC_MSG_WARN(config.cache exists!) + AC_MSG_ERROR(you must do 'make distclean' first to compile for + different target or different parameters.) else - AC_MSG_RESULT(ok) + AC_MSG_RESULT(ok) + fi + ]) + + + + +###################################################################### +# Check for SysV IPC (from GIMP) +###################################################################### +dnl WK_CHECK_IPC +dnl +define(WK_CHECK_IPC, + [ AC_CHECK_HEADERS(sys/ipc.h sys/shm.h) + if test "$ac_cv_header_sys_shm_h" = "yes"; then + AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches) + AC_TRY_RUN([ + #include + #include + #include + int main() + { + int id; + char *shmaddr; + id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0777); + if (id == -1) + exit (2); + shmaddr = shmat (id, 0, 0); + shmctl (id, IPC_RMID, 0); + if ((char*) shmat (id, 0, 0) == (char*) -1) + { + shmdt (shmaddr); + exit (1); + } + shmdt (shmaddr); + shmdt (shmaddr); + exit (0); + } + ], + AC_DEFINE(IPC_RMID_DEFERRED_RELEASE) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no), + AC_MSG_RESULT(assuming no)) fi ]) @@ -142,8 +184,8 @@ AC_CACHE_VAL(ac_cv_path_$1, test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if [$3]; then - ac_cv_path_$1="$ac_dir/$ac_word" - break + ac_cv_path_$1="$ac_dir/$ac_word" + break fi fi done @@ -206,7 +248,7 @@ AC_DEFUN(AM_WITH_NLS, [AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE(nls, - [ --disable-nls do not use Native Language Support], + [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) @@ -218,129 +260,129 @@ AC_DEFUN(AM_WITH_NLS, AC_DEFINE(ENABLE_NLS) AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH(included-gettext, - [ --with-included-gettext use the GNU gettext library included here], - nls_cv_force_use_gnu_gettext=$withval, - nls_cv_force_use_gnu_gettext=no) + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then - dnl User does not insist on using GNU NLS library. Figure out what - dnl to use. If gettext or catgets are available (in this order) we - dnl use this. Else we have to fall back to GNU NLS library. - dnl catgets is only used if permitted by option --with-catgets. - nls_cv_header_intl= - nls_cv_header_libgt= - CATOBJEXT=NONE + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE - AC_CHECK_HEADER(libintl.h, - [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, - [AC_TRY_LINK([#include ], [return (int) gettext ("")], - gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, + [AC_TRY_LINK([#include ], [return (int) gettext ("")], + gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) - if test "$gt_cv_func_gettext_libc" != "yes"; then - AC_CHECK_LIB(intl, bindtextdomain, - [AC_CACHE_CHECK([for gettext in libintl], - gt_cv_func_gettext_libintl, - [AC_TRY_LINK([], [return (int) gettext ("")], - gt_cv_func_gettext_libintl=yes, - gt_cv_func_gettext_libintl=no)])]) - fi + if test "$gt_cv_func_gettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for gettext in libintl], + gt_cv_func_gettext_libintl, + [AC_TRY_LINK([], [return (int) gettext ("")], + gt_cv_func_gettext_libintl=yes, + gt_cv_func_gettext_libintl=no)])]) + fi - if test "$gt_cv_func_gettext_libc" = "yes" \ - || test "$gt_cv_func_gettext_libintl" = "yes"; then - AC_DEFINE(HAVE_GETTEXT) - AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl - if test "$MSGFMT" != "no"; then - AC_CHECK_FUNCS(dcgettext) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) - AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; - return _nl_msg_cat_cntr], - [CATOBJEXT=.gmo - DATADIRNAME=share], - [CATOBJEXT=.mo - DATADIRNAME=lib]) - INSTOBJEXT=.mo - fi - fi - ]) + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + ]) - if test "$CATOBJEXT" = "NONE"; then - AC_MSG_CHECKING([whether catgets can be used]) - AC_ARG_WITH(catgets, - [ --with-catgets use catgets functions if available], - nls_cv_use_catgets=$withval, nls_cv_use_catgets=no) - AC_MSG_RESULT($nls_cv_use_catgets) + if test "$CATOBJEXT" = "NONE"; then + AC_MSG_CHECKING([whether catgets can be used]) + AC_ARG_WITH(catgets, + [ --with-catgets use catgets functions if available], + nls_cv_use_catgets=$withval, nls_cv_use_catgets=no) + AC_MSG_RESULT($nls_cv_use_catgets) - if test "$nls_cv_use_catgets" = "yes"; then - dnl No gettext in C library. Try catgets next. - AC_CHECK_LIB(i, main) - AC_CHECK_FUNC(catgets, - [AC_DEFINE(HAVE_CATGETS) - INTLOBJS="\$(CATOBJS)" - AC_PATH_PROG(GENCAT, gencat, no)dnl - if test "$GENCAT" != "no"; then - AC_PATH_PROG(GMSGFMT, gmsgfmt, no) - if test "$GMSGFMT" = "no"; then - AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no) - fi - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) - USE_INCLUDED_LIBINTL=yes - CATOBJEXT=.cat - INSTOBJEXT=.cat - DATADIRNAME=lib - INTLDEPS='$(top_builddir)/intl/libintl.a' - INTLLIBS=$INTLDEPS - LIBS=`echo $LIBS | sed -e 's/-lintl//'` - nls_cv_header_intl=intl/libintl.h - nls_cv_header_libgt=intl/libgettext.h - fi]) - fi - fi + if test "$nls_cv_use_catgets" = "yes"; then + dnl No gettext in C library. Try catgets next. + AC_CHECK_LIB(i, main) + AC_CHECK_FUNC(catgets, + [AC_DEFINE(HAVE_CATGETS) + INTLOBJS="\$(CATOBJS)" + AC_PATH_PROG(GENCAT, gencat, no)dnl + if test "$GENCAT" != "no"; then + AC_PATH_PROG(GMSGFMT, gmsgfmt, no) + if test "$GMSGFMT" = "no"; then + AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no) + fi + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.cat + INSTOBJEXT=.cat + DATADIRNAME=lib + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi]) + fi + fi - if test "$CATOBJEXT" = "NONE"; then - dnl Neither gettext nor catgets in included in the C library. - dnl Fall back on GNU gettext library. - nls_cv_use_gnu_gettext=yes - fi + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included in the C library. + dnl Fall back on GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions used to generate GNU NLS library. - INTLOBJS="\$(GETTOBJS)" - AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) - AC_SUBST(MSGFMT) - USE_INCLUDED_LIBINTL=yes - CATOBJEXT=.gmo - INSTOBJEXT=.mo - DATADIRNAME=share - INTLDEPS='$(top_builddir)/intl/libintl.a' - INTLLIBS=$INTLDEPS - LIBS=`echo $LIBS | sed -e 's/-lintl//'` - nls_cv_header_intl=intl/libintl.h - nls_cv_header_libgt=intl/libgettext.h + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_SUBST(MSGFMT) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h fi dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then - dnl If it is no GNU xgettext we define it as : so that the - dnl Makefiles still can work. - if $XGETTEXT --omit-header /dev/null 2> /dev/null; then - : ; - else - AC_MSG_RESULT( - [found xgettext programs is not GNU xgettext; ignore it]) - XGETTEXT=":" - fi + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext programs is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi fi # We need to process the po/ directory. @@ -415,9 +457,9 @@ __argz_count __argz_stringify __argz_next]) AC_MSG_CHECKING(for catalogs to be installed) NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do - case "$ALL_LINGUAS" in - *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; - esac + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac done LINGUAS=$NEW_LINGUAS AC_MSG_RESULT($LINGUAS) @@ -442,7 +484,7 @@ __argz_count __argz_stringify __argz_next]) dnl Determine which catalog format we have (if any is needed) dnl For now we know about two different formats: - dnl Linux libc-5 and the normal X/Open format + dnl Linux libc-5 and the normal X/Open format test -d intl || mkdir intl if test "$CATOBJEXT" = ".cat"; then AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) @@ -456,7 +498,7 @@ __argz_count __argz_stringify __argz_next]) $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed dnl In the intl/Makefile.in we have a special dependency which makes - dnl only sense for gettext. We comment this out for non-gettext + dnl only sense for gettext. We comment this out for non-gettext dnl packages. if test "$PACKAGE" = "gettext"; then GT_NO="#NO#" @@ -498,7 +540,7 @@ __argz_count __argz_stringify __argz_next]) fi rm -f po/POTFILES sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ - < $srcdir/po/POTFILES.in > po/POTFILES + < $srcdir/po/POTFILES.in > po/POTFILES ]) diff --git a/configure.in b/configure.in index 80a5c07dd..5962ddc6c 100644 --- a/configure.in +++ b/configure.in @@ -150,7 +150,6 @@ AC_HEADER_STDC AC_CHECK_HEADERS(unistd.h) - dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE @@ -184,6 +183,10 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul mlock mmap) AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime setrlimit) +WK_CHECK_IPC +if test "$ac_cv_header_sys_shm_h" = "yes"; then + AC_DEFINE(USE_SHM_COPROCESSING) +fi dnl check whether we have a random device if test "$try_dev_random" = yes ; then diff --git a/doc/gpg.1pod b/doc/gpg.1pod index 5be04b6b3..3cc3b24db 100644 --- a/doc/gpg.1pod +++ b/doc/gpg.1pod @@ -54,14 +54,14 @@ B<--verify> [[I] {I}] without generating any output. With no arguments, the signature packet is read from stdin (it may be a detached signature when not used in batch mode). If - only a sigfile is given, it may be a complete signature - or a detached signature, in which case the signed stuff - is expected in a file without the I<.sig> or I<.asc> - extension (if such a file does not exist it is expected - at stdin - use B<-> as filename to force a read from - stdin). With more than 1 argument, the - first should be a detached signature and the remaining - files are the signed stuff. + only a sigfile is given, it may be a complete + signature or a detached signature, in which case + the signed stuff is expected in a file without the + I<.sig> or I<.asc> extension (if such a file does + not exist it is expected at stdin - use B<-> as + filename to force a read from stdin). With more than + 1 argument, the first should be a detached signature + and the remaining files are the signed stuff. B<-k> [I] [I] Kludge to be somewhat compatible with PGP. @@ -76,11 +76,16 @@ B<-k> [I] [I] B<-kvvc> List fingerprints and signatures B<--list-keys> [I] - List all keys from the default public keyring, or just the ones - given on the command line. + List all keys from the public keyrings, or just the + ones given on the command line. + +B<--list-secret-keys> [I] + List all keys from the secret keyrings, or just the + ones given on the command line. B<--list-sigs> [I] - Same as B<--list-keys>, but the signatures are listed too. + Same as B<--list-keys>, but the signatures are listed + too. B<--check-sigs> [I] Same as B<--list-sigs>, but the signatures are verified. @@ -112,6 +117,9 @@ B<--edit-key> I asks whether it should be signed. This question is repeated for all users specified with B<-u>. + B + Change the owner trust value. This updates the + trust-db immediately and no save is required. B Create an alternate user id. B @@ -139,6 +147,21 @@ B<--edit-key> I B Quit the program without updating the key rings. + The listing shows you the key with its secondary + keys and all user ids. Selected keys or user ids + indicated by an asterisk. The trust value is + displayed with the primary key: The first one is the + assigned owner trust and the second the calculated + trust value; letters are used for the values: + B<-> No ownertrust assigned. + B Trust not yet calculated. + B Trust calculation failed. + B Not enough information for calculation. + B Never trust this key. + B Marginally trusted. + B Fully trusted. + B Ultimately trusted + B<--delete-key> Remove key from the public keyring @@ -157,17 +180,22 @@ B<--export> [I] the file given with option "output". Use together with B<-a> to mail those keys. + +B<--export-secret-keys> [I + Same as B<--export>, but does export the secret keys. + This is normally not very useful. + B<--import> import/merge keys B<--export-ownertrust> - List the assigned ownertrust values in ascii format for - backup purposes [B only]. + List the assigned ownertrust values in ascii format + for backup purposes [B only]. B<--import-ownertrust> [I] - Update the trustdb with the ownertrust values stored in - I (or stdin if not given); existing values will be - overwritten. [B only]. + Update the trustdb with the ownertrust values stored + in I (or stdin if not given); existing + values will be overwritten. [B only]. =head1 OPTIONS @@ -193,8 +221,8 @@ B<-u> I, B<--local-user> I B<--default-key> I Use I as default user-id for signatures. If this - is not used the default user-id is the first user-id in - the secret keyring. + is not used the default user-id is the first user-id + from the secret keyring. B<-r> I, B<--remote-user> I Use I as the user-id for encryption. @@ -323,9 +351,9 @@ B<--no-default-keyring> keyrings. B<--skip-verify> - Skip the signature verification step. This may be used to - make the encryption faster if the signature verification - is not needed. + Skip the signature verification step. This may be + used to make the encryption faster if the signature + verification is not needed. B<--version> Print version information along with a list @@ -369,6 +397,8 @@ F<~/.gnupg/trustdb.gpg> The trust database F<~/.gnupg/options> May contain options +F Default location for extensions + =head1 SEE ALSO gpgm(1) gpgd(1) @@ -389,6 +419,6 @@ is B easy to spy out your passphrase! On many systems this program should be installed as setuid(root); this is necessary to lock some pages of memory. If you get no warning message -about insecure memory you have a nice OS kernel and you don't need to make -it setuid. +about insecure memory your OS kernel supports locking without being root; +setuid is dropped as soon as this memory is allocated. diff --git a/g10/OPTIONS b/g10/OPTIONS index 4def8e60e..03ef351ee 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -26,24 +26,13 @@ print-md algo print-mds # print all message digests of all give filenames -sign-key store # simply packs the input data into a rfc1991 packet format -list-secret-keys -# - -export-secret-keys -# export secret keys (which may be usefuil in some cases) - check-trustdb - - - - #----------------------------------------------- #--- options #----------------------------------------------- @@ -57,9 +46,3 @@ compress-sigs # Normally, compressing of signatures does not make sense; so this # is disabled for detached signatures unless this option is used. - -emulate-pgp-sign-bug -# PGP 2.x can only cope with 2 byte length headers of the -# signature packets, this option forces. - - diff --git a/g10/keyedit.c b/g10/keyedit.c index 73772328b..c137d1af7 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -34,6 +34,7 @@ #include "memory.h" #include "util.h" #include "main.h" +#include "trustdb.h" #include "filter.h" #include "ttyio.h" #include "i18n.h" @@ -541,7 +542,7 @@ keyedit_menu( const char *username, STRLIST locusr ) enum cmdids { cmdNONE = 0, cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY, - cmdTOGGLE, cmdSELKEY, cmdPASSWD, + cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdNOP }; static struct { const char *name; enum cmdids id; @@ -571,6 +572,7 @@ keyedit_menu( const char *username, STRLIST locusr ) "and public key listing") }, { N_("t" ) , cmdTOGGLE , 1, NULL }, { N_("passwd") , cmdPASSWD , 1, N_("change the passphrase") }, + { N_("trust") , cmdTRUST , 0, N_("change the ownertrust") }, { NULL, cmdNONE } }; enum cmdids cmd; @@ -805,6 +807,16 @@ keyedit_menu( const char *username, STRLIST locusr ) sec_modified = 1; break; + case cmdTRUST: + show_key_with_all_names( keyblock, 0, 0, 1 ); + tty_printf("\n"); + if( edit_ownertrust( find_kbnode( keyblock, + PKT_PUBLIC_KEY )->pkt->pkt.public_key->local_id, 1 ) ) + redisplay = 1; + /* we don't need to set modified here, as the trustvalues + * are updated immediately */ + break; + case cmdNOP: break; @@ -839,7 +851,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, if( node->pkt->pkttype == PKT_PUBLIC_KEY || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) { PKT_public_key *pk = node->pkt->pkt.public_key; - tty_printf("%s%c %4u%c/%08lX created: %s expires: %s\n", + tty_printf("%s%c %4u%c/%08lX created: %s expires: %s", node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub", (node->flag & NODFLG_SELKEY)? '*':' ', nbits_from_pk( pk ), @@ -847,8 +859,15 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, (ulong)keyid_from_pk(pk,NULL), datestr_from_pk(pk), expirestr_from_pk(pk) ); - if( with_fpr && node->pkt->pkttype == PKT_PUBLIC_KEY ) - show_fingerprint( pk ); + if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { + int otrust, trust; + trust = query_trust_info(pk); + otrust = get_ownertrust_info( pk->local_id ); + tty_printf(" trust: %c/%c", otrust, trust ); + if( with_fpr ) + show_fingerprint( pk ); + } + tty_printf("\n"); } else if( node->pkt->pkttype == PKT_SECRET_KEY || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) { diff --git a/g10/pkclist.c b/g10/pkclist.c index 7fbe065b6..dbbcbbdd8 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -39,8 +39,8 @@ /**************** * Returns true if an ownertrust has changed. */ -static int -query_ownertrust( ulong lid ) +int +edit_ownertrust( ulong lid, int mode ) { char *p; int rc; @@ -63,14 +63,17 @@ query_ownertrust( ulong lid ) return 0; } - tty_printf(_("No owner trust defined for %lu:\n" - "%4u%c/%08lX %s \""), lid, - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk( pk ) ); - p = get_user_id( keyid, &n ); - tty_print_string( p, n ), - m_free(p); - tty_printf(_("\"\n\n" + if( !mode ) { + tty_printf(_("No owner trust defined for %lu:\n" + "%4u%c/%08lX %s \""), lid, + nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), + (ulong)keyid[1], datestr_from_pk( pk ) ); + p = get_user_id( keyid, &n ); + tty_print_string( p, n ), + m_free(p); + tty_printf("\"\n\n"); + } + tty_printf(_( "Please decide how far you trust this user to correctly\n" "verify other users' keys (by looking at passports,\n" "checking fingerprints from different sources...)?\n\n" @@ -146,7 +149,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n" log_fatal("Ooops: couldn't get owner trust for %lu\n", lid); if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED || trust == TRUST_UNKNOWN ) { - if( query_ownertrust( lid ) ) + if( edit_ownertrust( lid, 0 ) ) any=1; } } diff --git a/g10/tdbio.c b/g10/tdbio.c index 36f0ac503..381d0b2ec 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -734,19 +734,40 @@ tdbio_new_recnum() * The local_id of PK is set to the correct value */ int -tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) +tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec ) { - ulong recnum; - u32 keyid[2]; byte *fingerprint; size_t fingerlen; + u32 keyid[2]; + int rc; + + keyid_from_pk( pk, keyid ); + fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen ); + rc = tdbio_search_dir_byfpr( fingerprint, fingerlen, + pk->pubkey_algo, rec ); + + if( !rc ) { + if( pk->local_id && pk->local_id != rec->recnum ) + log_error_f(db_name, + "found record, but LID from memory does " + "not match recnum (%lu,%lu)\n", + pk->local_id, rec->recnum ); + pk->local_id = rec->recnum; + } + return rc; +} + + +int +tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen, + int pubkey_algo, TRUSTREC *rec ) +{ + ulong recnum; int rc; ulong hashrec, item; int msb; int level=0; - keyid_from_pk( pk, keyid ); - fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen ); assert( fingerlen == 20 || fingerlen == 16 ); /* locate the key using the hash table */ @@ -794,7 +815,7 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) g10_errstr(rc) ); return rc; } - if( tmp.r.key.pubkey_algo == pk->pubkey_algo + if( (!pubkey_algo || tmp.r.key.pubkey_algo == pubkey_algo) && tmp.r.key.fingerprint_len == fingerlen && !memcmp(tmp.r.key.fingerprint, fingerprint, fingerlen) ) { @@ -820,7 +841,7 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) } else if( rec->rectype == RECTYPE_KEY ) { /* must check that it is the requested key */ - if( rec->r.key.pubkey_algo != pk->pubkey_algo + if( (pubkey_algo && rec->r.key.pubkey_algo != pubkey_algo) || rec->r.key.fingerprint_len != fingerlen || memcmp(rec->r.key.fingerprint, fingerprint, fingerlen) ) return -1; /* no: not found */ @@ -832,14 +853,6 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) } recnum = rec->r.key.lid; - - if( pk->local_id && pk->local_id != recnum ) - log_error_f(db_name, - "found record, but LID from memory does " - "not match recnum (%lu,%lu)\n", - pk->local_id, recnum ); - pk->local_id = recnum; - /* Now read the dir record */ rc = tdbio_read_record( recnum, rec, RECTYPE_DIR); if( rc ) diff --git a/g10/tdbio.h b/g10/tdbio.h index c37c3ac1f..6fb0e545c 100644 --- a/g10/tdbio.h +++ b/g10/tdbio.h @@ -143,7 +143,9 @@ int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ); int tdbio_write_record( TRUSTREC *rec ); int tdbio_delete_record( ulong recnum ); ulong tdbio_new_recnum(void); -int tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ); +int tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec ); +int tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen, + int pubkey_algo, TRUSTREC *rec ); int tdbio_delete_uidrec( ulong dirlid, ulong uidlid ); diff --git a/g10/trustdb.c b/g10/trustdb.c index 2bd986c79..d1f0fd051 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -193,7 +193,7 @@ set_signature_packets_lid( PKT_signature *sig ) if( rc) goto leave; if( !pk->local_id ) { - rc = tdbio_search_dir_record( pk, &rec ); + rc = tdbio_search_dir_bypk( pk, &rec ); if( rc == -1 ) rc = insert_trust_record( pk ); if( rc ) @@ -935,7 +935,8 @@ update_sigs( TRUSTREC *dir ) rec->r.sig.sig[sigidx].lid = sig->local_id; rec->r.sig.sig[sigidx].flag = 0; sigidx++; - log_debug("key %08lX.%lu, uid %02X%02X: " + if( DBG_TRUST ) + log_debug("key %08lX.%lu, uid %02X%02X: " "signed by LID %lu\n", (ulong)keyid[1], lid, urec.r.uid.namehash[18], urec.r.uid.namehash[19], sig->local_id); @@ -1263,7 +1264,7 @@ list_trustdb( const char *username ) if( (rc = get_pubkey_byname( pk, username )) ) log_error("user '%s' not found: %s\n", username, g10_errstr(rc) ); - else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) + else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) log_error("problem finding '%s' in trustdb: %s\n", username, g10_errstr(rc)); else if( rc == -1 ) @@ -1343,6 +1344,9 @@ import_ownertrust( const char *fname ) } while( fgets( line, DIM(line)-1, fp ) ) { + TRUSTREC rec; + int rc; + if( !*line || *line == '#' ) continue; n = strlen(line); @@ -1373,7 +1377,44 @@ import_ownertrust( const char *fname ) line[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); line[fprlen] = 0; - log_hexdump("found: ", line, fprlen ); + repeat: + rc = tdbio_search_dir_byfpr( line, fprlen, 0, &rec ); + if( !rc ) { /* found: update */ + if( rec.r.dir.ownertrust ) + log_info("LID %lu: changing trust from %u to %u\n", + rec.r.dir.lid, rec.r.dir.ownertrust, otrust ); + else + log_info("LID %lu: setting trust to %u\n", + rec.r.dir.lid, otrust ); + rec.r.dir.ownertrust = otrust; + rc = tdbio_write_record( &rec ); + if( rc ) + log_error_f(fname, "error updating otrust: %s\n", + g10_errstr(rc)); + } + else if( rc == -1 ) { /* not found; get the key from the ring */ + PKT_public_key *pk = m_alloc_clear( sizeof *pk ); + + log_info_f(fname, "key not in trustdb, searching ring.\n"); + rc = get_pubkey_byfprint( pk, line, fprlen ); + if( rc ) + log_info_f(fname, "key not in ring: %s\n", g10_errstr(rc)); + else { + rc = query_trust_record( pk ); /* only as assertion */ + if( rc != -1 ) + log_error_f(fname, "Oops: key is now in trustdb???\n"); + else { + rc = insert_trust_record( pk ); + if( !rc ) + goto repeat; /* update the ownertrust */ + log_error_f(fname, "insert trust record failed: %s\n", + g10_errstr(rc) ); + } + } + } + else /* error */ + log_error_f(fname, "error finding dir record: %s\n", + g10_errstr(rc)); } if( ferror(fp) ) log_error_f(fname, _("read error: %s\n"), strerror(errno) ); @@ -1398,7 +1439,7 @@ list_trust_path( int max_depth, const char *username ) if( (rc = get_pubkey_byname( pk, username )) ) log_error("user '%s' not found: %s\n", username, g10_errstr(rc) ); - else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) + else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) log_error("problem finding '%s' in trustdb: %s\n", username, g10_errstr(rc)); else if( rc == -1 ) { @@ -1495,7 +1536,7 @@ check_trustdb( const char *username ) if( (rc = get_pubkey_byname( pk, username )) ) log_error("user '%s' not found: %s\n", username, g10_errstr(rc) ); - else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) + else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) log_error("problem finding '%s' in trustdb: %s\n", username, g10_errstr(rc)); else if( rc == -1 ) @@ -1564,7 +1605,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel ) } } else { /* no local_id: scan the trustdb */ - if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) { + if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) { log_error("check_trust: search dir record failed: %s\n", g10_errstr(rc)); return rc; @@ -1702,6 +1743,25 @@ get_ownertrust( ulong lid, unsigned *r_otrust ) return 0; } +int +get_ownertrust_info( ulong lid ) +{ + unsigned otrust; + int c; + + if( get_ownertrust( lid, &otrust ) ) + return '?'; + switch( (otrust & TRUST_MASK) ) { + case TRUST_NEVER: c = 'n'; break; + case TRUST_MARGINAL: c = 'm'; break; + case TRUST_FULLY: c = 'f'; break; + case TRUST_ULTIMATE: c = 'u'; break; + default: c = '-'; break; + } + return c; +} + + /**************** * This function simply looks for the key in the trustdb @@ -1723,7 +1783,7 @@ query_trust_record( PKT_public_key *pk ) } } else { /* no local_id: scan the trustdb */ - if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) { + if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) { log_error("query_trust_record: search_record failed: %s\n", g10_errstr(rc)); return rc; @@ -1774,6 +1834,9 @@ insert_trust_record( PKT_public_key *orig_pk ) size_t fingerlen; int rc = 0; + keylist_head = NULL; keylist_tail = &keylist_head; keylist = NULL; + uidlist_head = NULL; uidlist_tail = &uidlist_head; uidlist = NULL; + /* prepare dir record */ memset( &dirrec, 0, sizeof dirrec ); dirrec.rectype = RECTYPE_DIR; @@ -1796,8 +1859,6 @@ insert_trust_record( PKT_public_key *orig_pk ) } /* build data structure as linked lists in memory */ - keylist_head = NULL; keylist_tail = &keylist_head; keylist = NULL; - uidlist_head = NULL; uidlist_tail = &uidlist_head; uidlist = NULL; keyid[0] = keyid[1] = 0; for( node=keyblock; node; node = node->next ) { if( node->pkt->pkttype == PKT_PUBLIC_KEY diff --git a/g10/trustdb.h b/g10/trustdb.h index dba38188b..3f24cd514 100644 --- a/g10/trustdb.h +++ b/g10/trustdb.h @@ -46,9 +46,13 @@ int check_trust( PKT_public_key *pk, unsigned *r_trustlevel ); int query_trust_info( PKT_public_key *pk ); int enum_trust_web( void **context, ulong *lid ); int get_ownertrust( ulong lid, unsigned *r_otrust ); +int get_ownertrust_info( ulong lid ); int keyid_from_lid( ulong lid, u32 *keyid ); int query_trust_record( PKT_public_key *pk ); int insert_trust_record( PKT_public_key *pk ); int update_ownertrust( ulong lid, unsigned new_trust ); +/*-- pkclist.c --*/ +int edit_ownertrust( ulong lid, int mode ); + #endif /*G10_TRUSTDB_H*/ diff --git a/tools/Makefile.am b/tools/Makefile.am index 16a48bb93..249ce85d9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -4,7 +4,7 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl needed_libs = ../cipher/libcipher.a ../util/libutil.a \ ../mpi/libmpi.a ../util/libutil.a -noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata +noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest mpicalc_SOURCES = mpicalc.c @@ -12,10 +12,13 @@ bftest_SOURCES = bftest.c clean_sat_SOURCES = clean-sat.c mk_tdata_SOURCES = mk-tdata.c +shmtest_SOURCES = shmtest.c mpicalc_LDADD = @INTLLIBS@ $(needed_libs) bftest_LDADD = @INTLLIBS@ $(needed_libs) +shmtest_LDADD = @INTLLIBS@ $(needed_libs) + mpicalc bftest: $(needed_libs)