From 634b4c31d28914e9730fefcff03f6c242ebfa441 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Mar 2007 20:55:14 +0000 Subject: [PATCH] The Cherry XX44 keyboard's PINpad does now work. DINSIG and NKS card applications are now also PIN pad aware. --- NEWS | 8 +++- TODO | 5 +++ doc/ChangeLog | 4 ++ doc/Makefile.am | 2 +- doc/tools.texi | 49 +++++++++++++++++++++++- jnlib/ChangeLog | 4 ++ jnlib/argparse.c | 2 +- scd/ChangeLog | 11 ++++++ scd/apdu.c | 2 +- scd/app-dinsig.c | 62 ++++++++++++++++++++++-------- scd/app-nks.c | 69 ++++++++++++++++++++++++--------- scd/ccid-driver.c | 47 ++++++++++++++--------- tools/ChangeLog | 5 +++ tools/Makefile.am | 6 +-- tools/applygnupgdefaults | 83 ++++++++++++++++++++++++++++++++++++++++ 15 files changed, 295 insertions(+), 64 deletions(-) create mode 100755 tools/applygnupgdefaults diff --git a/NEWS b/NEWS index 59d46332f..33a18b1ac 100644 --- a/NEWS +++ b/NEWS @@ -11,7 +11,11 @@ Noteworthy changes in version 2.0.3 * New --verify-option show-primary-uid-only. * gpgconf may now read a global configuration file to select which - options are changeable by a frontend. + options are changeable by a frontend. The new applygnupgdefaults + tool may be used by an admin to set default options for all users. + + * The PIN pad of the Cherry XX44 keyboard is now supported. The + DINSIG and the NKS applications are now also aware of PIN pads. Noteworthy changes in version 2.0.2 (2007-01-31) @@ -471,7 +475,7 @@ Noteworthy changes in version 1.9.0 (2003-08-05) development branch. - Copyright 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/TODO b/TODO index 6733d1cc2..2e0f5454e 100644 --- a/TODO +++ b/TODO @@ -121,3 +121,8 @@ * UTF-8 UTF-8 specific TODO. + +* Pinpad Reader + We do not yet support P15 applications. The trivial thing using + ASCII characters will be easy to implement but the otehr cases need + some more work. diff --git a/doc/ChangeLog b/doc/ChangeLog index 799906988..7bd0b1082 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2007-03-07 Werner Koch + + * tools.texi (applygnupgdefaults): New. + 2007-03-06 Werner Koch * examples/gpgconf.conf: New. diff --git a/doc/Makefile.am b/doc/Makefile.am index 9614b222b..70a83d437 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -55,7 +55,7 @@ myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \ myman_pages = gpg2.1 gpgsm.1 gpg-agent.1 scdaemon.1 gpgv2.1 \ watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \ gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 \ - gpgsm-gencert.sh.1 + gpgsm-gencert.sh.1 applygnupgdefaults.8 man_MANS = $(myman_pages) noinst_MANS = gnupg.7 diff --git a/doc/tools.texi b/doc/tools.texi index 1e386f521..d10b806eb 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -12,6 +12,7 @@ GnuPG comes with a couple of smaller tools: * gpgv:: Verify OpenPGP signatures. * addgnupghome:: Create .gnupg home directories. * gpgconf:: Modify .gnupg home directories. +* applygnupgdefaults:: Run gpgconf for all users. * gpgsm-gencert.sh:: Generate an X.509 certificate request. * gpg-preset-passphrase:: Put a passphrase into the cache. * gpg-connect-agent:: Communicate with a running agent. @@ -82,10 +83,12 @@ Display a brief help page and exit @end table @mansect see also +@ifset isman @command{gpg}(1), @command{gpgsm}(1), @command{gpg-agent}(1), @command{scdaemon}(1) +@end ifset @include see-also-note.texi @@ -680,7 +683,7 @@ effect. @table @file -@item /etc/gnupg/gpg-agent.conf +@item /etc/gnupg/gpgconf.conf @cindex gpgconf.conf If this file exists, it is processed as a global configuration file. A commented example can be found in the @file{examples} directory of @@ -689,15 +692,51 @@ effect. @mansect see also +@ifset isman @command{gpg}(1), @command{gpgsm}(1), @command{gpg-agent}(1), @command{scdaemon}(1), @command{dirmngr}(1) +@end ifset @include see-also-note.texi -@manpause + +@c +@c APPLYGNUPGDEFAULTS +@c +@manpage applygnupgdefaults.8 +@node applygnupgdefaults +@section Run gpgconf for all users. +@ifset manverb +.B applygnupgdefaults +\- Run gpgconf --apply-defaults for all users. +@end ifset + +@mansect synopsis +@ifset manverb +.B applygnupgdefaults +@end ifset + +@mansect description +This script is a wrapper around @command{gpgconf} to run it with the +command @code{--apply-defaults} for all real users with an existing +GnuPG home directory. Admins might want to use this script to update he +GnuPG configuration files for all users after +@file{/etc/gnupg/gpgconf.conf} has been changed. This allows to enforce +certain policies for all users. Note, that this is not a bulletproof of +forcing a user to use certain options. A user may always directly edit +the configuration files and bypass gpgconf. + +@noindent +@command{applygnupgdefaults} is invoked by root as: + +@example +applygnupgdefaults +@end example + + @c @c GPGSM-GENCERT.SH @c @@ -725,9 +764,11 @@ which will be printed to stdout. @samp{gpgsm-cencert.sh} @mansect see also +@ifset isman @command{gpgsm}(1), @command{gpg-agent}(1), @command{scdaemon}(1) +@end ifset @include see-also-note.texi @@ -818,10 +859,12 @@ for other users. @end table @mansect see also +@ifset isman @command{gpg}(1), @command{gpgsm}(1), @command{gpg-agent}(1), @command{scdaemon}(1) +@end ifset @include see-also-note.texi @@ -1103,8 +1146,10 @@ The possible exit status codes of @command{symcryptrun} are: @end table @mansect see also +@ifset isman @command{gpg}(1), @command{gpgsm}(1), @command{gpg-agent}(1), +@end ifset @include see-also-note.texi diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index 3f9ef1539..3168b8a15 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,7 @@ +2007-03-07 Werner Koch + + * argparse.c (strusage): Set copyright year to 2007. + 2007-01-25 Werner Koch * stringhelp.c (utf8_charcount): New. diff --git a/jnlib/argparse.c b/jnlib/argparse.c index c4fb057c2..c9cb7d32e 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -905,7 +905,7 @@ strusage( int level ) switch( level ) { case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2006 Free Software Foundation, Inc."; break; + case 14: p = "Copyright (C) 2007 Free Software Foundation, Inc."; break; case 15: p = "This program comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it\n" diff --git a/scd/ChangeLog b/scd/ChangeLog index 38ef4f234..571457576 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,14 @@ +2007-03-07 Werner Koch + + * app-dinsig.c: Include i18n.h. + (verify_pin): Support PIN pads. + * app-nks.c (verify_pin): Ditto. + + * ccid-driver.c (bulk_in): Handle time extension before checking + the message type. + (ccid_transceive_secure): Support the Cherry XX44 keyboard. + Kudos to the nice folks at Cherry for helping with that. + 2007-02-18 Werner Koch * scdaemon.c (DEFAULT_PCSC_DRIVER): Add a default for OS X. diff --git a/scd/apdu.c b/scd/apdu.c index ac2f3c44b..a45f0a3e9 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -90,7 +90,7 @@ #define MAX_OPEN_FDS 20 #endif -/* Helper to pass patrameters related to keypad based operations. */ +/* Helper to pass parameters related to keypad based operations. */ struct pininfo_s { int mode; diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index 5cab42805..981568804 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -1,5 +1,5 @@ /* app-dinsig.c - The DINSIG (DIN V 66291-1) card application. - * Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -81,6 +81,7 @@ #include "scdaemon.h" +#include "i18n.h" #include "iso7816.h" #include "app-common.h" #include "tlv.h" @@ -279,11 +280,37 @@ verify_pin (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { - if (!app->did_chv1 || app->force_chv1 ) + const char *s; + int rc; + iso7816_pininfo_t pininfo; + + if ( app->did_chv1 && !app->force_chv1 ) + return 0; /* No need to verify it again. */ + + memset (&pininfo, 0, sizeof pininfo); + pininfo.mode = 1; + pininfo.minlen = 6; + pininfo.maxlen = 8; + + if (!opt.disable_keypad + && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) ) + { + rc = pincb (pincb_arg, + _("||Please enter your PIN at the reader's keypad"), + NULL); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + return rc; + } + rc = iso7816_verify_kp (app->slot, 0x81, "", 0, &pininfo); + /* Dismiss the prompt. */ + pincb (pincb_arg, NULL, NULL); + } + else /* No Keypad. */ { - const char *s; char *pinvalue; - int rc; rc = pincb (pincb_arg, "PIN", &pinvalue); if (rc) @@ -303,15 +330,17 @@ verify_pin (app_t app, return gpg_error (GPG_ERR_BAD_PIN); } - if (strlen (pinvalue) < 6) + if (strlen (pinvalue) < pininfo.minlen) { - log_error ("PIN is too short; minimum length is 6\n"); + log_error ("PIN is too short; minimum length is %d\n", + pininfo.minlen); xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } - else if (strlen (pinvalue) > 8) + else if (strlen (pinvalue) > pininfo.maxlen) { - log_error ("PIN is too large; maximum length is 8\n"); + log_error ("PIN is too large; maximum length is %d\n", + pininfo.maxlen); xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } @@ -326,7 +355,7 @@ verify_pin (app_t app, this. */ char paddedpin[8]; int i, ndigits; - + for (ndigits=0, s=pinvalue; *s; ndigits++, s++) ; i = 0; @@ -336,19 +365,18 @@ verify_pin (app_t app, if (i < sizeof paddedpin && *s) paddedpin[i++] = (((*s - '0') << 4) | 0x0f); while (i < sizeof paddedpin) - paddedpin[i++] = 0xff; + paddedpin[i++] = 0xff; rc = iso7816_verify (app->slot, 0x81, paddedpin, sizeof paddedpin); } - if (rc) - { - log_error ("verify PIN failed\n"); - xfree (pinvalue); - return rc; - } - app->did_chv1 = 1; xfree (pinvalue); } + if (rc) + { + log_error ("verify PIN failed\n"); + return rc; + } + app->did_chv1 = 1; return 0; } diff --git a/scd/app-nks.c b/scd/app-nks.c index 3c64fe45b..5feabc1ec 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -1,5 +1,5 @@ /* app-nks.c - The Telesec NKS 2.0 card application. - * Copyright (C) 2004 Free Software Foundation, Inc. + * Copyright (C) 2004, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -306,14 +306,43 @@ verify_pin (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { + iso7816_pininfo_t pininfo; + int rc; + /* Note that force_chv1 is never set but we do it here anyway so that other applications may reuse this function. For example it makes sense to set force_chv1 for German signature law cards. NKS is very similar to the DINSIG draft standard. */ - if (!app->did_chv1 || app->force_chv1 ) + if ( app->did_chv1 && !app->force_chv1 ) + return 0; /* No need to verify it again. */ + + memset (&pininfo, 0, sizeof pininfo); + pininfo.mode = 1; + pininfo.minlen = 6; + pininfo.maxlen = 16; + + if (!opt.disable_keypad + && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) ) + { + rc = pincb (pincb_arg, + _("||Please enter your PIN at the reader's keypad"), + NULL); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + return rc; + } + + /* Although it is possible to use a local PIN, we use the global + PIN for this application. */ + rc = iso7816_verify_kp (app->slot, 0, "", 0, &pininfo); + /* Dismiss the prompt. */ + pincb (pincb_arg, NULL, NULL); + } + else { char *pinvalue; - int rc; rc = pincb (pincb_arg, "PIN", &pinvalue); if (rc) @@ -324,35 +353,37 @@ verify_pin (app_t app, /* The following limits are due to TCOS but also defined in the NKS specs. */ - if (strlen (pinvalue) < 6) + if (strlen (pinvalue) < pininfo.minlen) { - log_error ("PIN is too short; minimum length is 6\n"); + log_error ("PIN is too short; minimum length is %d\n", + pininfo.minlen); xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } - else if (strlen (pinvalue) > 16) + else if (strlen (pinvalue) > pininfo.maxlen) { - log_error ("PIN is too large; maximum length is 16\n"); + log_error ("PIN is too large; maximum length is %d\n", + pininfo.maxlen); xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } - /* Also it is possible to use a local PIN, we use the gloabl + /* Although it is possible to use a local PIN, we use the global PIN for this application. */ rc = iso7816_verify (app->slot, 0, pinvalue, strlen (pinvalue)); - if (rc) - { - if ( gpg_error (rc) == GPG_ERR_USE_CONDITIONS ) - log_error (_("the NullPIN has not yet been changed\n")); - else - log_error ("verify PIN failed\n"); - xfree (pinvalue); - return rc; - } - app->did_chv1 = 1; xfree (pinvalue); } + if (rc) + { + if ( gpg_err_code (rc) == GPG_ERR_USE_CONDITIONS ) + log_error (_("the NullPIN has not yet been changed\n")); + else + log_error ("verify PIN failed\n"); + return rc; + } + app->did_chv1 = 1; + return 0; } @@ -457,7 +488,7 @@ do_decipher (app_t app, const char *keyidstr, if (!keyidstr || !*keyidstr || !indatalen) return gpg_error (GPG_ERR_INV_VALUE); - /* Check that the provided ID is vaid. This is not really needed + /* Check that the provided ID is valid. This is not really needed but we do it to to enforce correct usage by the caller. */ if (strncmp (keyidstr, "NKS-DF01.", 9) ) return gpg_error (GPG_ERR_INV_ID); diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index bbb886239..8ad329d67 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1,6 +1,6 @@ /* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - * Written by Werner Koch. + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + * Written by Werner Koch. * * This file is part of GnuPG. * @@ -1458,11 +1458,6 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen); return CCID_DRIVER_ERR_INV_VALUE; } - if (buffer[0] != expected_type) - { - DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); - return CCID_DRIVER_ERR_INV_VALUE; - } if (buffer[5] != 0) { DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]); @@ -1475,6 +1470,10 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, return CCID_DRIVER_ERR_INV_VALUE; } + /* We need to handle the time extension request before we check that + we go the expected message type. This is in particular required + for the Cherry keyboard which sends a time extension request for + each key hit. */ if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80) { /* Card present and active, time extension requested. */ @@ -1483,6 +1482,13 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, goto retry; } + if (buffer[0] != expected_type) + { + DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); + return CCID_DRIVER_ERR_INV_VALUE; + } + + if (!no_debug) { DEBUGOUT_3 ("status: %02X error: %02X octet[9]: %02X\n" @@ -2330,6 +2336,7 @@ ccid_transceive_secure (ccid_driver_t handle, int i; size_t dummy_nresp; int testmode; + int cherry_mode = 0; testmode = !resp && !nresp; @@ -2368,14 +2375,16 @@ ccid_transceive_secure (ccid_driver_t handle, case VENDOR_SCM: /* Tested with SPR 532. */ case VENDOR_KAAN: /* Tested with KAAN Advanced (1.02). */ break; - /* The CHERRY XX44 does not yet work. I have not investigated it - closer because there is another problem: It echos a "*" for - each entered character and we somehow need to arrange that it - doesn't get to the tty at all. Given that we are running - without a control terminal there is not much we can do about. - A weird hack using pinentry comes in mind but I doubt that - this is a clean solution. Need to contact Cherry. - */ + case VENDOR_CHERRY: + /* The CHERRY XX44 keyboard echos an asterisk for each entered + character on the keyboard channel. We use a special variant + of PC_to_RDR_Secure which directs these characters to the + smart card's bulk-in channel. We also need to append a zero + Lc byte to the APDU. It seems that it will be replaced with + the actual length instead of being appended before the APDU + is send to the card. */ + cherry_mode = 1; + break; default: return CCID_DRIVER_ERR_NOT_SUPPORTED; } @@ -2393,7 +2402,7 @@ ccid_transceive_secure (ccid_driver_t handle, return rc; } - msg[0] = PC_to_RDR_Secure; + msg[0] = cherry_mode? 0x89 : PC_to_RDR_Secure; msg[5] = 0; /* slot */ msg[6] = seqno = handle->seqno++; msg[7] = 0; /* bBWI */ @@ -2405,7 +2414,7 @@ ccid_transceive_secure (ccid_driver_t handle, if (handle->id_vendor == VENDOR_SCM) { /* For the SPR532 the next 2 bytes need to be zero. We do this - for all SCM product. Kudos to Martin Paljak for this + for all SCM products. Kudos to Martin Paljak for this hint. */ msg[13] = msg[14] = 0; } @@ -2419,7 +2428,7 @@ ccid_transceive_secure (ccid_driver_t handle, } /* The following is a little endian word. */ - msg[15] = pinlen_max; /* wPINMaxExtraDigit-Maximum. */ + msg[15] = pinlen_max; /* wPINMaxExtraDigit-Maximum. */ msg[16] = pinlen_min; /* wPINMaxExtraDigit-Minimum. */ msg[17] = 0x02; /* bEntryValidationCondition: @@ -2440,6 +2449,8 @@ ccid_transceive_secure (ccid_driver_t handle, msg[27] = apdu_buf[2]; /* P1 */ msg[28] = apdu_buf[3]; /* P2 */ msglen = 29; + if (cherry_mode) + msg[msglen++] = 0; /* An EDC is not required. */ set_msg_len (msg, msglen - 10); diff --git a/tools/ChangeLog b/tools/ChangeLog index 56247c6d8..c369506ae 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2007-03-07 Werner Koch + + * applygnupgdefaults: New. + * Makefile.am (sbin_SCRIPTS): Add it + 2007-03-06 Werner Koch * gpgconf-comp.c: Include pwd.h and grp.h. diff --git a/tools/Makefile.am b/tools/Makefile.am index 11abca701..d3c355662 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,5 +1,5 @@ # Makefile.am - Tools directory -# Copyright (C) 2003 Free Software Foundation, Inc. +# Copyright (C) 2003, 2007 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -20,7 +20,7 @@ EXTRA_DIST = \ Manifest watchgnupg.c \ - addgnupghome gpgsm-gencert.sh \ + addgnupghome applygnupgdefaults gpgsm-gencert.sh \ lspgpot mail-signed-keys convert-from-106 @@ -29,7 +29,7 @@ include $(top_srcdir)/am/cmacros.am AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS) -sbin_SCRIPTS = addgnupghome +sbin_SCRIPTS = addgnupghome applygnupgdefaults bin_SCRIPTS = gpgsm-gencert.sh if HAVE_USTAR diff --git a/tools/applygnupgdefaults b/tools/applygnupgdefaults new file mode 100755 index 000000000..882189c0c --- /dev/null +++ b/tools/applygnupgdefaults @@ -0,0 +1,83 @@ +#!/bin/sh +# Apply defaults from/etc/gnupg/gpg.conf to all users -*- sh -*- +# +# Copyright 2007 Free Software Foundation, Inc. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +PGM=applygnupgdefaults +errorfile= + +error () { + echo "$PGM: $*" >&2 + echo "$PGM: $*" >>$errorfile +} + +info () { + echo "$PGM: $*" >&2 +} + +if [ -n "$1" ]; then + echo "usage: $PGM" >&2 + exit 1 +fi + +# Cleanup on exit +cleanup () +{ + [ -n "$errorfile" -a -f "$errorfile" ] && rm "$errorfile" +} +trap cleanup EXIT SIGINT SIGHUP SIGPIPE +errorfile="/tmp/$PGM.$$.log" +: >$errorfile + + +# Check whether we can use getent +if getent --help /dev/null 2>&1 ; then + cat_passwd='getent passwd' +else + cat_passwd='cat /etc/passwd' + info "please note that only users from /etc/passwd are processed" +fi + +if [ ! -f /etc/gnupg/gpgconf.conf ]; then + error "global configuration file \`/etc/gnupg/gpgconf.conf' does not exist" + exit 1 +fi +if [ ! -f /etc/shells ]; then + error "missing file \`/etc/shells'" + exit 1 +fi + +if [ $(id -u) -ne 0 ]; then + error "needs to be run as root" + exit 1 +fi + +${cat_passwd} \ + | while IFS=: read -r user dmy_a uid dmy_c dmy_d home shell dmy_rest; do + # Process only entires with a valid login shell + grep /dev/null >/dev/null || continue + # and with an existant gnupg home directory + [ -d "$home/.gnupg" ] || continue + # but not root + [ "${uid:-0}" -eq 0 ] && continue + info "running \"gpgconf --apply-defaults\" for $user" + if su -l -s /bin/sh \ + -c 'gpgconf --apply-defaults && echo SUCCESS' $user \ + | tail -1 | grep ^SUCCESS >/dev/null ; then + : + else + error "failed to update gnupg defaults for $user" + fi +done + +[ "$(wc -c <$errorfile)" -gt 0 ] && exit 1 +exit 0 +